diff --git a/docs/docs/configuration/object_detectors.md b/docs/docs/configuration/object_detectors.md index 8f84c002a..27fb5a75f 100644 --- a/docs/docs/configuration/object_detectors.md +++ b/docs/docs/configuration/object_detectors.md @@ -318,10 +318,6 @@ detectors: # required core_mask: 0 # yolov8 model in rknn format to use; allowed calues: n, s, m, l, x yolov8_rknn_model: n - # minimal confidence for detection - min_score: 0.5 - # determines whether two overlapping boxes should be combined - nms_thresh: 0.45 model: # required # path to .rknn model file @@ -343,10 +339,6 @@ Explanation for rknn specific options: - `core_mask: 0b011` use core0 and core1. - `core_mask: 0b110` use core1 and core2. **This does not** work, since core0 is disabled. - **yolov8_rknn_model** see section below. -- **min_score** sets the minimal detection confidence. Should have the same value as min_score in the object block. See also [Reducing false positives](/guides/false_positives.md). -- **nms_thresh** is the IoU threshold for Non-maximum Suppression (NMS). Enable "bounding boxes" in the debug viewer. - - *Decrease* if two overlapping objects (for example one person in front of another) are detected as one object. - - *Increase* if there are multiple boxes around one object. ### Choosing a model diff --git a/frigate/detectors/plugins/rknn.py b/frigate/detectors/plugins/rknn.py index dee975025..1055119f2 100644 --- a/frigate/detectors/plugins/rknn.py +++ b/frigate/detectors/plugins/rknn.py @@ -29,13 +29,6 @@ class RknnDetectorConfig(BaseDetectorConfig): type: Literal[DETECTOR_KEY] yolov8_rknn_model: Literal["n", "s", "m", "l", "x"] = "n" core_mask: int = Field(default=0, ge=0, le=7, title="Core mask for NPU.") - min_score: float = Field( - default=0.5, ge=0, le=1, title="Minimal confidence for detection." - ) - nms_thresh: float = Field( - default=0.45, ge=0, le=1, title="IoU threshold for non-maximum suppression." - ) - class Rknn(DetectionApi): type_key = DETECTOR_KEY @@ -99,8 +92,6 @@ class Rknn(DetectionApi): self.height = config.model.height self.width = config.model.width self.core_mask = config.core_mask - self.min_score = config.min_score - self.nms_thresh = config.nms_thresh from rknnlite.api import RKNNLite @@ -126,46 +117,37 @@ class Rknn(DetectionApi): detections: array with shape (20, 6) with 20 rows of (class, confidence, y_min, x_min, y_max, x_max) """ - results = np.transpose(results[0, :, :, 0]) # array shape (2100, 84) - classes = np.argmax( - results[:, 4:], axis=1 - ) # array shape (2100,); index of class with max confidence of each row + results = np.transpose(results[0, :, :, 0]) # array shape (2100, 84) scores = np.max( results[:, 4:], axis=1 ) # array shape (2100,); max confidence of each row + results = [np.where(scores > 0.4)] + + detections = np.zeros((20, 6), np.float32) + num_detections = len(scores) + + if num_detections > 20: + max_ind = np.argpartition(scores, -20)[:-20] + results = results[max_ind] + scores = scores[max_ind] + num_detections = 20 + + classes = np.argmax(results[:, 4:], axis=1) - # array shape (2100, 4); bounding box of each row boxes = np.transpose( np.vstack( ( - results[:, 0] - 0.5 * results[:, 2], results[:, 1] - 0.5 * results[:, 3], - results[:, 2], - results[:, 3], + results[:, 0] - 0.5 * results[:, 2], + results[:, 3] + 0.5 * results[:, 3], + results[:, 2] + 0.5 * results[:, 2], ) ) ) - # indices of rows with confidence > min_score with Non-maximum Suppression (NMS) - result_boxes = cv2.dnn.NMSBoxes( - boxes, scores, self.min_score, self.nms_thresh, 0.5 - ) - - detections = np.zeros((20, 6), np.float32) - - for i in range(len(result_boxes)): - if i >= 20: - break - - index = result_boxes[i] - detections[i] = [ - classes[index], - scores[index], - (boxes[index][1]) / self.height, - (boxes[index][0]) / self.width, - (boxes[index][1] + boxes[index][3]) / self.height, - (boxes[index][0] + boxes[index][2]) / self.width, - ] + detections[:num_detections, 0] = classes + detections[:num_detections, 1] = scores + detections[:num_detections, 2:] = boxes return detections