mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Simplify plus submit (#15941)
* remove unused annotate file * improve plus error messages * formatting
This commit is contained in:
		
							parent
							
								
									b8a74793ca
								
							
						
					
					
						commit
						c4727f19e1
					
				@ -61,7 +61,7 @@ def start(id, num_detections, detection_queue, event):
 | 
				
			|||||||
    object_detector.cleanup()
 | 
					    object_detector.cleanup()
 | 
				
			||||||
    print(f"{id} - Processed for {duration:.2f} seconds.")
 | 
					    print(f"{id} - Processed for {duration:.2f} seconds.")
 | 
				
			||||||
    print(f"{id} - FPS: {object_detector.fps.eps():.2f}")
 | 
					    print(f"{id} - FPS: {object_detector.fps.eps():.2f}")
 | 
				
			||||||
    print(f"{id} - Average frame processing time: {mean(frame_times)*1000:.2f}ms")
 | 
					    print(f"{id} - Average frame processing time: {mean(frame_times) * 1000:.2f}ms")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
######
 | 
					######
 | 
				
			||||||
 | 
				
			|||||||
@ -151,7 +151,7 @@ class WebPushClient(Communicator):  # type: ignore[misc]
 | 
				
			|||||||
        camera: str = payload["after"]["camera"]
 | 
					        camera: str = payload["after"]["camera"]
 | 
				
			||||||
        title = f"{', '.join(sorted_objects).replace('_', ' ').title()}{' was' if state == 'end' else ''} detected in {', '.join(payload['after']['data']['zones']).replace('_', ' ').title()}"
 | 
					        title = f"{', '.join(sorted_objects).replace('_', ' ').title()}{' was' if state == 'end' else ''} detected in {', '.join(payload['after']['data']['zones']).replace('_', ' ').title()}"
 | 
				
			||||||
        message = f"Detected on {camera.replace('_', ' ').title()}"
 | 
					        message = f"Detected on {camera.replace('_', ' ').title()}"
 | 
				
			||||||
        image = f'{payload["after"]["thumb_path"].replace("/media/frigate", "")}'
 | 
					        image = f"{payload['after']['thumb_path'].replace('/media/frigate', '')}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # if event is ongoing open to live view otherwise open to recordings view
 | 
					        # if event is ongoing open to live view otherwise open to recordings view
 | 
				
			||||||
        direct_url = f"/review?id={reviewId}" if state == "end" else f"/#{camera}"
 | 
					        direct_url = f"/review?id={reviewId}" if state == "end" else f"/#{camera}"
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,7 @@ class ZoneConfig(BaseModel):
 | 
				
			|||||||
            if explicit:
 | 
					            if explicit:
 | 
				
			||||||
                self.coordinates = ",".join(
 | 
					                self.coordinates = ",".join(
 | 
				
			||||||
                    [
 | 
					                    [
 | 
				
			||||||
                        f'{round(int(p.split(",")[0]) / frame_shape[1], 3)},{round(int(p.split(",")[1]) / frame_shape[0], 3)}'
 | 
					                        f"{round(int(p.split(',')[0]) / frame_shape[1], 3)},{round(int(p.split(',')[1]) / frame_shape[0], 3)}"
 | 
				
			||||||
                        for p in coordinates
 | 
					                        for p in coordinates
 | 
				
			||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
				
			|||||||
@ -219,19 +219,19 @@ class TensorRtDetector(DetectionApi):
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, detector_config: TensorRTDetectorConfig):
 | 
					    def __init__(self, detector_config: TensorRTDetectorConfig):
 | 
				
			||||||
        assert (
 | 
					        assert TRT_SUPPORT, (
 | 
				
			||||||
            TRT_SUPPORT
 | 
					            f"TensorRT libraries not found, {DETECTOR_KEY} detector not present"
 | 
				
			||||||
        ), f"TensorRT libraries not found, {DETECTOR_KEY} detector not present"
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (cuda_err,) = cuda.cuInit(0)
 | 
					        (cuda_err,) = cuda.cuInit(0)
 | 
				
			||||||
        assert (
 | 
					        assert cuda_err == cuda.CUresult.CUDA_SUCCESS, (
 | 
				
			||||||
            cuda_err == cuda.CUresult.CUDA_SUCCESS
 | 
					            f"Failed to initialize cuda {cuda_err}"
 | 
				
			||||||
        ), f"Failed to initialize cuda {cuda_err}"
 | 
					        )
 | 
				
			||||||
        err, dev_count = cuda.cuDeviceGetCount()
 | 
					        err, dev_count = cuda.cuDeviceGetCount()
 | 
				
			||||||
        logger.debug(f"Num Available Devices: {dev_count}")
 | 
					        logger.debug(f"Num Available Devices: {dev_count}")
 | 
				
			||||||
        assert (
 | 
					        assert detector_config.device < dev_count, (
 | 
				
			||||||
            detector_config.device < dev_count
 | 
					            f"Invalid TensorRT Device Config. Device {detector_config.device} Invalid."
 | 
				
			||||||
        ), f"Invalid TensorRT Device Config. Device {detector_config.device} Invalid."
 | 
					        )
 | 
				
			||||||
        err, self.cu_ctx = cuda.cuCtxCreate(
 | 
					        err, self.cu_ctx = cuda.cuCtxCreate(
 | 
				
			||||||
            cuda.CUctx_flags.CU_CTX_MAP_HOST, detector_config.device
 | 
					            cuda.CUctx_flags.CU_CTX_MAP_HOST, detector_config.device
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -68,11 +68,13 @@ class PlusApi:
 | 
				
			|||||||
            or self._token_data["expires"] - datetime.datetime.now().timestamp() < 60
 | 
					            or self._token_data["expires"] - datetime.datetime.now().timestamp() < 60
 | 
				
			||||||
        ):
 | 
					        ):
 | 
				
			||||||
            if self.key is None:
 | 
					            if self.key is None:
 | 
				
			||||||
                raise Exception("Plus API not activated")
 | 
					                raise Exception(
 | 
				
			||||||
 | 
					                    "Plus API key not set. See https://docs.frigate.video/integrations/plus#set-your-api-key"
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
            parts = self.key.split(":")
 | 
					            parts = self.key.split(":")
 | 
				
			||||||
            r = requests.get(f"{self.host}/v1/auth/token", auth=(parts[0], parts[1]))
 | 
					            r = requests.get(f"{self.host}/v1/auth/token", auth=(parts[0], parts[1]))
 | 
				
			||||||
            if not r.ok:
 | 
					            if not r.ok:
 | 
				
			||||||
                raise Exception("Unable to refresh API token")
 | 
					                raise Exception(f"Unable to refresh API token: {r.text}")
 | 
				
			||||||
            self._token_data = r.json()
 | 
					            self._token_data = r.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_authorization_header(self) -> dict:
 | 
					    def _get_authorization_header(self) -> dict:
 | 
				
			||||||
@ -116,15 +118,6 @@ class PlusApi:
 | 
				
			|||||||
            logger.error(f"Failed to upload original: {r.status_code} {r.text}")
 | 
					            logger.error(f"Failed to upload original: {r.status_code} {r.text}")
 | 
				
			||||||
            raise Exception(r.text)
 | 
					            raise Exception(r.text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # resize and submit annotate
 | 
					 | 
				
			||||||
        files = {"file": get_jpg_bytes(image, 640, 70)}
 | 
					 | 
				
			||||||
        data = presigned_urls["annotate"]["fields"]
 | 
					 | 
				
			||||||
        data["content-type"] = "image/jpeg"
 | 
					 | 
				
			||||||
        r = requests.post(presigned_urls["annotate"]["url"], files=files, data=data)
 | 
					 | 
				
			||||||
        if not r.ok:
 | 
					 | 
				
			||||||
            logger.error(f"Failed to upload annotate: {r.status_code} {r.text}")
 | 
					 | 
				
			||||||
            raise Exception(r.text)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # resize and submit thumbnail
 | 
					        # resize and submit thumbnail
 | 
				
			||||||
        files = {"file": get_jpg_bytes(image, 200, 70)}
 | 
					        files = {"file": get_jpg_bytes(image, 200, 70)}
 | 
				
			||||||
        data = presigned_urls["thumbnail"]["fields"]
 | 
					        data = presigned_urls["thumbnail"]["fields"]
 | 
				
			||||||
 | 
				
			|||||||
@ -135,7 +135,7 @@ class PtzMotionEstimator:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                logger.debug(
 | 
					                logger.debug(
 | 
				
			||||||
                    f"{camera}: Motion estimator transformation: {self.coord_transformations.rel_to_abs([[0,0]])}"
 | 
					                    f"{camera}: Motion estimator transformation: {self.coord_transformations.rel_to_abs([[0, 0]])}"
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            except Exception:
 | 
					            except Exception:
 | 
				
			||||||
                pass
 | 
					                pass
 | 
				
			||||||
@ -471,7 +471,7 @@ class PtzAutoTracker:
 | 
				
			|||||||
                self.onvif.get_camera_status(camera)
 | 
					                self.onvif.get_camera_status(camera)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            logger.info(
 | 
					            logger.info(
 | 
				
			||||||
                f"Calibration for {camera} in progress: {round((step/num_steps)*100)}% complete"
 | 
					                f"Calibration for {camera} in progress: {round((step / num_steps) * 100)}% complete"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.calibrating[camera] = False
 | 
					        self.calibrating[camera] = False
 | 
				
			||||||
@ -690,7 +690,7 @@ class PtzAutoTracker:
 | 
				
			|||||||
                            f"{camera}: Predicted movement time: {self._predict_movement_time(camera, pan, tilt)}"
 | 
					                            f"{camera}: Predicted movement time: {self._predict_movement_time(camera, pan, tilt)}"
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                        logger.debug(
 | 
					                        logger.debug(
 | 
				
			||||||
                            f"{camera}: Actual movement time: {self.ptz_metrics[camera].stop_time.value-self.ptz_metrics[camera].start_time.value}"
 | 
					                            f"{camera}: Actual movement time: {self.ptz_metrics[camera].stop_time.value - self.ptz_metrics[camera].start_time.value}"
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # save metrics for better estimate calculations
 | 
					                    # save metrics for better estimate calculations
 | 
				
			||||||
@ -983,10 +983,10 @@ class PtzAutoTracker:
 | 
				
			|||||||
            logger.debug(f"{camera}: Zoom test: at max zoom: {at_max_zoom}")
 | 
					            logger.debug(f"{camera}: Zoom test: at max zoom: {at_max_zoom}")
 | 
				
			||||||
            logger.debug(f"{camera}: Zoom test: at min zoom: {at_min_zoom}")
 | 
					            logger.debug(f"{camera}: Zoom test: at min zoom: {at_min_zoom}")
 | 
				
			||||||
            logger.debug(
 | 
					            logger.debug(
 | 
				
			||||||
                f'{camera}: Zoom test: zoom in hysteresis limit: {zoom_in_hysteresis} value: {AUTOTRACKING_ZOOM_IN_HYSTERESIS} original: {self.tracked_object_metrics[camera]["original_target_box"]} max: {self.tracked_object_metrics[camera]["max_target_box"]} target: {calculated_target_box if calculated_target_box else self.tracked_object_metrics[camera]["target_box"]}'
 | 
					                f"{camera}: Zoom test: zoom in hysteresis limit: {zoom_in_hysteresis} value: {AUTOTRACKING_ZOOM_IN_HYSTERESIS} original: {self.tracked_object_metrics[camera]['original_target_box']} max: {self.tracked_object_metrics[camera]['max_target_box']} target: {calculated_target_box if calculated_target_box else self.tracked_object_metrics[camera]['target_box']}"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            logger.debug(
 | 
					            logger.debug(
 | 
				
			||||||
                f'{camera}: Zoom test: zoom out hysteresis limit: {zoom_out_hysteresis} value: {AUTOTRACKING_ZOOM_OUT_HYSTERESIS} original: {self.tracked_object_metrics[camera]["original_target_box"]} max: {self.tracked_object_metrics[camera]["max_target_box"]} target: {calculated_target_box if calculated_target_box else self.tracked_object_metrics[camera]["target_box"]}'
 | 
					                f"{camera}: Zoom test: zoom out hysteresis limit: {zoom_out_hysteresis} value: {AUTOTRACKING_ZOOM_OUT_HYSTERESIS} original: {self.tracked_object_metrics[camera]['original_target_box']} max: {self.tracked_object_metrics[camera]['max_target_box']} target: {calculated_target_box if calculated_target_box else self.tracked_object_metrics[camera]['target_box']}"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Zoom in conditions (and)
 | 
					        # Zoom in conditions (and)
 | 
				
			||||||
@ -1069,7 +1069,7 @@ class PtzAutoTracker:
 | 
				
			|||||||
                pan = ((centroid_x / camera_width) - 0.5) * 2
 | 
					                pan = ((centroid_x / camera_width) - 0.5) * 2
 | 
				
			||||||
                tilt = (0.5 - (centroid_y / camera_height)) * 2
 | 
					                tilt = (0.5 - (centroid_y / camera_height)) * 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            logger.debug(f'{camera}: Original box: {obj.obj_data["box"]}')
 | 
					            logger.debug(f"{camera}: Original box: {obj.obj_data['box']}")
 | 
				
			||||||
            logger.debug(f"{camera}: Predicted box: {tuple(predicted_box)}")
 | 
					            logger.debug(f"{camera}: Predicted box: {tuple(predicted_box)}")
 | 
				
			||||||
            logger.debug(
 | 
					            logger.debug(
 | 
				
			||||||
                f"{camera}: Velocity: {tuple(np.round(average_velocity).flatten().astype(int))}"
 | 
					                f"{camera}: Velocity: {tuple(np.round(average_velocity).flatten().astype(int))}"
 | 
				
			||||||
@ -1179,7 +1179,7 @@ class PtzAutoTracker:
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    zoom = (ratio - 1) / (ratio + 1)
 | 
					                    zoom = (ratio - 1) / (ratio + 1)
 | 
				
			||||||
                    logger.debug(
 | 
					                    logger.debug(
 | 
				
			||||||
                        f'{camera}: limit: {self.tracked_object_metrics[camera]["max_target_box"]}, ratio: {ratio} zoom calculation: {zoom}'
 | 
					                        f"{camera}: limit: {self.tracked_object_metrics[camera]['max_target_box']}, ratio: {ratio} zoom calculation: {zoom}"
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    if not result:
 | 
					                    if not result:
 | 
				
			||||||
                        # zoom out with special condition if zooming out because of velocity, edges, etc.
 | 
					                        # zoom out with special condition if zooming out because of velocity, edges, etc.
 | 
				
			||||||
 | 
				
			|||||||
@ -449,7 +449,7 @@ class RecordingMaintainer(threading.Thread):
 | 
				
			|||||||
                    return None
 | 
					                    return None
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    logger.debug(
 | 
					                    logger.debug(
 | 
				
			||||||
                        f"Copied {file_path} in {datetime.datetime.now().timestamp()-start_frame} seconds."
 | 
					                        f"Copied {file_path} in {datetime.datetime.now().timestamp() - start_frame} seconds."
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
 | 
				
			|||||||
@ -256,7 +256,7 @@ class ReviewSegmentMaintainer(threading.Thread):
 | 
				
			|||||||
                elif object["sub_label"][0] in self.config.model.all_attributes:
 | 
					                elif object["sub_label"][0] in self.config.model.all_attributes:
 | 
				
			||||||
                    segment.detections[object["id"]] = object["sub_label"][0]
 | 
					                    segment.detections[object["id"]] = object["sub_label"][0]
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    segment.detections[object["id"]] = f'{object["label"]}-verified'
 | 
					                    segment.detections[object["id"]] = f"{object['label']}-verified"
 | 
				
			||||||
                    segment.sub_labels[object["id"]] = object["sub_label"][0]
 | 
					                    segment.sub_labels[object["id"]] = object["sub_label"][0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # if object is alert label
 | 
					                # if object is alert label
 | 
				
			||||||
@ -352,7 +352,7 @@ class ReviewSegmentMaintainer(threading.Thread):
 | 
				
			|||||||
                elif object["sub_label"][0] in self.config.model.all_attributes:
 | 
					                elif object["sub_label"][0] in self.config.model.all_attributes:
 | 
				
			||||||
                    detections[object["id"]] = object["sub_label"][0]
 | 
					                    detections[object["id"]] = object["sub_label"][0]
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    detections[object["id"]] = f'{object["label"]}-verified'
 | 
					                    detections[object["id"]] = f"{object['label']}-verified"
 | 
				
			||||||
                    sub_labels[object["id"]] = object["sub_label"][0]
 | 
					                    sub_labels[object["id"]] = object["sub_label"][0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # if object is alert label
 | 
					                # if object is alert label
 | 
				
			||||||
 | 
				
			|||||||
@ -72,8 +72,7 @@ class BaseServiceProcess(Service, ABC):
 | 
				
			|||||||
                running = False
 | 
					                running = False
 | 
				
			||||||
            except TimeoutError:
 | 
					            except TimeoutError:
 | 
				
			||||||
                self.manager.logger.warning(
 | 
					                self.manager.logger.warning(
 | 
				
			||||||
                    f"{self.name} is still running after "
 | 
					                    f"{self.name} is still running after {timeout} seconds. Killing."
 | 
				
			||||||
                    f"{timeout} seconds. Killing."
 | 
					 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if running:
 | 
					        if running:
 | 
				
			||||||
 | 
				
			|||||||
@ -339,7 +339,7 @@ class TrackedObject:
 | 
				
			|||||||
                box[2],
 | 
					                box[2],
 | 
				
			||||||
                box[3],
 | 
					                box[3],
 | 
				
			||||||
                self.obj_data["label"],
 | 
					                self.obj_data["label"],
 | 
				
			||||||
                f"{int(self.thumbnail_data['score']*100)}% {int(self.thumbnail_data['area'])}",
 | 
					                f"{int(self.thumbnail_data['score'] * 100)}% {int(self.thumbnail_data['area'])}",
 | 
				
			||||||
                thickness=thickness,
 | 
					                thickness=thickness,
 | 
				
			||||||
                color=color,
 | 
					                color=color,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
				
			|||||||
@ -314,7 +314,7 @@ def get_relative_coordinates(
 | 
				
			|||||||
                            continue
 | 
					                            continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        rel_points.append(
 | 
					                        rel_points.append(
 | 
				
			||||||
                            f"{round(x / frame_shape[1], 3)},{round(y  / frame_shape[0], 3)}"
 | 
					                            f"{round(x / frame_shape[1], 3)},{round(y / frame_shape[0], 3)}"
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    relative_masks.append(",".join(rel_points))
 | 
					                    relative_masks.append(",".join(rel_points))
 | 
				
			||||||
@ -337,7 +337,7 @@ def get_relative_coordinates(
 | 
				
			|||||||
                    return []
 | 
					                    return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                rel_points.append(
 | 
					                rel_points.append(
 | 
				
			||||||
                    f"{round(x / frame_shape[1], 3)},{round(y  / frame_shape[0], 3)}"
 | 
					                    f"{round(x / frame_shape[1], 3)},{round(y / frame_shape[0], 3)}"
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mask = ",".join(rel_points)
 | 
					            mask = ",".join(rel_points)
 | 
				
			||||||
 | 
				
			|||||||
@ -208,7 +208,7 @@ class ProcessClip:
 | 
				
			|||||||
                box[2],
 | 
					                box[2],
 | 
				
			||||||
                box[3],
 | 
					                box[3],
 | 
				
			||||||
                obj["id"],
 | 
					                obj["id"],
 | 
				
			||||||
                f"{int(obj['score']*100)}% {int(obj['area'])}",
 | 
					                f"{int(obj['score'] * 100)}% {int(obj['area'])}",
 | 
				
			||||||
                thickness=thickness,
 | 
					                thickness=thickness,
 | 
				
			||||||
                color=color,
 | 
					                color=color,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -227,7 +227,7 @@ class ProcessClip:
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cv2.imwrite(
 | 
					        cv2.imwrite(
 | 
				
			||||||
            f"{os.path.join(debug_path, os.path.basename(self.clip_path))}.{int(frame_time*1000000)}.jpg",
 | 
					            f"{os.path.join(debug_path, os.path.basename(self.clip_path))}.{int(frame_time * 1000000)}.jpg",
 | 
				
			||||||
            current_frame,
 | 
					            current_frame,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -290,7 +290,7 @@ def process(path, label, output, debug_path):
 | 
				
			|||||||
        1 for result in results if result[1]["true_positive_objects"] > 0
 | 
					        1 for result in results if result[1]["true_positive_objects"] > 0
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    print(
 | 
					    print(
 | 
				
			||||||
        f"Objects were detected in {positive_count}/{len(results)}({positive_count/len(results)*100:.2f}%) clip(s)."
 | 
					        f"Objects were detected in {positive_count}/{len(results)}({positive_count / len(results) * 100:.2f}%) clip(s)."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if output:
 | 
					    if output:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user