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