From 7fbe4f59cd8814a45687c724360aa9ddeeb286f2 Mon Sep 17 00:00:00 2001 From: Cx330 <1487537121@qq.com> Date: Sat, 18 Apr 2026 15:16:32 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E8=AF=95=E5=8F=82=E6=95=B0=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/camera.py | 90 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/main/camera.py b/main/camera.py index 3338e24..433d09f 100644 --- a/main/camera.py +++ b/main/camera.py @@ -96,7 +96,7 @@ while True: for cnt in contours: area = cv2.contourArea(cnt) - if area < 500: # 过滤噪声,增大阈值 + if area < 75: # 过滤噪声,增大阈值 continue if area > 8000: # 过滤大面积假目标(如整个画面),减小阈值 @@ -117,12 +117,18 @@ while True: best_match = None min_distance = float('inf') + search_radius = 100 # 目标锁定区域半径 + for area, cnt, x, y, w, h in valid_contours: cx = x + w // 2 cy = y + h // 2 # 计算与上一目标的距离 distance = ((cx - prev_cx) ** 2 + (cy - prev_cy) ** 2) ** 0.5 - + + # 只考虑在锁定区域内的目标 + if distance > search_radius: + continue + # 如果距离小于阈值,认为是同一个目标 if distance < 50: # 距离阈值 if distance < min_distance: @@ -157,6 +163,18 @@ while True: cx = x + w // 2 cy = y + h // 2 + # 目标位置平滑处理 + alpha = 0.6 + if prev_cx is not None and prev_cy is not None: + cx = int(alpha * prev_cx + (1 - alpha) * cx) + cy = int(alpha * prev_cy + (1 - alpha) * cy) + + # 绘制画面中心 + center_x = 50 # 画面中心x坐标 + center_y = 120 # 画面中心y坐标 + cv2.circle(frame, (center_x, center_y), 5, (255, 0, 0), -1) + + # 绘制目标矩形和中心 cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1) @@ -178,29 +196,63 @@ while True: # 重置跟踪状态 tracking_target = None - # 控制逻辑:根据y轴坐标控制垃圾桶前后移动 + # 控制逻辑:根据x轴和y轴坐标控制垃圾桶移动 + center_x = 160 # 画面中心x坐标 center_y = 120 # 画面中心y坐标 - threshold = 20 # 阈值范围 - speed = 3000 # 电机速度 - + threshold = 15 # 阈值范围 + if target_jumped: # 目标跳变,停止移动 print("目标跳变,停止移动") motor.stop() - elif cy < center_y - threshold: - # 目标在上侧,垃圾桶向后移动 - print("目标在上侧,向后移动") - # 使用新的电机控制函数 - motor.backward(speed=0.6) - elif cy > center_y + threshold: - # 目标在下侧,垃圾桶向前移动 - print("目标在下侧,向前移动") - # 使用新的电机控制函数 - motor.forward(speed=0.6) else: - # 目标在中心附近,停止移动 - print("目标在中心,停止移动") - motor.stop() + # 计算目标与中心的偏差 + dx = cx - center_x + dy = cy - center_y + + # 确定移动方向 + if abs(dx) < threshold and abs(dy) < threshold: + # 目标在中心附近,停止移动 + print("目标在中心,停止移动") + motor.stop() + elif abs(dx) < threshold: + # 只在y轴方向有偏差 + if dy > threshold: + # 目标在下侧,垃圾桶向右移动 + print("目标在下侧,向右移动") + motor.move_right(speed=1.0) + else: + # 目标在上侧,垃圾桶向左移动 + print("目标在上侧,向左移动") + motor.move_left(speed=1.0) + elif abs(dy) < threshold: + # 只在x轴方向有偏差 + if dx > threshold: + # 目标在右侧,垃圾桶向后移动 + print("目标在右侧,向后移动") + motor.backward(speed=1.0) + else: + # 目标在左侧,垃圾桶向前移动 + print("目标在左侧,向前移动") + motor.forward(speed=1.0) + else: + # 在x轴和y轴方向都有偏差,使用斜向移动 + if dx > threshold and dy > threshold: + # 目标在右下侧,垃圾桶向右后移动 + print("目标在右下侧,向右后移动") + motor.move_right_backward(speed=1.0) + elif dx > threshold and dy < -threshold: + # 目标在右上侧,垃圾桶向左后移动 + print("目标在右上侧,向左后移动") + motor.move_left_backward(speed=1.0) + elif dx < -threshold and dy > threshold: + # 目标在左下侧,垃圾桶向右前移动 + print("目标在左下侧,向右前移动") + motor.move_right_forward(speed=1.0) + else: + # 目标在左上侧,垃圾桶向左前移动 + print("目标在左上侧,向左前移动") + motor.move_left_forward(speed=1.0) # 更新上一帧的目标信息 prev_cx = cx