Создать маску, где зеленый канал ярче синего и красного? - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь извлечь отображение зеленого светодиодного дисплея из фотографии, и я обнаружил, что самый простой способ предварительно обработать фотографию - это замаскировать (затемнить) все пиксели, где зеленый канал не самый яркий канал,Я создал алгоритм для этого, но он очень медленный:

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 секунд для запуска фотографии, котораяэто слишком большой.Есть ли встроенный алгоритм, который выполняет ту же функцию, или оптимизацию, которую я могу использовать?

1 Ответ

0 голосов
/ 15 октября 2018

Это решение работает:

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