فهرست منبع

chore: update configs, model and detection logic

1. fix missing match_count default value in calibration.py
2. update PTZ mount type to ceiling and disable ptz detection
3. switch detection model to yolo11s onnx and lower confidence threshold
4. refactor ONNX model loading to use Ultralytics
5. add sigmoid confidence calculation and NMS post-processing
wenhongquan 2 روز پیش
والد
کامیت
87522b274c

BIN
dual_camera_system/__pycache__/calibration.cpython-313.pyc


BIN
dual_camera_system/__pycache__/panorama_camera.cpython-310.pyc


+ 1 - 1
dual_camera_system/calibration.py

@@ -1602,7 +1602,7 @@ class CameraCalibrator:
                         pan_end=r['pan_end'],
                         tilt_start=r['tilt_start'],
                         tilt_end=r['tilt_end'],
-                        match_count=r['match_count'],
+                        match_count=r.get('match_count', 0),
                         panorama_center_x=0,
                         panorama_center_y=0
                     )

BIN
dual_camera_system/config/__pycache__/__init__.cpython-313.pyc


BIN
dual_camera_system/config/__pycache__/camera.cpython-310.pyc


BIN
dual_camera_system/config/__pycache__/coordinator.cpython-310.pyc


BIN
dual_camera_system/config/__pycache__/detection.cpython-310.pyc


BIN
dual_camera_system/config/__pycache__/detection.cpython-313.pyc


BIN
dual_camera_system/config/__pycache__/ptz.cpython-310.pyc


+ 3 - 3
dual_camera_system/config/detection.py

@@ -14,8 +14,8 @@ def _default_model():
 
     if system == 'Linux' and machine == 'aarch64':
         # RK3588 / ARM64 NPU
-        # 使用 yolo26n end2end RKNN(单输出 1x300x6,x1/y1/x2/y2/conf/cls
-        return '/home/admin/dsh/testrk3588/yolo26n_end2end.rknn', 'rknn'
+        # 使用 yolo11s.onnx(Ultralytics 推理
+        return '/home/admin/dsh/testrk3588/yolo11s.onnx', 'onnx'
     elif system == 'Darwin':
         # macOS 本地测试:使用 yolo11n.pt,Ultralytics 会自动下载
         return '/Users/wenhongquan/Desktop/阿里云同步/项目/dnn/sb/model/yolo11n.pt', 'yolo'
@@ -48,7 +48,7 @@ DETECTION_CONFIG = {
     'use_gpu': True,                # 是否使用 GPU / NPU
 
     # 人体检测后处理阈值
-    'person_threshold': 0.5,    # 进入联动跟踪的人体置信度阈值
+    'person_threshold': 0.3,    # 进入联动跟踪的人体置信度阈值
 
     # RKNN/ONNX 模型类别映射(yolo26n COCO80:0=person)
     'class_map': {0: 'person'},

+ 2 - 3
dual_camera_system/config/ptz.py

@@ -29,8 +29,7 @@ PTZ_CONFIG = {
 
     # 球机安装方向配置
     # mount_type: 'ceiling' - 吸顶/吊装(镜头朝下), 'wall' - 壁装/立杆(镜头水平/朝下看)
-    # 测试环境设备端已设 ceiling 模式,代码层按 wall 处理
-    'mount_type': 'wall',
+    'mount_type': 'ceiling',
 
     # 方向修正(根据实际安装方向调整)
     # pan_flip: 如果球机与全景朝向相反(球机看后面),设为True
@@ -52,7 +51,7 @@ PTZ_CONFIG = {
     'overlap_tilt_step': 10,
 
     # 球机端人体检测与自动对焦配置
-    'enable_ptz_detection': True,    # 是否启用球机端人体检测
+    'enable_ptz_detection': False,    # 是否启用球机端人体检测
     'auto_zoom': {
         'enabled': True,             # 是否启用自动变焦
         'target_size_ratio': 0.2,    # 目标人体占画面比例(提高以获得更近的图像)

+ 13 - 10
dual_camera_system/panorama_camera.py

@@ -523,18 +523,17 @@ class ObjectDetector:
             raise ImportError("未安装 rknnlite,请运行: pip install rknnlite2")
     
     def _load_onnx_model(self):
-        """加载 ONNX 模型"""
+        """加载 ONNX 模型(使用 Ultralytics 推理,保证后处理正确)"""
         if not self.model_path:
             raise ValueError("ONNX 模型需要指定 model_path")
-        
+
         try:
-            import onnxruntime as ort
-            self.session = ort.InferenceSession(self.model_path)
-            self.input_name = self.session.get_inputs()[0].name
-            self.output_names = [o.name for o in self.session.get_outputs()]
-            print(f"ONNX 模型加载成功: {self.model_path}, 输出数量={len(self.output_names)}")
+            from ultralytics import YOLO
+            self.model = YOLO(self.model_path, task='detect')
+            self.device = 'cpu'  # RK3588 无 CUDA,强制 CPU
+            print(f"ONNX 模型加载成功: {self.model_path} (via Ultralytics, device=cpu)")
         except ImportError:
-            raise ImportError("未安装 onnxruntime,请运行: pip install onnxruntime")
+            raise ImportError("未安装 ultralytics")
     
     def _load_yolo_model(self):
         """加载YOLO11检测模型"""
@@ -929,7 +928,7 @@ class ObjectDetector:
 
                     class_probs = output[4:, i]
                     best_class = int(np.argmax(class_probs))
-                    confidence = float(class_probs[best_class])
+                    confidence = 1.0 / (1.0 + np.exp(-float(class_probs[best_class])))
 
                     if confidence < conf_threshold:
                         continue
@@ -972,6 +971,7 @@ class ObjectDetector:
         """分区域检测 - 将宽幅全景图分成多个重叠区域分别检测,提高远处目标识别率"""
         results = []
         h0, w0 = frame.shape[:2]
+        need_nms = not self.is_end2end
         conf_threshold = self.config['confidence_threshold']
         class_map = self.config.get('class_map', {0: 'person'})
 
@@ -1038,7 +1038,7 @@ class ObjectDetector:
                     for i in range(output.shape[1]):
                         class_probs = output[4:, i]
                         best_class = int(np.argmax(class_probs))
-                        confidence = float(class_probs[best_class])
+                        confidence = 1.0 / (1.0 + np.exp(-float(class_probs[best_class])))
                         if confidence < conf_threshold:
                             continue
                         x1 = output[0, i] - output[2, i] / 2
@@ -1086,6 +1086,9 @@ class ObjectDetector:
                 )
                 results.append(obj)
 
+        if need_nms and results:
+            results = nms(results, iou_threshold=0.45)
+
         return results
     
     def detect(self, frame: np.ndarray) -> List[DetectedObject]: