openmv识别矩形,可能会乱识别,导致激光乱飞,这里有两个思路
主体思路如下
在目标再识别与跟踪过程中,系统通过以下两个核心机制实现稳定追踪:
云台动态校准机制
-
实时采集视频流中的目标矩形框坐标数据
-
通过PID控制算法动态调整云台俯仰/偏转角度
-
以画面中心点为基准建立坐标系(1920x1080分辨率下(960,540)为原点)
-
计算目标矩形中心点(x,y)与画面中心的欧式距离偏差
-
当偏差超过±15像素阈值时触发云台伺服电机补偿
-
在多目标场景下,优先选择几何中心最近的目标矩形
框角位置约束机制
-
建立目标框角坐标历史缓存队列(最近5帧数据)
-
对当前帧检测到的四个框角坐标(x1,y1)...(x4,y4)进行验证:
a) 与上一帧对应框角坐标进行差分比较
b) 设置±10像素的动态容差范围(可配置参数)
c) 采用滑动窗口均值滤波消除瞬时抖动
-
当3个及以上框角满足位置约束时,判定为有效跟踪
-
对于超出阈值的异常框角,采用卡尔曼滤波进行位置预测补偿
-
连续3帧校验失败时触发目标重识别流程
该系统在实测中达到:
-
云台响应延迟 < 80ms
-
框角位置稳定性 > 92%(在30fps视频流中)
-
可耐受目标瞬时遮挡(最长12帧)
1,再识别过程中实时调整云台位置,确保矩形一直在中点位置,然后寻找距离中点位置最近的矩形。
2,识别过程中,保存四个框角的位置,确保每次矩形更新时,四个框角都在上次保存框角的正负10像素以内(已验证)
这里主要说下2
1. 首次识别时锁定目标矩形的精确角点坐标
2. 后续帧只接受角点变化在±10像素范围内的矩形
3. 连续丢失目标时自动进入保护模式
伪代码如下:
python
while(1):
if(flag_first==0):
if(识别到矩形):
for(寻找距离中点最近的矩形):
将矩形四个点坐标加入到数组中
flag_first == 1
if(flag_first==1):
if(识别到矩形):
if(矩形四个点坐标在上次数组的+-10像素以内)
更新矩形四个点坐标到数组
返回矩形中点
部分代码如下图所示
python
while (True):
clock.tick()
img = sensor.snapshot()
detected_rects = img.find_rects(threshold=10000)
if tracking_flag == 0:
min_distance = float('inf')
target_rect = None
for r in detected_rects:
corners = r.corners()
center_x = sum(p[0] for p in corners) / 4
center_y = sum(p[1] for p in corners) / 4
distance = ((center_x - search_center[0]) ** 2 +
(center_y - search_center[1]) ** 2) ** 0.5
if distance < min_distance:
min_distance = distance
target_rect = r
if target_rect:
corners = target_rect.corners()
for i in range(4):
rect[i * 2] = corners[i][0]
rect[i * 2 + 1] = corners[i][1]
tracking_flag = 1
print("进入追踪模式,初始矩形:", rect)
elif tracking_flag == 1:
matched_rect = None
for r in detected_rects:
current_corners = r.corners()
all_match = True
for i in range(4):
if (abs(current_corners[i][0] - rect[i * 2]) > 10 or
abs(current_corners[i][1] - rect[i * 2 + 1]) > 10):
all_match = False
break
if all_match:
matched_rect = r
break
if matched_rect:
corners = matched_rect.corners()
for i in range(4):
rect[i * 2] = corners[i][0]
rect[i * 2 + 1] = corners[i][1]
else:
pass
if tracking_flag == 1:
points = [(rect[0], rect[1]), (rect[2], rect[3]),
(rect[4], rect[5]), (rect[6], rect[7])]
print("追踪中的矩形:", points)
for i in range(4):
start = points[i]
end = points[(i + 1) % 4]
img.draw_line(start[0], start[1], end[0], end[1], color=(255, 255, 255))
center_x = sum(p[0] for p in points) / 4
center_y = sum(p[1] for p in points) / 4
img.draw_cross(int(center_x), int(center_y), color=(0, 255, 0), size=5)
img.draw_string(int(center_x + 10), int(center_y),
"TRACKING" if tracking_flag else "SEARCHING",
color=(255, 0, 0))
if center_y > red_ponit_y:
motor1(0, int((center_y - red_ponit_y) / 10)) # 向下
elif center_y < red_ponit_y:
motor1(1, int((red_ponit_y - center_y) / 10)) # 向上
if center_x > red_ponit_x:
motor2(1, int((center_x - red_ponit_x) / 10)) # 向左
elif center_x < red_ponit_x:
motor2(0, int((red_ponit_x - center_x) / 10)) # 向右
这里不贴全代码了,但验证过是可以的,所以各位加油吧