python - 不能用 HSV 使黄色消失(OpenCV,Python)

标签 python opencv image-processing hsv

我有下图:

src

我想做的是保留所有红色数字。

使用这段代码..

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()

...我能得到的最大值是这样的:

output

如何去除黄色并保留 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)

enter image description here

关于python - 不能用 HSV 使黄色消失(OpenCV,Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50221851/

相关文章:

python - 如何用白色填充闭合轮廓区域

c++ - 在 ARM 上快速搜索/替换 8 位数组中匹配的单个字节

python - 使用 BeautifulSoup 与 XPath 进行 Python Web 抓取的优缺点

python - 使用 PyQt5 的语法高亮编辑器

python - Codecademy 循环 8/19

c++ - 用C++将OpenCV帧写入磁盘:单线程写入速度是否受磁盘吞吐量的限制?

python-3.x - 没有名为 cy_yolo_findboxes 的模块

python - 从 python 字符串中删除最后的 0

opencv - 重组代码后链接到OpenCV时出错

python - numpy 矢量化/更高效的 for 循环