diff --git a/src/polystar/dependency_injection.py b/src/polystar/dependency_injection.py index 748cb1ebe40f744ec0a10b272ec13506f471f5ca..71276be16e6d770b2137ed8542ec626073dc8e56 100644 --- a/src/polystar/dependency_injection.py +++ b/src/polystar/dependency_injection.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import List +from typing import List, Type from injector import Injector, Module, multiprovider, provider, singleton from numpy.core._multiarray_umath import deg2rad @@ -25,7 +25,6 @@ from polystar.target_pipeline.objects_linker.objects_linker_abs import ObjectsLi from polystar.target_pipeline.objects_linker.simple_objects_linker import SimpleObjectsLinker from polystar.target_pipeline.target_factories.ratio_simple_target_factory import RatioSimpleTargetFactory from polystar.target_pipeline.target_factories.target_factory_abc import TargetFactoryABC -from research.common.constants import PIPELINES_DIR def make_injector() -> Injector: @@ -57,15 +56,14 @@ class CommonModule(Module): @provider @singleton - def provide_objects_detector(self) -> ObjectsDetectorABC: - model_dir = PIPELINES_DIR / "roco-detection" / settings.OBJECTS_DETECTION_MODEL + def provide_objects_detector_class(self) -> Type[ObjectsDetectorABC]: if self.settings.is_dev: from polystar.target_pipeline.objects_detectors.tf_model_objects_detector import TFModelObjectsDetector - return TFModelObjectsDetector(model_dir) + return TFModelObjectsDetector from polystar.target_pipeline.objects_detectors.trt_model_object_detector import TRTModelObjectsDetector - return TRTModelObjectsDetector(model_dir) + return TRTModelObjectsDetector @multiprovider @singleton @@ -104,6 +102,7 @@ class CommonModule(Module): return SimpleObjectsLinker(min_percentage_intersection=0.8) @provider + @singleton def provide_webcam(self) -> FrameGeneratorABC: if self.settings.is_prod: return make_csi_camera_frame_generator(1_280, 720) diff --git a/src/polystar/frame_generators/cv2_frame_generator_abc.py b/src/polystar/frame_generators/cv2_frame_generator_abc.py index f191ea187582e6b267180a229d6c19dce298fb96..46d7969d649bf177fe251e0a87d4a42809a83059 100644 --- a/src/polystar/frame_generators/cv2_frame_generator_abc.py +++ b/src/polystar/frame_generators/cv2_frame_generator_abc.py @@ -18,7 +18,8 @@ class CV2Capture(Iterator[Image]): def __init__(self, capture_params: Iterable): self._cap = VideoCapture(*capture_params) assert self._cap.isOpened() - self._cap.set(CAP_PROP_BUFFERSIZE, 0) + + # self._cap.set(CAP_PROP_BUFFERSIZE, 0) def __next__(self) -> Image: success, frame = self._cap.read() diff --git a/src/polystar/target_pipeline/objects_detectors/robots_detector.py b/src/polystar/target_pipeline/objects_detectors/robots_detector.py index 30e563186e0c2a018aaafa685364f9568cdfdf63..ab69fda7ac7618a2cf3b5c7b52b1ccbac0ff8a1e 100644 --- a/src/polystar/target_pipeline/objects_detectors/robots_detector.py +++ b/src/polystar/target_pipeline/objects_detectors/robots_detector.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from threading import Condition -from typing import Iterable, List, Tuple +from typing import Iterable, List, Tuple, Type from injector import inject @@ -8,28 +8,29 @@ from polystar.models.box import Box from polystar.models.image import Image from polystar.models.label_map import LabelMap from polystar.models.roco_object import ObjectType +from polystar.settings import settings from polystar.target_pipeline.detected_objects.detected_armor import DetectedArmor from polystar.target_pipeline.detected_objects.detected_robot import DetectedRobot from polystar.target_pipeline.detected_objects.objects_params import ObjectParams from polystar.target_pipeline.objects_detectors.objects_detector_abc import ObjectsDetectorABC from polystar.target_pipeline.objects_linker.objects_linker_abs import ObjectsLinkerABC from polystar.utils.thread import MyThread +from polystar.utils.time import time_it +from research.common.constants import PIPELINES_DIR @inject @dataclass class RobotsDetector: label_map: LabelMap - object_detector: ObjectsDetectorABC + object_detector_class: Type[ObjectsDetectorABC] objects_linker: ObjectsLinkerABC def flow_robots(self, images: Iterable[Image]) -> Iterable[List[DetectedRobot]]: - detector_thread = ObjectsDetectorThread(self.object_detector, images) + detector_thread = ObjectsDetectorThread(self.object_detector_class, images) detector_thread.start() while detector_thread.running: - with detector_thread.condition: - detector_thread.condition.wait() # TODO: timeout ? - image, objects_params = detector_thread.image, detector_thread.objects_params + image, objects_params = detector_thread.get_next_detection() robots, armors = self.make_robots_and_armors(objects_params, image) yield image, list(self.objects_linker.link_armors_to_robots(robots, armors, image)) @@ -56,16 +57,26 @@ class RobotsDetector: class ObjectsDetectorThread(MyThread): - def __init__(self, objects_detector: ObjectsDetectorABC, images: Iterable[Image]): + def __init__(self, objects_detector_class: Type[ObjectsDetectorABC], images: Iterable[Image]): super().__init__() - self.objects_detector = objects_detector - self.objects_params: List[ObjectParams] = None + self.objects_detector_class = objects_detector_class self.images = images self.condition = Condition() + self.image = None + + def get_next_detection(self) -> Tuple[Image, List[ObjectParams]]: + with self.condition: + self.condition.wait() + return self.image, self.objects_params def loop(self): + model_dir = PIPELINES_DIR / "roco-detection" / settings.OBJECTS_DETECTION_MODEL + objects_detector = self.objects_detector_class(model_dir) for image in self.images: - objects_params = self.objects_detector.detect(image) + if not (image != self.image).any(): + continue + + objects_params = objects_detector.detect(image) with self.condition: self.image, self.objects_params = image, objects_params diff --git a/src/polystar/target_pipeline/objects_detectors/trt_model_object_detector.py b/src/polystar/target_pipeline/objects_detectors/trt_model_object_detector.py index 2ab21540328f2787856f84d062efb5a7830d4ebf..8ab92f206e3f2a57202178390b0ad4d0b0ba35e2 100644 --- a/src/polystar/target_pipeline/objects_detectors/trt_model_object_detector.py +++ b/src/polystar/target_pipeline/objects_detectors/trt_model_object_detector.py @@ -11,8 +11,6 @@ import tensorrt as trt from polystar.constants import RESOURCES_DIR from polystar.models.image import Image -from polystar.target_pipeline.detected_objects.detected_armor import DetectedArmor -from polystar.target_pipeline.detected_objects.detected_robot import DetectedRobot from polystar.target_pipeline.detected_objects.objects_params import ObjectParams from polystar.target_pipeline.objects_detectors.objects_detector_abc import ObjectsDetectorABC @@ -24,34 +22,32 @@ class TRTModelObjectsDetector(ObjectsDetectorABC): def __post_init__(self, model_dir: Path): self.trt_model = TRTModel(model_dir / "trt_model.bin", (300, 300)) - def detect(self, image: Image) -> Tuple[List[DetectedRobot], List[DetectedArmor]]: + def detect(self, image: Image) -> List[ObjectParams]: results = self.trt_model(image) - return self._construct_objects_from_trt_results(results, image) - - def _construct_objects_from_trt_results( - self, results: np.ndarray, image: Image - ) -> Tuple[List[DetectedRobot], List[DetectedArmor]]: - return self.objects_factory.make_lists( - [ - ObjectParams( - ymin=float(ymin), - xmin=float(xmin), - ymax=float(ymax), - xmax=float(xmax), - score=float(score), - object_class_id=int(object_class_id), - ) - for (_, object_class_id, score, xmin, ymin, xmax, ymax) in results - if object_class_id >= 0 - ], - image, + return _construct_objects_from_trt_results(results) + + +def _construct_objects_from_trt_results(results: np.ndarray) -> List[ObjectParams]: + return [ + ObjectParams( + ymin=float(ymin), + xmin=float(xmin), + ymax=float(ymax), + xmax=float(xmax), + score=float(score), + object_class_id=int(object_class_id), ) + for (_, object_class_id, score, xmin, ymin, xmax, ymax) in results + if object_class_id == 4 and score >= 0.1 + ] class TRTModel: def __init__(self, trt_model_path: Path, input_size: Tuple[int, int]): self.input_size = input_size + self.cuda_ctx = cuda.Device(0).make_context() + self.trt_logger = trt.Logger(trt.Logger.INFO) self._load_plugins() self.engine = self._load_engine(trt_model_path) @@ -117,3 +113,4 @@ class TRTModel: del self.stream del self.cuda_outputs del self.cuda_inputs + self.cuda_ctx.pop() diff --git a/src/research/scripts/demo_pipeline_camera.py b/src/research/scripts/demo_pipeline_camera.py index cddc0321e5977945cbced26ee426d56844ea75d1..9a18f564ef806de330aa83d4273c8e44202c711f 100644 --- a/src/research/scripts/demo_pipeline_camera.py +++ b/src/research/scripts/demo_pipeline_camera.py @@ -28,6 +28,7 @@ class CameraPipelineDemo: for debug_info in self.pipeline.flow_debug(self.webcam): self._send_target(debug_info.target) self._display(viewer, debug_info) + self.fps.skip() def _send_target(self, target: Optional[SimpleTarget]): if target is not None: