2025电赛e题:openmv识别过程丢失矩形
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. 连续丢失目标时自动进入保护模式
伪代码如下:
while(1):if(flag_first==0):if(识别到矩形):for(寻找距离中点最近的矩形):将矩形四个点坐标加入到数组中flag_first == 1if(flag_first==1):if(识别到矩形):if(矩形四个点坐标在上次数组的+-10像素以内)更新矩形四个点坐标到数组返回矩形中点
部分代码如下图所示
while (True):clock.tick()img = sensor.snapshot()detected_rects = img.find_rects(threshold=10000)if tracking_flag == 0:min_distance = float('inf')target_rect = Nonefor r in detected_rects:corners = r.corners()center_x = sum(p[0] for p in corners) / 4center_y = sum(p[1] for p in corners) / 4distance = ((center_x - search_center[0]) ** 2 +(center_y - search_center[1]) ** 2) ** 0.5if distance < min_distance:min_distance = distancetarget_rect = rif 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 = 1print("进入追踪模式,初始矩形:", rect)elif tracking_flag == 1:matched_rect = Nonefor r in detected_rects:current_corners = r.corners()all_match = Truefor i in range(4):if (abs(current_corners[i][0] - rect[i * 2]) > 10 orabs(current_corners[i][1] - rect[i * 2 + 1]) > 10):all_match = Falsebreakif all_match:matched_rect = rbreakif 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:passif 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) / 4center_y = sum(p[1] for p in points) / 4img.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)) # 向右
这里不贴全代码了,但验证过是可以的,所以各位加油吧