如何用Python+OpenCV检测视频中除特定颜色外的多种颜色?
在OpenCV中检测除特定颜色外的多种颜色
嘿,我来帮你搞定这个OpenCV颜色检测的需求~ 你现在要做的是在视频里检测除了某一种特定颜色外的多种颜色,其实核心就是利用掩码的合并与取反来实现,结合你已经写的轨迹条代码,我们可以轻松扩展出解决方案。
方法一:检测多种指定颜色(排除某一种)
如果你的需求是明确要检测几种特定颜色,同时排除掉另一种,那我们可以给每种要检测的颜色都加一组HSV轨迹条,分别生成它们的掩码,再合并起来,最后去掉要排除的颜色区域。
比如你想检测红色和蓝色,排除绿色,我给你修改了代码,直接就能用:
import numpy as np import cv2 def nothing(x): pass cap = cv2.VideoCapture(0) cv2.namedWindow('image') # 第一组轨迹条:红色的HSV范围(红色分两段,这里先设第一段) cv2.createTrackbar('lh1','image',0,180,nothing) cv2.createTrackbar('ls1','image',120,255,nothing) cv2.createTrackbar('lv1','image',70,255,nothing) cv2.createTrackbar('hh1','image',10,180,nothing) cv2.createTrackbar('hs1','image',255,255,nothing) cv2.createTrackbar('hv1','image',255,255,nothing) # 第二组轨迹条:蓝色的HSV范围 cv2.createTrackbar('lh2','image',90,180,nothing) cv2.createTrackbar('ls2','image',50,255,nothing) cv2.createTrackbar('lv2','image',50,255,nothing) cv2.createTrackbar('hh2','image',130,180,nothing) cv2.createTrackbar('hs2','image',255,255,nothing) cv2.createTrackbar('hv2','image',255,255,nothing) # 第三组轨迹条:要排除的绿色的HSV范围 cv2.createTrackbar('ex_lh','image',40,180,nothing) cv2.createTrackbar('ex_ls','image',50,255,nothing) cv2.createTrackbar('ex_lv','image',50,255,nothing) cv2.createTrackbar('ex_hh','image',70,180,nothing) cv2.createTrackbar('ex_hs','image',255,255,nothing) cv2.createTrackbar('ex_hv','image',255,255,nothing) while True: ret, frame = cap.read() if not ret: break hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 获取红色的完整掩码(处理HSV中红色跨范围的情况) lh1 = cv2.getTrackbarPos('lh1','image') ls1 = cv2.getTrackbarPos('ls1','image') lv1 = cv2.getTrackbarPos('lv1','image') hh1 = cv2.getTrackbarPos('hh1','image') hs1 = cv2.getTrackbarPos('hs1','image') hv1 = cv2.getTrackbarPos('hv1','image') lower_red = np.array([lh1, ls1, lv1]) upper_red = np.array([hh1, hs1, hv1]) mask_red1 = cv2.inRange(hsv, lower_red, upper_red) lower_red2 = np.array([170, 120, 70]) upper_red2 = np.array([180, 255, 255]) mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2) mask_red = cv2.bitwise_or(mask_red1, mask_red2) # 获取蓝色的掩码 lh2 = cv2.getTrackbarPos('lh2','image') ls2 = cv2.getTrackbarPos('ls2','image') lv2 = cv2.getTrackbarPos('lv2','image') hh2 = cv2.getTrackbarPos('hh2','image') hs2 = cv2.getTrackbarPos('hs2','image') hv2 = cv2.getTrackbarPos('hv2','image') lower_blue = np.array([lh2, ls2, lv2]) upper_blue = np.array([hh2, hs2, hv2]) mask_blue = cv2.inRange(hsv, lower_blue, upper_blue) # 获取要排除的绿色掩码,然后取反得到非绿色区域 ex_lh = cv2.getTrackbarPos('ex_lh','image') ex_ls = cv2.getTrackbarPos('ex_ls','image') ex_lv = cv2.getTrackbarPos('ex_lv','image') ex_hh = cv2.getTrackbarPos('ex_hh','image') ex_hs = cv2.getTrackbarPos('ex_hs','image') ex_hv = cv2.getTrackbarPos('ex_hv','image') lower_green = np.array([ex_lh, ex_ls, ex_lv]) upper_green = np.array([ex_hh, ex_hs, ex_hv]) mask_green = cv2.inRange(hsv, lower_green, upper_green) mask_no_green = cv2.bitwise_not(mask_green) # 合并红、蓝掩码,再去掉绿色区域 combined_mask = cv2.bitwise_or(mask_red, mask_blue) final_mask = cv2.bitwise_and(combined_mask, mask_no_green) # 得到最终检测结果 result = cv2.bitwise_and(frame, frame, mask=final_mask) cv2.imshow('Original', frame) cv2.imshow('Detection Result', result) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
方法二:排除单一颜色,检测其余所有内容
如果你的需求更简单——只要排除某一种颜色,剩下的都检测,那不用搞多组轨迹条,直接生成要排除的颜色掩码,取反后和原图做与运算就行,代码更简洁:
import numpy as np import cv2 def nothing(x): pass cap = cv2.VideoCapture(0) cv2.namedWindow('image') # 为要排除的颜色设置轨迹条(这里默认是绿色) cv2.createTrackbar('ex_lh','image',40,180,nothing) cv2.createTrackbar('ex_ls','image',50,255,nothing) cv2.createTrackbar('ex_lv','image',50,255,nothing) cv2.createTrackbar('ex_hh','image',70,180,nothing) cv2.createTrackbar('ex_hs','image',255,255,nothing) cv2.createTrackbar('ex_hv','image',255,255,nothing) while True: ret, frame = cap.read() if not ret: break hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 获取要排除的颜色的HSV范围和掩码 ex_lh = cv2.getTrackbarPos('ex_lh','image') ex_ls = cv2.getTrackbarPos('ex_ls','image') ex_lv = cv2.getTrackbarPos('ex_lv','image') ex_hh = cv2.getTrackbarPos('ex_hh','image') ex_hs = cv2.getTrackbarPos('ex_hs','image') ex_hv = cv2.getTrackbarPos('ex_hv','image') ex_lower = np.array([ex_lh, ex_ls, ex_lv]) ex_upper = np.array([ex_hh, ex_hs, ex_hv]) ex_mask = cv2.inRange(hsv, ex_lower, ex_upper) # 取反掩码,得到排除后的区域 final_mask = cv2.bitwise_not(ex_mask) result = cv2.bitwise_and(frame, frame, mask=final_mask) cv2.imshow('Original', frame) cv2.imshow('Result (Excluded Color)', result) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
几个实用小技巧
- 红色特殊处理:HSV里红色是分两段的(0-10和170-180),所以要生成两个掩码再合并,我在第一个例子里已经加了这段逻辑
- 轨迹条初始值:可以根据目标颜色预设初始值,比如蓝色的初始LH设90,HH设130,这样不用从零开始调,节省时间
- HSV优势:相比RGB,HSV把颜色和亮度分开,调整的时候不会因为光线变化影响颜色检测的准确性
内容的提问来源于stack exchange,提问作者shadow
相关产品推荐
相关产品推荐

