cleaned up code.

This commit is contained in:
didier committed 2024-11-08 11:57:32 -05:00
1 parent afbe73cd21
commit 4171dd2bc4
4 files changed
+49 -43

No files matched your search

+10 -6
View File
@@ -41,12 +41,7 @@ def get_video_writer(display_frame: bool,
return closing(MP4VVideoWriter.from_frame(video_input, video_output, thresholds)) return closing(MP4VVideoWriter.from_frame(video_input, video_output, thresholds))
@cli.command() def process_logic(input_: Path, output: Path | None, display_video: bool):
@click.option('--input', '-i', 'input_',
type=click.Path(readable=True, path_type=Path))
@click.option('--output', '-o', type=click.Path(path_type=Path))
@click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False)
def process(input_: Path, output: Path | None, display_video: bool):
output = get_output(input_, output) output = get_output(input_, output)
detected_box_objects = [ detected_box_objects = [
DetectedObjectBox.from_viridis(threshold) for threshold in DetectedObjectBox.from_viridis(threshold) for threshold in
@@ -65,6 +60,15 @@ def process(input_: Path, output: Path | None, display_video: bool):
with time_tracker(): with time_tracker():
tracker.main() tracker.main()
@cli.command()
@click.option('--input', '-i', 'input_',
type=click.Path(readable=True, path_type=Path))
@click.option('--output', '-o', type=click.Path(path_type=Path))
@click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False)
def process(input_: Path, output: Path | None, display_video: bool):
process_logic(input_, output, display_video)
if __name__ == "__main__": if __name__ == "__main__":
cli() cli()
# process_logic(Path('/home/didier/all-dressed-programming/dodgeball-tracker/data/micro.mp4'), None, False)
+7 -7
View File
@@ -10,7 +10,7 @@ import numpy as np
import pandas as pd import pandas as pd
import pandera as pa import pandera as pa
from boxmot import DeepOcSort as DeepOCSORT from boxmot import DeepOcSort as DeepOCSORT
from .typing import VideoFrame, DetectedObject_ from .typing import VideoFrame, DetectedObject_, TrackedDetectedObject_
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -111,7 +111,7 @@ class DodgeballTracker:
def run_model_on_frame(self, model, frame: VideoFrame): def run_model_on_frame(self, model, frame: VideoFrame):
model_outputs = model(frame)[0] model_outputs = model(frame)[0]
boxes = model_outputs.boxes.data.cpu().numpy() boxes = model_outputs.boxes.data.cpu().numpy()
columns=['xmin', 'ymin', 'xmax', 'ymin', 'score', 'category'] columns=['xmin', 'ymin', 'xmax', 'ymax', 'score', 'category']
return pd.DataFrame(boxes, columns=columns) return pd.DataFrame(boxes, columns=columns)
def persist_points(self): def persist_points(self):
@@ -131,9 +131,10 @@ class DodgeballTracker:
""" """
return YOLO("yolo11n.pt", verbose=True) return YOLO("yolo11n.pt", verbose=True)
def update_tracker(self, tracker: DeepOCSORT, detected_objs, frame: VideoFrame): @pa.check_io(detected_objs=DetectedObject_, out=TrackedDetectedObject_)
def update_tracker(self, tracker: DeepOCSORT, detected_objs: pd.DataFrame, frame: VideoFrame):
data_ = tracker.update(detected_objs.to_numpy(), frame) data_ = tracker.update(detected_objs.to_numpy(), frame)
columns = ['xmin', 'ymin', 'xmax', 'ymin', 'object_id', 'score', 'category', 'index'] columns = ['xmin', 'ymin', 'xmax', 'ymax', 'object_id', 'score', 'category', 'index']
return pd.DataFrame(data_, columns=columns) return pd.DataFrame(data_, columns=columns)
@@ -147,9 +148,8 @@ class DodgeballTracker:
# run the YOLO model on the frame # run the YOLO model on the frame
detected_objs = self.run_model_on_frame(model, frame) detected_objs = self.run_model_on_frame(model, frame)
tracked_obj = self.update_tracker(tracker, detected_objs, frame) tracked_obj = self.update_tracker(tracker, detected_objs, frame)
# self.video_writer.plot_boxes_to_frame(detected_objs, frame) self.video_writer.plot_boxes_to_frame(detected_objs, frame)
# self.video_writer.write_frame(frame)
# self.video_writer.write_frame(frame)
if self.video_writer.wait(): if self.video_writer.wait():
break break
+16 -22
View File
@@ -2,7 +2,7 @@ from typing import NewType
from dataclasses import dataclass from dataclasses import dataclass
import numpy as np import numpy as np
import pandera as pa import pandera as pa
from pandera.dtypes import Float32 from pandera.dtypes import Float32, Float64
XCoord = NewType('XCoord', float) XCoord = NewType('XCoord', float)
YCoord = NewType('YCoord', float) YCoord = NewType('YCoord', float)
@@ -10,15 +10,16 @@ Score = NewType('Confidence', float)
Category = NewType('Category', float) Category = NewType('Category', float)
@dataclass @dataclass
class Point: class Point:
x: XCoord x: XCoord
y: YCoord y: YCoord
VideoFrame = NewType('Frame', float) VideoFrame = NewType('Frame', float)
VideoTimestamp = float VideoTimestamp = float
@dataclass @dataclass
class DetectedObject: class DetectedObject:
xmin: XCoord xmin: XCoord
@@ -29,31 +30,24 @@ class DetectedObject:
category: Category category: Category
def as_int_box(self) -> tuple[tuple[int, int], tuple[int, int]]: def as_int_box(self) -> tuple[tuple[int, int], tuple[int, int]]:
return (int(self.xmin), int(self.ymin)), (int(self.xmax), int(self.ymax)) return (int(self.xmin), int(self.ymin)), (
int(self.xmax), int(self.ymax))
def as_nparray(self): def as_nparray(self):
return np.array([self.xmin, self.ymax, self.xmax, self.ymax, self.score, self.category]) return np.array([self.xmin, self.ymax, self.xmax, self.ymax, self.score,
self.category])
DetectedObject_ = pa.DataFrameSchema({ def tensor_of(data_type: pa.DataType, cols: list[str]) -> pa.DataFrameSchema:
"xmin": pa.Column(Float32), return pa.DataFrameSchema({col: pa.Column(data_type) for col in cols})
"ymin": pa.Column(Float32),
"xmax": pa.Column(Float32),
"ymin": pa.Column(Float32),
"score": pa.Column(Float32),
"category": pa.Column(Float32),
})
TrackedDetectedObject_ = pa.DataFrameSchema({
"xmin": pa.Column(Float32), DetectedObject_ = tensor_of(Float32, ["xmin", "ymin", "xmax", "ymax", "score",
"ymin": pa.Column(Float32), "category"])
"xmax": pa.Column(Float32),
"ymin": pa.Column(Float32), TrackedDetectedObject_ = tensor_of(Float64,
"object_id": pa.Column(Float32), list(DetectedObject_.columns) + ["object_id", "index"])
"score": pa.Column(Float32), # ["xmin", "ymin", "xmax", "ymax", "object_id", "score", "category", "index"])
"category": pa.Column(Float32),
"index": pa.Column(Float32),
})
Color = tuple[int, int, int] Color = tuple[int, int, int]
+16 -8
View File
@@ -1,6 +1,10 @@
import abc import abc
from pathlib import Path from pathlib import Path
from dodgeballtracker.typing import VideoFrame, DetectedObject, Color
import pandas as pd
import pandera as pa
from dodgeballtracker.typing import VideoFrame, DetectedObject, Color, DetectedObject_
import matplotlib import matplotlib
import cv2 import cv2
@@ -44,7 +48,7 @@ class VideoWriter(abc.ABC):
pass pass
@abc.abstractmethod @abc.abstractmethod
def plot_boxes_to_frame(self, data: list[DetectedObject], frame: VideoFrame) -> None: def plot_boxes_to_frame(self, data: pd.DataFrame, frame: VideoFrame) -> None:
pass pass
@abc.abstractmethod @abc.abstractmethod
@@ -58,7 +62,7 @@ class VideoWriter(abc.ABC):
class NoopVideoWriter(VideoWriter): class NoopVideoWriter(VideoWriter):
def plot_boxes_to_frame(self, boxes: list[DetectedObject], frame: VideoFrame) -> None: def plot_boxes_to_frame(self, boxes: pd.DataFrame, frame: VideoFrame) -> None:
pass pass
def write_frame(self, frame: VideoFrame) -> None: def write_frame(self, frame: VideoFrame) -> None:
@@ -80,16 +84,20 @@ class MP4VVideoWriter(VideoWriter):
def write_frame(self, frame: VideoFrame) -> None: def write_frame(self, frame: VideoFrame) -> None:
self._video_writer.write(frame) self._video_writer.write(frame)
def plot_box_to_frame(self, data: DetectedObject, frame: VideoFrame) -> None: def plot_box_to_frame(self, data: pd.Series, frame: VideoFrame) -> None:
confidence = float(data.score) confidence = float(data.score)
# data = data.map(int)
for threshold in self._thresholds: for threshold in self._thresholds:
if threshold.min_threshold < confidence: if threshold.min_threshold < confidence:
# xmin, ymin, xmax, ymax = self._extract_box(data) start_point = data[['xmin', 'ymin']].array.astype('int32')
cv2.rectangle(frame, *data.as_int_box(), threshold.color, 2) end_point = data[['xmax', 'ymax']].array.astype('int32')
cv2.rectangle(frame, start_point, end_point, threshold.color, 2)
return return
def plot_boxes_to_frame(self, boxes: list[DetectedObject], frame: VideoFrame) -> None: @pa.decorators.check_io(boxes=DetectedObject_)
for box in boxes: def plot_boxes_to_frame(self, boxes: pd.DataFrame, frame: VideoFrame) -> None:
boxes_that_passe_threshold = boxes[boxes['score'] > 0.5]
for i, box in boxes_that_passe_threshold.iterrows():
self.plot_box_to_frame(box, frame) self.plot_box_to_frame(box, frame)