如何用OpenCV/Python检测相机中间100像素是否全在指定颜色范围
问题修正方案
原代码存在的问题
- 颜色空间不匹配:截取的
tag是BGR格式,但用HSV阈值范围判断,应该先把tag转换成HSV格式 - 索引越界:
tag是10×10的子区域,循环用原图像坐标(235-245)访问tag会超出其索引范围(tag索引仅0-9) - 逻辑错误:需求是全部像素在颜色范围内才终止程序,但原代码是只要有一个像素符合就break,逻辑完全相反
- 代码结构错误:
cap.release()和窗口销毁代码放在while循环内部,会导致第一次循环就释放相机,后续无法读取帧 - 效率低下:嵌套循环逐个判断像素,不如OpenCV批量处理API高效
修正后的代码
import cv2 import numpy as np cap = cv2.VideoCapture(0) # 设置相机分辨率为480×640(部分相机可能不支持,需根据实际调整) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 定义目标HSV颜色范围(可根据实际需求调整) lower_red = np.array([20, 20, 50]) upper_red = np.array([255, 255, 130]) while True: ret, frame = cap.read() if not ret: break # 读取帧失败时直接退出 # 截取画面中间10×10的区域(共100个像素) tag = frame[235:245, 315:325] # 将子区域转换为HSV格式 tag_hsv = cv2.cvtColor(tag, cv2.COLOR_BGR2HSV) # 生成掩码:符合颜色范围的像素为255,否则为0 mask = cv2.inRange(tag_hsv, lower_red, upper_red) # 检查所有像素是否都符合颜色范围 if np.all(mask == 255): print("所有像素都在指定颜色范围内,程序终止") break cv2.imshow('image', frame) # 按下q键手动退出程序 if cv2.waitKey(1) == ord('q'): break # 释放相机资源并销毁窗口 cap.release() cv2.destroyAllWindows()
关键说明
- 用
cv2.inRange对整个子区域批量处理生成掩码,替代低效的嵌套循环 - 通过
np.all(mask == 255)直接判断所有像素是否符合条件,逻辑清晰且高效 - 仅转换需要判断的子区域为HSV格式,减少不必要的计算量
- 修正资源释放代码的位置,保证程序完整运行流程
内容的提问来源于stack exchange,提问作者Μανωλόπουλος Κωνσταντίνος
相关产品推荐
相关产品推荐

