更新ROI相关文件并修改配置
This commit is contained in:
parent
1821dbcced
commit
189bd45223
@ -1,69 +0,0 @@
|
||||
# ROI区域过滤验证工具
|
||||
|
||||
## 项目结构
|
||||
```
|
||||
ROI/
|
||||
├── roi_filter.py # ROI过滤核心模块
|
||||
├── validate_roi_setup.py # ROI设置验证工具
|
||||
├── test_roi_logic.py # ROI逻辑测试
|
||||
├── test_roi_rtsp.py # RTSP流测试(含GUI)
|
||||
└── README.md # 本说明文档
|
||||
```
|
||||
|
||||
## 验证结果
|
||||
✅ **ROI设置验证成功!**
|
||||
|
||||
- 配置文件加载: 正常
|
||||
- ROI区域定义: 正常 (2个区域)
|
||||
- 坐标过滤功能: 正常
|
||||
- RTSP流测试: 正常
|
||||
|
||||
## ROI区域配置
|
||||
当前配置了以下ROI区域:
|
||||
|
||||
1. **control_lever_area** (控制摇杆区域)
|
||||
- 坐标范围: (0.10, 0.70) -> (0.30, 0.90)
|
||||
- 状态: 启用
|
||||
|
||||
2. **valve_area** (阀门区域)
|
||||
- 坐标范围: (0.70, 0.60) -> (0.80, 0.80)
|
||||
- 状态: 启用
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 验证ROI设置
|
||||
```bash
|
||||
python validate_roi_setup.py
|
||||
```
|
||||
|
||||
### 2. 在d8_5.py中集成ROI过滤
|
||||
```python
|
||||
from ROI.roi_filter import ROIManager
|
||||
|
||||
# 初始化ROI管理器
|
||||
roi_manager = ROIManager("../config.yaml")
|
||||
|
||||
# 在检测循环中应用过滤
|
||||
filtered_detections = roi_manager.filter_detections(detections, frame_width, frame_height)
|
||||
```
|
||||
|
||||
### 3. 修改ROI配置
|
||||
编辑项目根目录下的 `config.yaml` 文件,修改 `roi_filter` 部分:
|
||||
|
||||
```yaml
|
||||
roi_filter:
|
||||
enabled: true
|
||||
regions:
|
||||
- name: "区域名称"
|
||||
x_min: 0.1 # X坐标最小值 (0-1)
|
||||
x_max: 0.3 # X坐标最大值 (0-1)
|
||||
y_min: 0.7 # Y坐标最小值 (0-1)
|
||||
y_max: 0.9 # Y坐标最大值 (0-1)
|
||||
description: "区域描述"
|
||||
enabled: true # 是否启用
|
||||
```
|
||||
|
||||
## 验证说明
|
||||
- 红色矩形框表示ROI区域
|
||||
- 在ROI区域内的检测目标将被过滤掉
|
||||
- 可通过修改配置文件动态调整ROI区域
|
||||
@ -1,21 +0,0 @@
|
||||
input:
|
||||
height: 480
|
||||
video_path: rtsp://10.0.0.50:8554/camera_test/scene1
|
||||
width: 640
|
||||
roi_filter:
|
||||
enabled: true
|
||||
regions:
|
||||
- description: 控制摇杆区域
|
||||
enabled: true
|
||||
name: control_lever_area
|
||||
x_max: 0.3
|
||||
x_min: 0.1
|
||||
y_max: 0.9
|
||||
y_min: 0.7
|
||||
- description: 阀门区域
|
||||
enabled: true
|
||||
name: valve_area
|
||||
x_max: 0.8
|
||||
x_min: 0.7
|
||||
y_max: 0.8
|
||||
y_min: 0.6
|
||||
@ -1,77 +0,0 @@
|
||||
# roi_filter.py
|
||||
import yaml
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
class ROIManager:
|
||||
def __init__(self, config_path="../config.yaml"):
|
||||
self.config_path = config_path
|
||||
self.roi_config = self.load_config()
|
||||
|
||||
def load_config(self):
|
||||
try:
|
||||
with open(self.config_path, 'r', encoding='utf-8') as f:
|
||||
config = yaml.safe_load(f)
|
||||
roi_config = config.get('roi_filter', {})
|
||||
return roi_config
|
||||
except FileNotFoundError:
|
||||
print(f"配置文件 {self.config_path} 不存在")
|
||||
return {"enabled": False, "regions": []}
|
||||
except yaml.YAMLError as e:
|
||||
print(f"解析YAML配置文件出错: {e}")
|
||||
return {"enabled": False, "regions": []}
|
||||
|
||||
def is_in_any_roi(self, center_x, center_y):
|
||||
if not self.roi_config.get('enabled', False):
|
||||
return False, None
|
||||
|
||||
regions = self.roi_config.get('regions', [])
|
||||
for region in regions:
|
||||
if (region.get('enabled', True) and
|
||||
region['x_min'] <= center_x <= region['x_max'] and
|
||||
region['y_min'] <= center_y <= region['y_max']):
|
||||
return True, region.get('name', 'unknown')
|
||||
return False, None
|
||||
|
||||
def filter_detections(self, detections, img_width, img_height):
|
||||
if not self.roi_config.get('enabled', False):
|
||||
return detections
|
||||
|
||||
filtered_detections = []
|
||||
for det in detections:
|
||||
center_x = ((det[0] + det[2]) / 2) / img_width
|
||||
center_y = ((det[1] + det[3]) / 2) / img_height
|
||||
|
||||
in_roi, roi_name = self.is_in_any_roi(center_x, center_y)
|
||||
if not in_roi:
|
||||
filtered_detections.append(det)
|
||||
else:
|
||||
print(f"过滤检测框: 位置({center_x:.2f}, {center_y:.2f}) 在ROI区域 {roi_name}")
|
||||
|
||||
return filtered_detections
|
||||
|
||||
def draw_roi_regions(self, frame):
|
||||
if not self.roi_config.get('enabled', False):
|
||||
return frame
|
||||
|
||||
height, width = frame.shape[:2]
|
||||
regions = self.roi_config.get('regions', [])
|
||||
|
||||
frame_with_roi = frame.copy()
|
||||
|
||||
for region in regions:
|
||||
if region.get('enabled', True):
|
||||
x_min = int(region['x_min'] * width)
|
||||
x_max = int(region['x_max'] * width)
|
||||
y_min = int(region['y_min'] * height)
|
||||
y_max = int(region['y_max'] * height)
|
||||
|
||||
cv2.rectangle(frame_with_roi, (x_min, y_min), (x_max, y_max), (0, 0, 255), 2)
|
||||
cv2.putText(frame_with_roi, region['name'], (x_min, y_min - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
|
||||
|
||||
return frame_with_roi
|
||||
|
||||
def draw_roi_on_frame(frame, config_path="../config.yaml"):
|
||||
roi_manager = ROIManager(config_path)
|
||||
return roi_manager.draw_roi_regions(frame)
|
||||
@ -1,110 +0,0 @@
|
||||
# test_roi_logic.py
|
||||
import yaml
|
||||
import numpy as np
|
||||
from roi_filter import ROIManager
|
||||
|
||||
def test_roi_logic():
|
||||
print("="*50)
|
||||
print("ROI配置逻辑验证测试")
|
||||
print("="*50)
|
||||
|
||||
# 初始化ROI管理器
|
||||
roi_manager = ROIManager("../config.yaml")
|
||||
|
||||
print(f"✅ ROI配置加载完成")
|
||||
print(f" ROI过滤启用状态: {roi_manager.roi_config.get('enabled', False)}")
|
||||
|
||||
regions = roi_manager.roi_config.get('regions', [])
|
||||
print(f" 定义的ROI区域数量: {len(regions)}")
|
||||
|
||||
for i, region in enumerate(regions):
|
||||
print(f" 区域 {i+1}: {region.get('name', 'N/A')} - "
|
||||
f"({region.get('x_min', 0):.2f}, {region.get('y_min', 0):.2f}) 到 "
|
||||
f"({region.get('x_max', 1):.2f}, {region.get('y_max', 1):.2f})")
|
||||
|
||||
print("\n" + "="*50)
|
||||
print("ROI坐标检测验证")
|
||||
print("="*50)
|
||||
|
||||
# 测试一些坐标点
|
||||
test_points = [
|
||||
(0.2, 0.8), # 应该在control_lever_area区域 (如果x_min=0.1, x_max=0.3, y_min=0.7, y_max=0.9)
|
||||
(0.75, 0.7), # 应该在valve_area区域 (如果x_min=0.7, x_max=0.8, y_min=0.6, y_max=0.8)
|
||||
(0.5, 0.5), # 应该在非ROI区域
|
||||
]
|
||||
|
||||
for x, y in test_points:
|
||||
in_roi, roi_name = roi_manager.is_in_any_roi(x, y)
|
||||
status = "🔴 在ROI区域" if in_roi else "🟢 不在ROI区域"
|
||||
print(f"坐标 ({x:.2f}, {y:.2f}): {status} {roi_name if in_roi else ''}")
|
||||
|
||||
print("\n" + "="*50)
|
||||
print("ROI过滤功能验证")
|
||||
print("="*50)
|
||||
|
||||
# 模拟检测结果 [x1, y1, x2, y2, conf, class_id]
|
||||
# 假设图像尺寸为640x480
|
||||
mock_detections = [
|
||||
[50, 50, 150, 150, 0.8, 0], # 左上角 (0.08, 0.1) - 不在ROI
|
||||
[100, 300, 200, 400, 0.9, 0], # 左下角 (0.16, 0.71) - 可能在control_lever_area
|
||||
[400, 250, 500, 350, 0.7, 0], # 右下角 (0.63, 0.64) - 可能不在ROI
|
||||
[450, 300, 550, 400, 0.85, 0], # 右下角 (0.7, 0.71) - 可能在valve_area
|
||||
]
|
||||
|
||||
print(f"原始检测数量: {len(mock_detections)}")
|
||||
|
||||
filtered_detections = roi_manager.filter_detections(mock_detections, 640, 480)
|
||||
print(f"过滤后检测数量: {len(filtered_detections)}")
|
||||
|
||||
print(f"\n✅ ROI逻辑验证完成!")
|
||||
print(f" - 配置文件加载: {'成功' if roi_manager.roi_config else '失败'}")
|
||||
print(f" - ROI区域检测: {'正常' if len(regions) > 0 else '无区域定义'}")
|
||||
print(f" - 坐标过滤功能: {'正常' if True else '异常'}") # 假设总是正常的
|
||||
|
||||
return True
|
||||
|
||||
def test_roi_with_sample_config():
|
||||
"""创建并测试示例配置"""
|
||||
sample_config = {
|
||||
'roi_filter': {
|
||||
'enabled': True,
|
||||
'regions': [
|
||||
{
|
||||
'name': 'control_lever_area',
|
||||
'x_min': 0.1,
|
||||
'x_max': 0.3,
|
||||
'y_min': 0.7,
|
||||
'y_max': 0.9,
|
||||
'description': '控制摇杆区域',
|
||||
'enabled': True
|
||||
},
|
||||
{
|
||||
'name': 'valve_area',
|
||||
'x_min': 0.7,
|
||||
'x_max': 0.8,
|
||||
'y_min': 0.6,
|
||||
'y_max': 0.8,
|
||||
'description': '阀门区域',
|
||||
'enabled': True
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# 保存示例配置
|
||||
with open('../config.yaml', 'w', encoding='utf-8') as f:
|
||||
yaml.dump(sample_config, f, default_flow_style=False, allow_unicode=True)
|
||||
|
||||
print("✅ 示例配置已创建")
|
||||
return test_roi_logic()
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
|
||||
# 检查配置文件是否存在
|
||||
config_path = "../config.yaml"
|
||||
if not os.path.exists(config_path):
|
||||
print("⚠️ 主配置文件不存在,创建示例配置...")
|
||||
test_roi_with_sample_config()
|
||||
else:
|
||||
test_roi_logic()
|
||||
@ -1,164 +0,0 @@
|
||||
# test_roi_rtsp.py
|
||||
import cv2
|
||||
import numpy as np
|
||||
from roi_filter import draw_roi_on_frame
|
||||
import sys
|
||||
import os
|
||||
|
||||
def test_roi_with_rtsp():
|
||||
print("="*50)
|
||||
print("ROI区域RTSP流验证测试")
|
||||
print("请检查:红色矩形框是否出现在RTSP流图像上")
|
||||
print("按'q'退出")
|
||||
print("="*50)
|
||||
|
||||
# RTSP流地址 - 根据您的配置
|
||||
rtsp_url = "rtsp://10.0.0.50:8554/camera_test/scene1"
|
||||
|
||||
# 创建视频捕获对象
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
|
||||
# 设置一些参数以优化RTSP流
|
||||
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 减少缓冲延迟
|
||||
|
||||
if not cap.isOpened():
|
||||
print(f"❌ 无法连接到RTSP流: {rtsp_url}")
|
||||
print("请检查RTSP流地址是否正确")
|
||||
return
|
||||
|
||||
print(f"✅ 成功连接到RTSP流: {rtsp_url}")
|
||||
print("等待视频流开始...")
|
||||
|
||||
frame_count = 0
|
||||
while True:
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
print("❌ 无法读取视频帧,可能RTSP流已断开")
|
||||
break
|
||||
|
||||
frame_count += 1
|
||||
|
||||
# 应用ROI区域绘制
|
||||
frame_with_roi = draw_roi_on_frame(frame, "../config.yaml")
|
||||
|
||||
# 添加状态信息
|
||||
status_text = f'Frame: {frame_count} | ROI Test Active'
|
||||
cv2.putText(frame_with_roi, status_text, (10, 30),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
||||
cv2.putText(frame_with_roi, 'Press Q to quit', (10, 60),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
||||
|
||||
# 显示带有ROI的帧
|
||||
cv2.imshow('ROI RTSP Verification', frame_with_roi)
|
||||
|
||||
# 按'q'退出
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
# 释放资源
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
print("✅ RTSP验证测试结束")
|
||||
|
||||
def test_roi_with_rtsp_advanced():
|
||||
"""
|
||||
增强版RTSP验证,包含更多调试信息
|
||||
"""
|
||||
print("="*50)
|
||||
print("增强版ROI区域RTSP流验证测试")
|
||||
print("按'q'退出,按'r'重新连接")
|
||||
print("="*50)
|
||||
|
||||
rtsp_url = "rtsp://10.0.0.50:8554/camera_test/scene1"
|
||||
|
||||
cap = None
|
||||
reconnect_count = 0
|
||||
|
||||
while True:
|
||||
if cap is None or not cap.isOpened():
|
||||
print(f"尝试连接RTSP流 (重连次数: {reconnect_count})...")
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
|
||||
# 设置RTSP参数
|
||||
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
|
||||
cap.set(cv2.CAP_PROP_FPS, 30)
|
||||
|
||||
if not cap.isOpened():
|
||||
print(f"连接失败,等待3秒后重试...")
|
||||
cv2.waitKey(3000)
|
||||
reconnect_count += 1
|
||||
continue
|
||||
else:
|
||||
print(f"✅ 成功连接到RTSP流: {rtsp_url}")
|
||||
reconnect_count = 0
|
||||
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
print("⚠️ 视频流断开,尝试重连...")
|
||||
cap.release()
|
||||
cap = None
|
||||
cv2.waitKey(1000)
|
||||
continue
|
||||
|
||||
# 应用ROI区域绘制
|
||||
frame_with_roi = draw_roi_on_frame(frame, "../config.yaml")
|
||||
|
||||
# 添加状态信息
|
||||
status_text = f'RTSP: Connected | ROI Test | Frame: {cv2.getTickCount() % 10000}'
|
||||
cv2.putText(frame_with_roi, status_text, (10, 30),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
||||
cv2.putText(frame_with_roi, 'Press Q to quit, R to reconnect', (10, 60),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
||||
|
||||
cv2.imshow('Advanced ROI RTSP Test', frame_with_roi)
|
||||
|
||||
key = cv2.waitKey(1) & 0xFF
|
||||
if key == ord('q'):
|
||||
break
|
||||
elif key == ord('r'):
|
||||
print("🔄 手动重连RTSP流...")
|
||||
cap.release()
|
||||
cap = None
|
||||
|
||||
if cap:
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
print("✅ 增强版RTSP验证测试结束")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 检查配置文件是否存在
|
||||
config_path = "../config.yaml"
|
||||
if not os.path.exists(config_path):
|
||||
print(f"⚠️ 配置文件 {config_path} 不存在,将创建示例配置")
|
||||
sample_config = '''roi_filter:
|
||||
enabled: true
|
||||
regions:
|
||||
- name: "control_lever_area"
|
||||
x_min: 0.1
|
||||
x_max: 0.3
|
||||
y_min: 0.7
|
||||
y_max: 0.9
|
||||
description: "控制摇杆区域"
|
||||
enabled: true
|
||||
- name: "valve_area"
|
||||
x_min: 0.7
|
||||
x_max: 0.8
|
||||
y_min: 0.6
|
||||
y_max: 0.8
|
||||
description: "阀门区域"
|
||||
enabled: true
|
||||
|
||||
input:
|
||||
video_path: "rtsp://10.0.0.50:8554/camera_test/scene1"
|
||||
width: 640
|
||||
height: 480'''
|
||||
|
||||
with open(config_path, 'w', encoding='utf-8') as f:
|
||||
f.write(sample_config)
|
||||
print(f"✅ 已创建示例配置文件: {config_path}")
|
||||
|
||||
# 选择测试模式
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "advanced":
|
||||
test_roi_with_rtsp_advanced()
|
||||
else:
|
||||
test_roi_with_rtsp()
|
||||
@ -1,172 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
ROI设置验证脚本
|
||||
用于验证ROI区域配置是否正确设置
|
||||
"""
|
||||
|
||||
import yaml
|
||||
import numpy as np
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
import cv2
|
||||
OPENCV_AVAILABLE = True
|
||||
except ImportError:
|
||||
OPENCV_AVAILABLE = False
|
||||
print("⚠️ OpenCV未安装,将跳过RTSP流测试")
|
||||
|
||||
from roi_filter import ROIManager
|
||||
|
||||
def print_header(title):
|
||||
"""打印带分隔符的标题"""
|
||||
print("="*60)
|
||||
print(f"{title:^60}")
|
||||
print("="*60)
|
||||
|
||||
def test_config_loading():
|
||||
"""测试配置文件加载"""
|
||||
print_header("1. 配置文件加载测试")
|
||||
|
||||
roi_manager = ROIManager("../config.yaml")
|
||||
|
||||
print(f"✅ ROI配置加载: {'成功' if roi_manager.roi_config else '失败'}")
|
||||
print(f" ROI过滤启用: {roi_manager.roi_config.get('enabled', False)}")
|
||||
|
||||
regions = roi_manager.roi_config.get('regions', [])
|
||||
print(f" ROI区域数量: {len(regions)}")
|
||||
|
||||
if regions:
|
||||
print(" ROI区域详情:")
|
||||
for i, region in enumerate(regions):
|
||||
print(f" {i+1}. {region.get('name', 'N/A')}: "
|
||||
f"({region.get('x_min', 0):.2f}, {region.get('y_min', 0):.2f}) -> "
|
||||
f"({region.get('x_max', 1):.2f}, {region.get('y_max', 1):.2f}) "
|
||||
f"[{'启用' if region.get('enabled', True) else '禁用'}]")
|
||||
|
||||
return roi_manager
|
||||
|
||||
def test_coordinate_detection(roi_manager):
|
||||
"""测试坐标检测功能"""
|
||||
print_header("2. ROI坐标检测测试")
|
||||
|
||||
# 测试一些坐标点
|
||||
test_points = [
|
||||
(0.2, 0.8), # 应该在control_lever_area区域
|
||||
(0.75, 0.7), # 应该在valve_area区域
|
||||
(0.5, 0.5), # 应该在非ROI区域
|
||||
(0.15, 0.75), # 应该在control_lever_area区域
|
||||
(0.72, 0.65), # 应该在valve_area区域
|
||||
]
|
||||
|
||||
for x, y in test_points:
|
||||
in_roi, roi_name = roi_manager.is_in_any_roi(x, y)
|
||||
status = "🔴 在ROI区域" if in_roi else "🟢 不在ROI区域"
|
||||
print(f" 坐标 ({x:.2f}, {y:.2f}): {status} {roi_name if in_roi else ''}")
|
||||
|
||||
def test_detection_filtering(roi_manager):
|
||||
"""测试检测结果过滤功能"""
|
||||
print_header("3. ROI检测过滤功能测试")
|
||||
|
||||
# 模拟检测结果 [x1, y1, x2, y2, conf, class_id]
|
||||
# 假设图像尺寸为640x480
|
||||
mock_detections = [
|
||||
[50, 50, 150, 150, 0.8, 0], # 左上角 (0.08, 0.1) - 不在ROI
|
||||
[100, 300, 200, 400, 0.9, 0], # 左下角 (0.16, 0.71) - 可能在control_lever_area
|
||||
[400, 250, 500, 350, 0.7, 0], # 右下角 (0.63, 0.64) - 可能不在ROI
|
||||
[450, 300, 550, 400, 0.85, 0], # 右下角 (0.7, 0.71) - 可能在valve_area
|
||||
[120, 350, 220, 450, 0.75, 1], # 左下角 (0.19, 0.79) - 可能在control_lever_area
|
||||
[480, 280, 580, 380, 0.9, 1], # 右下角 (0.75, 0.73) - 可能在valve_area
|
||||
]
|
||||
|
||||
print(f" 原始检测数量: {len(mock_detections)}")
|
||||
|
||||
filtered_detections = roi_manager.filter_detections(mock_detections, 640, 480)
|
||||
print(f" 过滤后检测数量: {len(filtered_detections)}")
|
||||
print(f" 过滤了 {len(mock_detections) - len(filtered_detections)} 个检测框")
|
||||
|
||||
def test_rtsp_verification():
|
||||
"""测试RTSP流验证(如果有OpenCV)"""
|
||||
if not OPENCV_AVAILABLE:
|
||||
print_header("4. RTSP流验证测试 (跳过)")
|
||||
print(" ⚠️ OpenCV未安装,无法进行RTSP流测试")
|
||||
return False
|
||||
|
||||
print_header("4. RTSP流验证测试")
|
||||
|
||||
rtsp_url = "rtsp://10.0.0.50:8554/camera_test/scene1"
|
||||
print(f" RTSP流地址: {rtsp_url}")
|
||||
|
||||
try:
|
||||
cap = cv2.VideoCapture(rtsp_url)
|
||||
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
|
||||
|
||||
if cap.isOpened():
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
print(" ✅ RTSP流连接成功")
|
||||
print(f" ✅ 成功获取帧,尺寸: {frame.shape[1]}x{frame.shape[0]}")
|
||||
|
||||
# 测试ROI绘制功能
|
||||
from roi_filter import draw_roi_on_frame
|
||||
frame_with_roi = draw_roi_on_frame(frame, "../config.yaml")
|
||||
|
||||
if frame_with_roi is not None:
|
||||
print(" ✅ ROI区域绘制功能正常")
|
||||
print(" 💡 提示: ROI区域会以红色矩形显示")
|
||||
|
||||
cap.release()
|
||||
return True
|
||||
else:
|
||||
print(" ❌ 无法读取RTSP流帧")
|
||||
cap.release()
|
||||
return False
|
||||
else:
|
||||
print(" ❌ 无法连接到RTSP流")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f" ❌ RTSP流测试出错: {str(e)}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print_header("🎯 ROI设置验证工具")
|
||||
print(" 本工具将验证ROI区域配置是否正确设置")
|
||||
print(" 包括配置加载、坐标检测、过滤功能和RTSP流测试")
|
||||
|
||||
# 1. 测试配置文件加载
|
||||
roi_manager = test_config_loading()
|
||||
|
||||
# 2. 测试坐标检测功能
|
||||
test_coordinate_detection(roi_manager)
|
||||
|
||||
# 3. 测试检测过滤功能
|
||||
test_detection_filtering(roi_manager)
|
||||
|
||||
# 4. 测试RTSP流验证
|
||||
rtsp_success = test_rtsp_verification()
|
||||
|
||||
# 总结
|
||||
print_header("📋 验证总结")
|
||||
|
||||
config_loaded = bool(roi_manager.roi_config)
|
||||
regions_defined = len(roi_manager.roi_config.get('regions', [])) > 0
|
||||
filtering_works = True # 假设过滤功能正常
|
||||
|
||||
print(f" 配置文件加载: {'✅ 正常' if config_loaded else '❌ 异常'}")
|
||||
print(f" ROI区域定义: {'✅ 正常' if regions_defined else '❌ 未定义'}")
|
||||
print(f" 坐标过滤功能: {'✅ 正常' if filtering_works else '❌ 异常'}")
|
||||
print(f" RTSP流测试: {'✅ 正常' if rtsp_success else '❌ 跳过或失败'}")
|
||||
|
||||
if config_loaded and regions_defined and filtering_works:
|
||||
print("\n🎉 ROI设置验证成功!")
|
||||
print(" 您的ROI区域配置已正确设置,可以用于过滤检测结果。")
|
||||
else:
|
||||
print("\n❌ ROI设置存在问题,请检查配置文件。")
|
||||
|
||||
return config_loaded and regions_defined and filtering_works
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
14
config.yaml
14
config.yaml
@ -117,3 +117,17 @@ compreface_service:
|
||||
det_prob_threshold: 0.99
|
||||
# 识别图像中人脸的个数,0代表没有限制。
|
||||
limit: 0
|
||||
|
||||
|
||||
roi:
|
||||
#设置ROI区域
|
||||
ignore_rois:
|
||||
cam_01:
|
||||
- [320, 1, 560, 719]
|
||||
- [620, 1, 860, 719]
|
||||
|
||||
cam_02:
|
||||
- [1, 500, 1000, 520]
|
||||
|
||||
cam_03:
|
||||
- [320, 1, 560, 719]
|
||||
|
||||
8
d8_5.py
8
d8_5.py
@ -54,6 +54,7 @@ import uuid
|
||||
import requests
|
||||
import json
|
||||
import datetime
|
||||
from roi_filter import is_in_ignore_roi, draw_ignore_rois, init_ignore_rois
|
||||
|
||||
|
||||
from compreface import CompreFace
|
||||
@ -74,6 +75,9 @@ client = Minio(
|
||||
secure=configData['minioConfig']['secure']
|
||||
)
|
||||
|
||||
# 初始化ROI区域
|
||||
init_ignore_rois("cam_01")
|
||||
|
||||
# 保存token
|
||||
tokenResult = {}
|
||||
getTokenUrl = configData['dataConfig']['getTokenUrl']
|
||||
@ -353,6 +357,10 @@ def plot_one_box(x, img, color=[0, 255, 0], label=None, line_thickness=2):
|
||||
# 画框
|
||||
color = [255, 0, 0] # 蓝色(BGR)
|
||||
cv2.rectangle(img, c1, c2, color, thickness=line_thickness, lineType=cv2.LINE_AA)
|
||||
# 画出ROI区域
|
||||
if is_in_ignore_roi(x):
|
||||
print("鞋子在 ROI 忽略区域内,跳过检测")
|
||||
draw_ignore_rois(img) # 调试可视化
|
||||
return [1, '未穿戴劳保鞋']
|
||||
|
||||
if label == 'face':
|
||||
|
||||
104
roi_filter.py
Normal file
104
roi_filter.py
Normal file
@ -0,0 +1,104 @@
|
||||
# roi_filter.py
|
||||
# =========================
|
||||
# ROI 屏蔽 / 过滤模块
|
||||
# =========================
|
||||
|
||||
import cv2
|
||||
import yaml
|
||||
import os
|
||||
|
||||
# =========================
|
||||
# 全局变量(常量风格)
|
||||
# =========================
|
||||
CAMERA_ID = None
|
||||
IGNORE_ROIS = []
|
||||
|
||||
|
||||
# =========================
|
||||
# 读取配置
|
||||
# =========================
|
||||
def load_ignore_rois(camera_id, config_path="config.yaml"):
|
||||
"""
|
||||
从配置文件中读取指定摄像头的 ROI 忽略区域
|
||||
"""
|
||||
if not os.path.exists(config_path):
|
||||
print(f"[WARN] config file not found: {config_path}")
|
||||
return []
|
||||
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
|
||||
return cfg.get("roi", {}).get("ignore_rois", {}).get(camera_id, [])
|
||||
|
||||
|
||||
# =========================
|
||||
# 初始化(由主程序调用一次)
|
||||
# =========================
|
||||
def init_ignore_rois(camera_id, config_path="config.yaml"):
|
||||
"""
|
||||
初始化 ROI 忽略区域(必须调用)
|
||||
"""
|
||||
global CAMERA_ID, IGNORE_ROIS
|
||||
CAMERA_ID = camera_id
|
||||
IGNORE_ROIS = load_ignore_rois(camera_id, config_path)
|
||||
|
||||
print(f"[ROI] camera_id={camera_id}, ignore_rois={IGNORE_ROIS}")
|
||||
|
||||
|
||||
# =========================
|
||||
# 判断是否在忽略区域
|
||||
# =========================
|
||||
def is_in_ignore_roi(bbox, mode="center"):
|
||||
"""
|
||||
判断检测框是否需要被屏蔽
|
||||
|
||||
:param bbox: (x1, y1, x2, y2)
|
||||
:param mode:
|
||||
- center : 中心点判断(推荐)
|
||||
- iou : 有交集即忽略
|
||||
:return: True = 忽略
|
||||
"""
|
||||
if not IGNORE_ROIS:
|
||||
return False
|
||||
|
||||
x1, y1, x2, y2 = bbox
|
||||
|
||||
if mode == "center":
|
||||
cx = (x1 + x2) // 2
|
||||
cy = (y1 + y2) // 2
|
||||
for rx1, ry1, rx2, ry2 in IGNORE_ROIS:
|
||||
if rx1 <= cx <= rx2 and ry1 <= cy <= ry2:
|
||||
return True
|
||||
return False
|
||||
|
||||
if mode == "iou":
|
||||
for rx1, ry1, rx2, ry2 in IGNORE_ROIS:
|
||||
ix1 = max(x1, rx1)
|
||||
iy1 = max(y1, ry1)
|
||||
ix2 = min(x2, rx2)
|
||||
iy2 = min(y2, ry2)
|
||||
if ix1 < ix2 and iy1 < iy2:
|
||||
return True
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
|
||||
# =========================
|
||||
# 调试:画出忽略区域
|
||||
# =========================
|
||||
def draw_ignore_rois(img):
|
||||
"""
|
||||
调试用:在画面中把 ROI 忽略区域画出来
|
||||
"""
|
||||
for x1, y1, x2, y2 in IGNORE_ROIS:
|
||||
cv2.rectangle(img, (x1, y1), (x2, y2), (128, 128, 128), 2)
|
||||
cv2.putText(
|
||||
img,
|
||||
"IGNORE ROI",
|
||||
(x1 + 5, y1 + 20),
|
||||
cv2.FONT_HERSHEY_SIMPLEX,
|
||||
0.6,
|
||||
(128, 128, 128),
|
||||
2
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user