我试着从我的网络摄像头上检测到球的颜色。我尝试的颜色是红、绿、蓝和黄。我编写了下面的代码。但它显示,即使没有球,蓝球也是随机检测出来的。同时,当显示绿色或红色时,检测到的蓝色球会在中间弹出。请提出一些方法,使它更准确,以及如何包括黄色。
enter code here
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
lower_green = np.array([45,140,50])
upper_green = np.array([75,255,255])
lower_red = np.array([160,140,50])
upper_red = np.array([180,255,255])
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
foundred = False
while(True):
success,frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
hsv = cv2.medianBlur(hsv,5)
imgThreshHighred = cv2.inRange(hsv, lower_red, upper_red)
imgThreshHighgreen = cv2.inRange(hsv, lower_green, upper_green)
imgThreshHighblue = cv2.inRange(hsv, lower_blue, upper_blue)
circlesred = cv2.HoughCircles(imgThreshHighred,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
circlesblue = cv2.HoughCircles(imgThreshHighblue,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
circlesgreen = cv2.HoughCircles(imgThreshHighgreen,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
if circlesred is not None:
print "found red"
# print circlesred
if circlesgreen is not None:
print "found green"
# print circlesgreen
if circlesblue is not None:
print "found blue"
# print circlesblue
else:
print "no ball"
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()发布于 2018-01-16 05:51:45
你正在观察假阳性,正如火焰精英指出的那样,它们是由你图像中属于你目标的HSV范围的其他区域引起的。这与你目前的做法是正常的。基于颜色区域检测的检测几乎肯定会在自然图像中产生假阳性。要减少或消除假阳性,您有两种策略。
1.使用更具体的颜色模型。您可以使用更窄的HSV范围(如火炬精英建议的那样),也可以使用OpenCV的高斯混合建模方法和EM类来训练每个球的高斯模型。这可以用于分段,并将替换调用inRange的3行代码。在这两种方法中,您必须小心您的训练图像与您的测试图像相匹配(特别是灯光与自动白平衡的颜色变化相似,如果是主动的,则表示在培训图像中)。
2.使用其他特性/信息。如果仍然存在假阳性,则需要使用颜色以外的属性来消除它们。例如,在视频中,球的半径是否近似恒定?如果是这样,您可以拒绝明显太小或太大的区域。这是非常有效的。背景不动吗?如果是这样的话,你可以尝试使用OpenCV的背景减法来消除假阳性。你一次只看到一个球吗?如果是这样的话,你可以拒绝所有可能的‘球’区域,例如,使用高斯颜色模型在每个区域的对数似然的平均值。
发布于 2018-01-16 04:57:31
我想在你的图像帧的某个点上,一定有一些在蓝色范围内有色调值的小分量,这就是为什么你得到蓝色作为假阳性。以下是我的建议:
最大的三类像素将给你真正的颜色球。
我希望这能帮上忙。
https://stackoverflow.com/questions/48268272
复制相似问题