Python OpenCV 颜色追踪

15

以下是我用Python编写的追踪白色物体的代码。它可以工作,但只能持续几秒钟,然后整个屏幕变黑,在一些情况下它也不能正常工作。我尝试了蓝色,它可以工作,但白色和绿色会给我带来问题:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):

_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# define range of white color in HSV
# change it according to your need !
sensitivity = 15
lower_white = np.array([0,0,255-sensitivity])
upper_white = np.array([255,sensitivity,255])

# Threshold the HSV image to get only white colors
mask = cv2.inRange(hsv, lower_white, upper_white)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)

cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)

k = cv2.waitKey(5) & 0xFF
if k == 27:
break

cv2.destroyAllWindows()
2个回答

24
首先,你应该知道你正在使用的颜色空间。 这是一个关于OpenCV中Mat类型为CV_8UC3的颜色空间的小教程。(图片来自维基百科)

HSV

enter image description here

在HSV(色相、饱和度、明度)颜色空间中,H代表主导颜色,S代表颜色的饱和度,V代表亮度。在OpenCV中,范围有所不同。S和V的取值范围是[0,255],而H的取值范围是[0,180]。通常情况下,H的取值范围是[0,360](完整的圆),但为了适应一个字节(256个不同的值),它的值被减半。
在HSV空间中,分离单一颜色更容易,因为你可以简单地设置H的适当范围,并确保S不太小(否则会接近白色),V不太小(否则会很暗)。
举个例子,如果你需要几乎是蓝色的颜色,你需要将H的值设定在大约120左右(例如在[110,130]范围内),并且S和V不要太小(例如在[100,255]范围内)。
白色不是一种色调(彩虹中没有白色),而是一种颜色的组合。
在HSV中,你需要涵盖所有H的范围(H在[0,180]范围内),非常小的S值(例如S在[0,25]范围内),以及非常高的V值(例如V在[230,255]范围内)。这基本上对应于圆锥体中央轴的上部分。
为了在HSV空间中追踪白色物体,你需要:
lower_white = np.array([0, 0, 230])
upper_white = np.array([180, 25, 255])

或者,如果您定义了一个敏感度值,就像这样:
sensitivity = 15
lower_white = np.array([0, 0, 255-sensitivity])
upper_white = np.array([180, sensitivity, 255])

对于其他颜色:
green = 60;
blue = 120;
yellow = 30;
...
sensitivity = 15

// Change color with your actual color
lower_color = np.array([color - sensitivity, 100, 100]) 
upper_color = np.array([color + sensitivity, 255, 255])

红色 H 值为0,因此您需要取两个范围并将它们“或”在一起:

sensitivity = 15
lower_red_0 = np.array([0, 100, 100]) 
upper_red_0 = np.array([sensitivity, 255, 255])
lower_red_1 = np.array([180 - sensitivity, 100, 100]) 
upper_red_1 = np.array([180, 255, 255])

mask_0 = cv2.inRange(hsv, lower_red_0 , upper_red_0);
mask_1 = cv2.inRange(hsv, lower_red_1 , upper_red_1 );

mask = cv2.bitwise_or(mask_0, mask_1)

现在你应该能够追踪任何颜色!

3

不必猜测和尝试HSV的下限/上限颜色范围,您可以使用HSV颜色阈值脚本通过滑块确定范围。这使得很容易定义您要分割的任何颜色的范围。只需更改cv2.imread中的输入图像。示例用于分割白色。

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('1.jpg')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(True):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接