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"])
|
||||
|
||||
Reference in new issue
Block a user