Python OpenCV 颜色跟踪

Python OpenCV Color Tracking

下面是我的 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()

嗯,首先你应该知道你使用的是什么颜色 space。 OpenCV 中 Mat 类型 CV_8UC3 的颜色 spaces 的小教程。 (图片来自维基百科)

单纯疱疹病毒

在HSV(色相、饱和度、明度)颜色space中,H给出颜色主色,S给出颜色的饱和度,V给出亮度。在 OpenCV 中,范围不同。 S,V 在 [0,255] 中,而 H 在 [0, 180] 中。通常 H 在 [0,360](整圈)范围内,但为了适应一个字节(256 个不同的值),它的值减半。

在HSV中space更容易分离单一颜色,因为你可以简单地为H设置合适的范围,并注意S不要太小(它会接近白色),并且V不算小(会黑)

因此,例如,如果您需要几乎 blue 颜色,则需要 H 值在 120 左右(比如 [110,130]),并且 S、V 不能太小(比如 [100,255])。

白色不是一种色调(彩虹中没有白色),而是一种颜色的组合。

在 HSV 中,您需要获取所有范围的 H(H 在 [0, 180] 中)、非常小的 S 值(例如 [0, 25] 中的 S)和非常高的 V 值(例如 V 在[230、255])。这个基本对应圆锥体中轴的上部


因此,要使其跟踪 HSV space 中的白色对象,您需要:

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,所以需要取两个范围"OR"一起:

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(mask1, mask2)

现在您应该可以追踪任何颜色了!

不必猜测和检查 HSV lower/upper 颜色范围,您可以使用 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()