1

我试图从照片中提取绿色 LED 显示屏的显示,我发现预处理照片的最简单方法是屏蔽(变黑)绿色通道不是最亮通道的所有像素。我创建了一个算法来做到这一点,但它非常慢:

def mask_dominant(image, color):
    # For example, if color == "green", then we blacken out
    # all pixels where green isn't the brightest pixel
    image_copy = np.copy(image)
    black_pixel = np.array([0, 0, 0], dtype=np.uint8)
    height, width, _ = image_copy.shape
    for row in range(height):
        for col in range(width):
            # OpenCV stores colors in BGR
            b, g, r = image_copy[row, col]
            zero = False
            if color == 'blue':
                if b < g or b < r:
                    zero = True
            elif color == 'green':
                if g < b or g < r:
                    zero = True
            elif color == 'red':
                if r < b or r < g:
                    zero = True
            else:
                raise AssertionError("Color must be one of blue, green, or red")
            if zero:
                image_copy[row, col] = black_pixel
    return image_copy

如何运行它:

import cv2
import numpy as np
image = cv2.imread("image1.jpg")
dominant = mask_dominant(image, 'green')

上面的算法在一张照片上运行需要 40 秒,这实在是太大了。是否有内置算法可以做同样的事情或我可以使用的 numpy 优化?

4

1 回答 1

2

此解决方案有效:

def mask_dominant(image, color):
    # For example, if color == Green, then it blacks out
    # all pixels where green isn't the brightest pixel
    b,g,r = cv2.split(image)
    if color == 'green':
        target = g
        other1 = b
        other2 = r
    elif color == 'red':
        target = r
        other1 = g
        other2 = b
    elif color == 'blue':
        target = b
        other1 = g
        other2 = r
    else:
        raise AssertionError("invalid color: " + color)

    # Figure out which ones we need to zero & zero them
    should_zero = (target < other1) | (target < other2)
    g[should_zero] = 0
    r[should_zero] = 0
    b[should_zero] = 0

    # Merge channels back
    return cv2.merge((b,g,r))
于 2018-10-15T02:38:41.863 回答