OpenCV HSV 值根据 screen/camera 上的位置而变化
OpenCV HSV value changes depending on location on the screen/camera
我对所有编程都很陌生,一直在努力掌握 Python (2.7.6)、OpenCV 和 ROS,以便能够在机器人中使用神经网络。
我现在陷入了获取正确 HSV 值的 OpenCV (2.4.8) 问题,简而言之,它突然从红色(Hue 约为 5)或蓝色(Hue 约为 110)变为绿色(大约 40/50)而我只是移动 camera/presenting 屏幕另一侧的图像。
class CV:
def __init__(self):
# Initialize object
self.cap = cv2.VideoCapture(0) # '0' should stay or won't work for me
self.cap.set(cv2.cv.CV_CAP_PROP_FPS, 0.1)
def recognize(self):
while True:
ret, frame = self.cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Thresholding and contour finding
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.GaussianBlur(gray, (15, 15), 0)
thresh = cv2.adaptiveThreshold(gray_blur, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 1)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# Largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt = contours[max_index]
# Find center
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = int(x), int(y)
center_int = list(center)
# Color recognition
print hsv[center_int[0], center_int[1]]
# Show capture
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
self.cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
object = CV()
object.recognize()
所以我在屏幕的左边或右边显示了一个红色或蓝色的圆圈。我正在尝试从视频输入中获取颜色识别的 HSV 值。该图像显示在面向我的网络摄像头的另一个屏幕上。
在我的代码中你可以看到(或者至少我希望你应该看到)我找到了最大的轮廓,然后是最小的外接圆,然后我从中心 (x,y) 坐标得到了 HSV 值。如果我在左边显示我的圆圈,我可以很好地找到红色,蓝色也是如此,但是对于两种颜色,如果我在屏幕右侧显示我的圆圈,HSV 值完全不在绿色范围内,如上所述。
如果我将圆圈保持在一个位置并从右向左缓慢移动我的相机(因此我从凸轮获得的框架中的圆圈从左向右移动)HSV 值突然从 blue/red 从一个像素到下一个像素到绿色色调(饱和度和值也有很大不同,但对这些值不太感兴趣)。
我认为这与我实际上从屏幕上的哪个位置获取颜色有关,但我就是找不到正确的调试技巧来自己得到答案。我希望你们中的一个能帮助我!
编辑
我在形状的中心坐标处打印了一个圆圈,以跟踪最小外接圆的中心坐标在哪里,并且看起来就位。但是,我将背景更改为蓝色(从白色),现在我发现当形状位于屏幕右侧时,HSV 值为蓝色,因此 HSV 值似乎不是来自中心坐标,但我有不知道为什么..
经过两天与这个问题的斗争,我终于找到了错误的地方:
这样返回的坐标:
(x, y), radius = cv2.minEnclosingCircle(cnt)
不是x和y坐标,而是行和列索引。
因此,当我将相机或圆圈从左向右移动时,中心点的 HSV 值编码为:
print hsv[center_int[0], center_int[1]]
在框架上下移动,返回圆圈上方和下方的颜色。
我这样重命名坐标:
(r, c), radius = cv2.minEnclosingCircle(cnt)
center = int(r), int(c)
center_int = list(center)
感兴趣的区域现在是:
print hsv[center_int[1], center_int[0]]
一切顺利。
我对所有编程都很陌生,一直在努力掌握 Python (2.7.6)、OpenCV 和 ROS,以便能够在机器人中使用神经网络。
我现在陷入了获取正确 HSV 值的 OpenCV (2.4.8) 问题,简而言之,它突然从红色(Hue 约为 5)或蓝色(Hue 约为 110)变为绿色(大约 40/50)而我只是移动 camera/presenting 屏幕另一侧的图像。
class CV:
def __init__(self):
# Initialize object
self.cap = cv2.VideoCapture(0) # '0' should stay or won't work for me
self.cap.set(cv2.cv.CV_CAP_PROP_FPS, 0.1)
def recognize(self):
while True:
ret, frame = self.cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Thresholding and contour finding
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.GaussianBlur(gray, (15, 15), 0)
thresh = cv2.adaptiveThreshold(gray_blur, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 1)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# Largest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt = contours[max_index]
# Find center
(x, y), radius = cv2.minEnclosingCircle(cnt)
center = int(x), int(y)
center_int = list(center)
# Color recognition
print hsv[center_int[0], center_int[1]]
# Show capture
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
self.cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
object = CV()
object.recognize()
所以我在屏幕的左边或右边显示了一个红色或蓝色的圆圈。我正在尝试从视频输入中获取颜色识别的 HSV 值。该图像显示在面向我的网络摄像头的另一个屏幕上。
在我的代码中你可以看到(或者至少我希望你应该看到)我找到了最大的轮廓,然后是最小的外接圆,然后我从中心 (x,y) 坐标得到了 HSV 值。如果我在左边显示我的圆圈,我可以很好地找到红色,蓝色也是如此,但是对于两种颜色,如果我在屏幕右侧显示我的圆圈,HSV 值完全不在绿色范围内,如上所述。
如果我将圆圈保持在一个位置并从右向左缓慢移动我的相机(因此我从凸轮获得的框架中的圆圈从左向右移动)HSV 值突然从 blue/red 从一个像素到下一个像素到绿色色调(饱和度和值也有很大不同,但对这些值不太感兴趣)。
我认为这与我实际上从屏幕上的哪个位置获取颜色有关,但我就是找不到正确的调试技巧来自己得到答案。我希望你们中的一个能帮助我!
编辑 我在形状的中心坐标处打印了一个圆圈,以跟踪最小外接圆的中心坐标在哪里,并且看起来就位。但是,我将背景更改为蓝色(从白色),现在我发现当形状位于屏幕右侧时,HSV 值为蓝色,因此 HSV 值似乎不是来自中心坐标,但我有不知道为什么..
经过两天与这个问题的斗争,我终于找到了错误的地方:
这样返回的坐标:
(x, y), radius = cv2.minEnclosingCircle(cnt)
不是x和y坐标,而是行和列索引。 因此,当我将相机或圆圈从左向右移动时,中心点的 HSV 值编码为:
print hsv[center_int[0], center_int[1]]
在框架上下移动,返回圆圈上方和下方的颜色。
我这样重命名坐标:
(r, c), radius = cv2.minEnclosingCircle(cnt)
center = int(r), int(c)
center_int = list(center)
感兴趣的区域现在是:
print hsv[center_int[1], center_int[0]]
一切顺利。