Going somewhere with a coffee

This commit is contained in:
didier committed 2024-11-16 09:16:25 -05:00
1 parent 236dd82871
commit a10fdbee50
7 files changed
+247 -143

No files matched your search

+37 -13
View File
@@ -1,25 +1,25 @@
import json5 as json
from contextlib import closing, contextmanager from contextlib import closing, contextmanager
from pathlib import Path from pathlib import Path
import sqlite3 import sqlite3
from dodgeballtracker.metadata import VideoMetadata
from dodgeballtracker.helper import time_tracker from dodgeballtracker.helper import time_tracker
from dodgeballtracker.logic import (DodgeballTracker, from dodgeballtracker.logic import (DodgeballTracker,
get_court_perspective_transform) get_court_perspective_transform)
from dodgeballtracker.data_dumper import SQLiteDataDumper from dodgeballtracker.data_dumper import SQLiteDataDumper, DataDumper
import numpy as np import numpy as np
import logging import logging
import click import click
import hashlib import hashlib
from typing import ContextManager from typing import ContextManager, Iterator
from dodgeballtracker.video_writer import (MP4VVideoWriter, from dodgeballtracker.video_writer import (MP4VVideoWriter,
VideoWriter, VideoWriter,
DetectedObjectBox, DetectedObjectBox,
MP4VVideoWriterWithFrame) MP4VVideoWriterWithFrame)
here = Path(__file__).parent
input_dir = here / '..' / 'data'
output_dir = here / '..' / 'outputs'
@click.group() @click.group()
@@ -53,15 +53,29 @@ def get_file_sha256(file_: Path) -> str:
@contextmanager @contextmanager
def create_data_dumper(input_file: Path, outout_file: Path): def create_data_dumper(input_file: Path,
with closing(sqlite3.connect(outout_file)) as conn: output_file: Path,
metadata: VideoMetadata) -> Iterator[DataDumper]:
with closing(sqlite3.connect(output_file)) as conn:
conn.execute('PRAGMA foreign_keys = 1') conn.execute('PRAGMA foreign_keys = 1')
dumper = SQLiteDataDumper(conn) dumper = SQLiteDataDumper(conn)
dumper.start(input_file, get_file_sha256(input_file)) dumper.start(input_file, get_file_sha256(input_file), metadata)
yield dumper yield dumper
def deserialized_video_metadata(positional_data: Path | None) -> VideoMetadata | None:
if not positional_data:
return None
with open(positional_data, 'rt') as file_:
data = json.load(file_)
return VideoMetadata(**data)
def process_logic(input_: Path,
output_dir: Path | None,
metadata_file: Path | None,
display_video: bool):
metadata = deserialized_video_metadata(metadata_file)
def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
output_dir = get_output_dir(input_, output_dir) output_dir = get_output_dir(input_, output_dir)
detected_box_objects = [ detected_box_objects = [
DetectedObjectBox.from_viridis(threshold) for threshold in DetectedObjectBox.from_viridis(threshold) for threshold in
@@ -71,7 +85,7 @@ def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
transformation_matrix = get_court_perspective_transform() transformation_matrix = get_court_perspective_transform()
with get_video_writer(display_video, input_, output_dir / 'video.mov') as video_writer: with get_video_writer(display_video, input_, output_dir / 'video.mov') as video_writer:
with create_data_dumper(input_, output_dir / 'data.sqlite') as data_dumper: with create_data_dumper(input_, output_dir / 'data.sqlite', metadata) as data_dumper:
tracker = DodgeballTracker(input_, tracker = DodgeballTracker(input_,
video_writer, video_writer,
data_dumper, data_dumper,
@@ -86,15 +100,25 @@ def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
def train(): def train():
pass pass
@cli.command() @cli.command()
@click.option('--input', '-i', 'input_', @click.option('--input', '-i', 'input_',
type=click.Path(readable=True, path_type=Path)) type=click.Path(readable=True, path_type=Path))
@click.option('--output-dir', '-o', type=click.Path(path_type=Path)) @click.option('--output-dir', '-o', type=click.Path(path_type=Path))
@click.option('--metadata-file', '-f', type=click.Path(path_type=Path, file_okay=True, exists=True))
@click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False) @click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False)
def process(input_: Path, output_dir: Path | None, display_video: bool): def process(input_: Path,
process_logic(input_, output_dir, display_video) output_dir: Path | None,
metadata_file: Path | None,
display_video: bool):
process_logic(input_,
output_dir,
metadata_file,
display_video)
if __name__ == "__main__": if __name__ == "__main__":
cli() cli()
# process_logic(Path('/home/didier/all-dressed-programming/dodgeball-tracker/data/experiments/rue-honore-beaugrand-ouest-001.MOV'), None, False) # process_logic(Path('/home/didier/all-dressed-programming/dodgeball-tracker/data/experiments/rue-honore-beaugrand-ouest-001.MOV'),
# Path('/home/didier/all-dressed-programming/dodgeball-tracker/outputs/benchmark-001'),
# False)
+18 -4
View File
@@ -2,6 +2,8 @@ import abc
import pandas as pd import pandas as pd
from pathlib import Path from pathlib import Path
from dodgeballtracker.metadata import VideoMetadata
from dodgeballtracker.typing import TrackedDetectedObject, VideoTimestamp from dodgeballtracker.typing import TrackedDetectedObject, VideoTimestamp
from sqlite3 import Connection from sqlite3 import Connection
@@ -61,15 +63,20 @@ class SQLiteDataDumper(DataDumper):
ymax DOUBLE PRECISION NOT NULL, ymax DOUBLE PRECISION NOT NULL,
score DOUBLE PRECISION NOT NULL, score DOUBLE PRECISION NOT NULL,
category INTEGER NOT NULL, category INTEGER NOT NULL,
object_id INTEGER NOT NULL,
video_frame_id INTEGER NOT NULL, video_frame_id INTEGER NOT NULL,
FOREIGN KEY(video_frame_id) REFERENCES video_frame(id) FOREIGN KEY(video_frame_id) REFERENCES video_frame(id)
); );
''') ''')
self._conn.commit() self._conn.commit()
def start(self, video_path: Path, hexa_hash: str) -> None: def start(self,
video_path: Path,
hexa_hash: str,
metadata: VideoMetadata|None=None) -> None:
self._create_tables() self._create_tables()
cur = self._conn.cursor() cur = self._conn.cursor()
@@ -101,9 +108,16 @@ class SQLiteDataDumper(DataDumper):
RETURNING id RETURNING id
''', (ts, frame_index, self._video_id)) ''', (ts, frame_index, self._video_id))
frame_id = res.fetchone()[0] frame_id = res.fetchone()[0]
cols = ['xmin', 'ymin', 'xmax', 'ymax', 'score', 'category'] cols = ['xmin', 'ymin', 'xmax', 'ymax', 'score', 'category', 'object_id']
cur.executemany(''' cur.executemany('''
INSERT INTO tracked_detected_object(xmin, ymin, xmax, ymax, score, category, video_frame_id) INSERT INTO tracked_detected_object(xmin,
VALUES (?, ?, ?, ?, ?, ?, ?) ymin,
xmax,
ymax,
score,
category,
object_id,
video_frame_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (list(x[cols]) + [frame_id] for x in df.iloc)) ''', (list(x[cols]) + [frame_id] for x in df.iloc))
self._conn.commit() self._conn.commit()
+20
View File
@@ -0,0 +1,20 @@
from pydantic import BaseModel
class KnownImagePoint(BaseModel):
height: float
width: float
class BirdViewPoint(BaseModel):
x: float
y: float
class KnownPoint(BaseModel):
image: KnownImagePoint
bird_view: BirdViewPoint
class VideoMetadata(BaseModel):
knownPoints: list[KnownPoint]
+8
View File
@@ -3,6 +3,8 @@ import tempfile
from pathlib import Path from pathlib import Path
from sqlite3 import Connection from sqlite3 import Connection
from dodgeballtracker.metadata import VideoMetadata
from dodgeballtracker.typing import TrackedDetectedObject from dodgeballtracker.typing import TrackedDetectedObject
import pandas as pd import pandas as pd
@@ -27,6 +29,12 @@ def list_tables(conn: Connection) -> set[str]:
''') ''')
return {row[0] for row in res} return {row[0] for row in res}
def video_metadata() -> VideoMetadata:
data = {
}
return VideoMetadata()
@pytest.fixture @pytest.fixture
def tmp_dir(): def tmp_dir():
with tempfile.TemporaryDirectory() as dir_: with tempfile.TemporaryDirectory() as dir_:
+1 -2
View File
@@ -10,8 +10,7 @@ def tensor_of(data_type: pa.DataType, cols: list[str]) -> pa.DataFrameSchema:
return pa.DataFrameSchema({col: pa.Column(data_type) for col in cols}) return pa.DataFrameSchema({col: pa.Column(data_type) for col in cols})
DetectedObject = tensor_of(Float32, ["xmin", "ymin", "xmax", "ymax", "score", DetectedObject = tensor_of(Float32, ["xmin", "ymin", "xmax", "ymax", "score", "category"])
"category"])
TrackedDetectedObject = tensor_of(Float64, TrackedDetectedObject = tensor_of(Float64,
list(DetectedObject.columns) + ["object_id", "index"]) list(DetectedObject.columns) + ["object_id", "index"])
-2
View File
@@ -1,2 +0,0 @@
*.json
*.mp4
+163 -122
View File
@@ -1,165 +1,206 @@
absl-py==2.1.0 absl-py==2.1.0
anyio==4.2.0 aiodns==3.2.0
appnope==0.1.3 aiohappyeyeballs==2.3.6
aiohttp==3.10.5
aiosignal==1.3.1
annotated-types==0.7.0
anyio==4.4.0
argon2-cffi==23.1.0 argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0 argon2-cffi-bindings==21.2.0
arrow==1.3.0 arrow==1.3.0
asttokens==2.4.1 asttokens==2.4.1
astunparse==1.6.3
async-lru==2.0.4 async-lru==2.0.4
async-timeout==4.0.3
async_generator==1.10
attrs==23.2.0 attrs==23.2.0
Babel==2.14.0 Babel==2.15.0
beautifulsoup4==4.12.2 bcrypt==4.1.3
beautifulsoup4==4.12.3
bleach==6.1.0 bleach==6.1.0
boxmot==10.0.51 boxmot==10.0.81
build==1.0.3 Brotli==1.1.0
brotlicffi==1.1.0.0
cachetools==5.3.2 cachetools==5.3.2
certifi==2023.11.17 certifi==2024.7.4
cffi==1.16.0 cffi==1.17.1
cfgv==3.4.0 chardet==5.2.0
charset-normalizer==3.3.2 charset-normalizer==3.3.2
click==8.1.7 click==8.1.7
comm==0.2.1 comm==0.2.2
contourpy==1.2.0 contourpy==1.2.1
cryptography==43.0.0
curio==1.6
curl_cffi==0.7.1
cycler==0.12.1 cycler==0.12.1
Cython==3.0.8 ddt==1.7.2
debugpy==1.8.0
decorator==5.1.1 decorator==5.1.1
deep-sort-realtime==1.3.2 defusedxml==0.8.0rc2
defusedxml==0.7.1 executing==2.1.0
distlib==0.3.8
exceptiongroup==1.2.0
executing==2.0.1
fastjsonschema==2.19.1 fastjsonschema==2.19.1
filelock==3.13.1 filelock==3.15.1
filterpy==1.4.5 filterpy==1.4.5
fonttools==4.47.2 fonttools==4.53.1
fqdn==1.5.1 fqdn==1.5.1
fsspec==2023.12.2 frozenlist==1.4.1
ftfy==6.1.3 fsspec==2024.3.0
gdown==4.6.3 ftfy==6.2.3
future==1.0.0
gdown==5.2.0
gitdb==4.0.11 gitdb==4.0.11
GitPython==3.1.41 GitPython==3.1.43
google-auth==2.26.2 google-auth==2.30.0
google-auth-oauthlib==1.2.0 google-auth-oauthlib==1.2.1
grpcio==1.60.0 grpcio==1.64.1
identify==2.5.33 gviz-api==1.10.0
idna==3.6 h11==0.14.0
ipykernel==6.28.0 html5lib==1.1
ipython==8.20.0 httpcore==1.0.5
ipywidgets==8.1.1 httpx==0.27.0
idna==3.7
iniconfig==2.0.0
ipykernel==6.29.5
ipython==8.27.0
ipywidgets==8.1.5
isoduration==20.11.0 isoduration==20.11.0
jedi==0.19.1 jedi==0.19.1
Jinja2==3.1.3 jeepney==0.8.0
joblib==1.3.2 Jinja2==3.1.4
joblib==1.4.2
json5==0.9.14 json5==0.9.14
jsonpointer==2.4 jsonpointer==3.0.0
jsonschema==4.20.0 jsonschema==4.22.0
jsonschema-specifications==2023.12.1 jsonschema-specifications==2023.12.1
jupyter==1.0.0 jupyter==1.1.1
jupyter-console==6.6.3 jupyter-console==6.6.3
jupyter-events==0.9.0 jupyter-events==0.10.0
jupyter-lsp==2.2.1 jupyter-lsp==2.2.5
jupyter_client==8.6.0 jupyter_client==8.6.2
jupyter_core==5.7.1 jupyter_core==5.7.2
jupyter_server==2.12.4 jupyter_server==2.14.2
jupyter_server_terminals==0.5.1 jupyter_server_terminals==0.5.3
jupyterlab==4.0.10 jupyterlab==4.2.5
jupyterlab-widgets==3.0.9
jupyterlab_pygments==0.3.0 jupyterlab_pygments==0.3.0
jupyterlab_server==2.25.2 jupyterlab_server==2.27.3
jupyterlab_widgets==3.0.13
kiwisolver==1.4.5 kiwisolver==1.4.5
lapx==0.5.5 lapx==0.5.11
loguru==0.7.2 loguru==0.7.2
Markdown==3.5.2 lz4==4.3.3
MarkupSafe==2.1.3 Markdown==3.7
matplotlib==3.8.2 MarkupSafe==2.1.5
matplotlib-inline==0.1.6 matplotlib==3.9.1
matplotlib-inline==0.1.7
mistune==3.0.2 mistune==3.0.2
mpmath==1.3.0 mpmath==1.3.0
nbclient==0.9.0 multidict==6.1.0
nbconvert==7.14.1 multimethod==1.9.1
nbformat==5.9.2 mutagen==1.47.0
nest-asyncio==1.5.8 mypy_extensions==1.0.0
networkx==3.2.1 nbclient==0.10.0
nodeenv==1.8.0 nbconvert==7.16.4
notebook==7.0.6 nbformat==5.10.4
notebook_shim==0.2.3 nest_asyncio==1.6.0
numpy==1.24.4 networkx==3.3
notebook==7.2.2
notebook_shim==0.2.4
numpy==1.26.4
oauthlib==3.2.2 oauthlib==3.2.2
opencv-python==4.9.0.80 olefile==0.47
overrides==7.4.0 opencv @ file:///build/source/modules/python/package/dist/opencv-4.9.0-py3-none-any.whl#sha256=0b1c6093b66ec745df186877df1e6e72241dfe8dda392f023bc361fe1d5411ca
packaging==23.2 outcome==1.3.0.post0
pandas==2.1.4 overrides==7.7.0
pandocfilters==1.5.0 packaging==24.1
parso==0.8.3 pandas==2.2.2
pandera==0.20.4
pandocfilters==1.5.1
paramiko==3.5.0
parso==0.8.4
pexpect==4.9.0 pexpect==4.9.0
pillow==10.2.0 pillow==10.4.0
pip-tools==7.3.0 platformdirs==4.2.2
platformdirs==4.1.0 pluggy==1.5.0
pre-commit==3.6.0 prometheus_client==0.21.0
prometheus-client==0.19.0 prompt_toolkit==3.0.47
prompt-toolkit==3.0.43 protobuf==5.28.2
protobuf==4.23.4 psutil==6.0.0
psutil==5.9.7
ptyprocess==0.7.0 ptyprocess==0.7.0
pure-eval==0.2.2 pure_eval==0.2.2
py-cpuinfo==9.0.0 py-cpuinfo==9.0.0
pyasn1==0.5.1 pyasn1==0.6.0
pyasn1-modules==0.3.0 pyasn1_modules==0.4.0
pycparser==2.21 pybind11==2.13.5
Pygments==2.17.2 pycares==4.4.0
pyparsing==3.1.1 pycparser==2.22
pyproject_hooks==1.0.0 pycryptodomex==3.20.0
pydantic==2.8.2
pydantic_core==2.20.1
Pygments==2.18.0
pyparsing==3.1.2
PySocks==1.7.1 PySocks==1.7.1
python-dateutil==2.8.2 pyspnego==0.10.2
pytest==8.3.2
python-dateutil==2.9.0.post0
python-json-logger==2.0.7 python-json-logger==2.0.7
pytz==2023.3.post1 python-socks==2.4.4
PyYAML==6.0.1 pytz==2024.2
pyzmq==25.1.2 PyYAML==6.0.2
qtconsole==5.5.1 pyzmq==26.0.3
QtPy==2.4.1 referencing==0.34.0
referencing==0.32.1 regex==2024.5.15
regex==2023.12.25 requests==2.32.3
requests==2.31.0 requests-oauthlib==2.0.0
requests-oauthlib==1.3.1 rfc3339_validator==0.1.4
rfc3339-validator==0.1.4 rfc3986_validator==0.1.1
rfc3986-validator==0.1.1 rpds-py==0.18.1
rpds-py==0.17.1
rsa==4.9 rsa==4.9
scikit-learn==1.4.0 scikit-learn==1.5.0
scipy==1.11.4 scipy==1.14.0
seaborn==0.13.1 seaborn==0.13.2
SecretStorage==3.3.3
Send2Trash==1.8.2 Send2Trash==1.8.2
setuptools==72.1.0.post0
six==1.16.0 six==1.16.0
smmap==5.0.1 smbprotocol==1.12.0
sniffio==1.3.0 smmap==6.0.0
sniffio==1.3.1
sortedcontainers==2.4.0
soupsieve==2.5 soupsieve==2.5
stack-data==0.6.3 stack_data==0.6.3
sympy==1.12 sympy==1.12.1
tensorboard==2.15.1 tensorboard==2.17.0
tensorboard-data-server==0.7.2 tensorboard-data-server==0.7.2
terminado==0.18.0 tensorboard-plugin-profile==2.11.1
thop==0.1.1.post2209072238 tensorboard-plugin-wit==1.7.0
threadpoolctl==3.2.0 terminado==0.18.1
tinycss2==1.2.1 threadpoolctl==3.4.0
tomli==2.0.1 tinycss2==1.3.0
torch==2.1.2 toml==0.10.2
torchvision==0.16.2 torch==2.5.0
tornado==6.4 torchvision==0.20.0a0
tqdm==4.66.1 tornado==6.4.1
traitlets==5.14.1 tqdm==4.66.4
types-python-dateutil==2.8.19.20240106 traitlets==5.14.3
typing_extensions==4.9.0 trio==0.25.0
tzdata==2023.4 triton==3.1.0
ultralytics==8.1.3 typeguard==4.3.0
types-python-dateutil==2.9.0.20240316
typing_extensions==4.12.2
typing_inspect==0.9.0
tzdata==2024.1
ultralytics==8.3.13
ultralytics-thop==2.0.9
uri-template==1.3.0 uri-template==1.3.0
urllib3==2.1.0 urllib3==2.2.2
virtualenv==20.25.0
wcwidth==0.2.13 wcwidth==0.2.13
webcolors==1.13 webcolors==1.13
webencodings==0.5.1 webencodings==0.5.1
websocket-client==1.7.0 websocket-client==1.8.0
Werkzeug==3.0.1 websockets==12.0
widgetsnbextension==4.0.9 Werkzeug==3.0.4
wheel==0.43.0
widgetsnbextension==4.0.13
wrapt==1.16.0
yacs==0.1.8 yacs==0.1.8
youtube-dl==2021.12.17 yarl==1.9.4
yt-dlp==2024.10.22