我有下图:
我想做的是保留所有红色数字。
使用这段代码..
import cv2
import numpy as np
def callback(x):
pass
cap = cv2.VideoCapture(0)
cv2.namedWindow('image')
ilowH = 0
ihighH = 179
ilowS = 0
ihighS = 255
ilowV = 0
ihighV = 255
# create trackbars for color change
cv2.createTrackbar('lowH', 'image', ilowH, 179, callback)
cv2.createTrackbar('highH', 'image', ihighH, 179, callback)
cv2.createTrackbar('lowS', 'image', ilowS, 255, callback)
cv2.createTrackbar('highS', 'image', ihighS, 255, callback)
cv2.createTrackbar('lowV', 'image', ilowV, 255, callback)
cv2.createTrackbar('highV', 'image', ihighV, 255, callback)
while True:
# grab the frame
frame = cv2.imread('color_test.png')
# get trackbar positions
ilowH = cv2.getTrackbarPos('lowH', 'image')
ihighH = cv2.getTrackbarPos('highH', 'image')
ilowS = cv2.getTrackbarPos('lowS', 'image')
ihighS = cv2.getTrackbarPos('highS', 'image')
ilowV = cv2.getTrackbarPos('lowV', 'image')
ihighV = cv2.getTrackbarPos('highV', 'image')
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_hsv = np.array([ilowH, ilowS, ilowV])
higher_hsv = np.array([ihighH, ihighS, ihighV])
mask = cv2.inRange(hsv, lower_hsv, higher_hsv)
frame = cv2.bitwise_and(frame, frame, mask=mask)
# show thresholded image
cv2.imshow('image', frame)
k = cv2.waitKey(1) & 0xFF # large wait time to remove freezing
if k == 113 or k == 27:
break
cv2.destroyAllWindows()
cap.release()
...我能得到的最大值是这样的:
如何去除黄色并保留 3 个红色图形?在这种情况下,HSL 是一个很好的替代方案吗? 请记住,中间的红色与其他两个不同;一个是全红色 (255, 0, 0) 另一个是较少 (237, 28, 36) RGB。
最佳答案
我前一段时间做了类似的事情,最终在 HSV 空间中定义了我自己的基本颜色,包括单色定义(我承认这有点武断)。
无论如何,正如评论中所述,在 HSV 中,红色色调是分开的,所以我做了一个简单的函数来组合我定义的任何颜色,以便轻松地为它们创建蒙版:
import cv2
import numpy as np
HSV_RANGES = {
# red is a major color
'red': [
{
'lower': np.array([0, 39, 64]),
'upper': np.array([20, 255, 255])
},
{
'lower': np.array([161, 39, 64]),
'upper': np.array([180, 255, 255])
}
],
# yellow is a minor color
'yellow': [
{
'lower': np.array([21, 39, 64]),
'upper': np.array([40, 255, 255])
}
],
# green is a major color
'green': [
{
'lower': np.array([41, 39, 64]),
'upper': np.array([80, 255, 255])
}
],
# cyan is a minor color
'cyan': [
{
'lower': np.array([81, 39, 64]),
'upper': np.array([100, 255, 255])
}
],
# blue is a major color
'blue': [
{
'lower': np.array([101, 39, 64]),
'upper': np.array([140, 255, 255])
}
],
# violet is a minor color
'violet': [
{
'lower': np.array([141, 39, 64]),
'upper': np.array([160, 255, 255])
}
],
# next are the monochrome ranges
# black is all H & S values, but only the lower 25% of V
'black': [
{
'lower': np.array([0, 0, 0]),
'upper': np.array([180, 255, 63])
}
],
# gray is all H values, lower 15% of S, & between 26-89% of V
'gray': [
{
'lower': np.array([0, 0, 64]),
'upper': np.array([180, 38, 228])
}
],
# white is all H values, lower 15% of S, & upper 10% of V
'white': [
{
'lower': np.array([0, 0, 229]),
'upper': np.array([180, 38, 255])
}
]
}
def create_mask(hsv_img, colors):
"""
Creates a binary mask from HSV image using given colors.
"""
# noinspection PyUnresolvedReferences
mask = np.zeros((hsv_img.shape[0], hsv_img.shape[1]), dtype=np.uint8)
for color in colors:
for color_range in HSV_RANGES[color]:
# noinspection PyUnresolvedReferences
mask += cv2.inRange(
hsv_img,
color_range['lower'],
color_range['upper']
)
return mask
将它应用于您的示例(我将其命名为“color_shapes.png”),我得到了很好的结果:
img = cv2.imread('color_shapes.png')
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
red_mask = create_mask(img_hsv, ['red'])
mask_img = cv2.bitwise_and(img_hsv, img_hsv, mask=red_mask)
关于python - 不能用 HSV 使黄色消失(OpenCV,Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50221851/