OpenCV红色检测二次触发舵机功能代码运行异常求助
问题根因
- 缺少状态记录变量:没有全局标记记录是否已经完成第一次红色识别,
red1函数匹配到红色后会直接调用donme()退出程序,根本不会执行第二次检测逻辑 - 无持续检测逻辑:现有代码仅处理单次轮廓数据,没有嵌入摄像头帧循环中,无法识别不同时间出现的两次红色
- 逻辑顺序错误:顺序调用
red1、red2的方式无法对应时序上的两次识别要求,同一帧的红色会同时被两个函数匹配,若你外层本身套了帧循环,就会出现没检测到红色也触发舵机的异常
修正后代码
你可以用全局状态标记的方案实现需求,参考代码如下:
import cv2 import time # 全局状态标记:是否已经检测到第一次红色 first_red_caught = False # 最小识别轮廓面积,避免小噪点误触发 min_contour_area = 500 # 第一次识别后的冷却时间,避免同一个红色物体被重复计数为第二次 cooldown_time = 5 last_first_detect_time = 0 def ilkkirmizi(): print("首次识别到红色,不触发舵机") def donme(): print("第二次识别到红色,触发舵机运行") p.start(2.5) # 舵机初始化 p.ChangeDutyCycle(5) time.sleep(4) exit() # 以下逻辑需要嵌入你原有的摄像头取帧、红色阈值筛选、轮廓提取的循环中 # 你的原有逻辑应该是循环读取摄像头帧 → 提取红色区域 → 得到contours,把下面的逻辑替换你原来的red1()、red2()调用即可 while True: # 你原有代码的摄像头取帧、红色掩码提取、轮廓查找逻辑写在这里 # ret, goruntu = cap.read() # 红色阈值筛选得到mask # contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) red_detected = False for c in contours: if cv2.contourArea(c) < min_contour_area: continue # 匹配到符合要求的红色 red_detected = True (x,y,w,h) = cv2.boundingRect(c) cv2.rectangle(goruntu,(x,y),(x+w,y+h),(255,0,0),3) break if red_detected: if not first_red_caught: # 第一次检测到红色 first_red_caught = True last_first_detect_time = time.time() ilkkirmizi() else: # 冷却时间过了之后的第二次检测 if time.time() - last_first_detect_time > cooldown_time: donme() # 你原有代码的窗口展示逻辑 # cv2.imshow("frame", goruntu) # if cv2.waitKey(1) & 0xFF == ord('q'): # break
注意事项
- 上述代码中的循环部分需要嵌入你原有项目的摄像头取帧逻辑中,替换原来的
red1()、red2()调用即可 - 可以根据实际使用场景调整
min_contour_area和cooldown_time的数值,适配不同的识别距离和触发间隔要求
内容的提问来源于stack exchange,提问作者MUSTAFA KENDİGÜZEL
相关产品推荐
相关产品推荐

