OpenCV - обнаружение цветовых диапазонов и отображение на консоли - PullRequest
0 голосов
/ 29 августа 2018

Итак, у меня есть следующий код, и он отлично работает при отображении цветов на изображении. Я знаю, что он использует маску поверх исходного изображения и показывает только те цвета, которые определены в заявленных границах. Так что в основном он не «определяет» цвет, а охватывает все остальное, что не входит в диапазон.

использование: python code.py

Пример изображения, которое вы можете найти здесь

код:

import numpy as np
import cv2
import sys

image = cv2.imread(sys.argv[1])


colors = {
    "red_lower" : "[  0   0 255]",
    "red_upper" : "[  0   0 127]",
    "blue_lower" : "[255  38   0]",
    "blue_upper" : "[255  38   0]",
    "yellow_lower" : "[  0 216 255]",
    "yellow_upper" : "[  0 216 255]",
    "gray_lower" : "[160 160 160]",
    "gray_upper" : "[160 160 160]"
}

boundaries = [
    ([0, 0, 255], [127, 0, 255]), #red
    ([255, 38, 0], [255, 38, 0]), #blue
    ([0, 216, 255], [0, 216, 255]), #yellow
    ([160, 160, 160], [160, 160, 160]) #gray
]

# loop over the boundaries
for (lower, upper) in boundaries:

    # create NumPy arrays from the boundaries
    lower = np.array(lower, dtype = np.uint8)
    upper = np.array(upper, dtype = np.uint8)

    # find the colors within the specified boundaries and apply the mask
    mask = cv2.inRange(image, lower, upper)
    output = cv2.bitwise_and(image, image, mask = mask)

    # show the images
    cv2.imshow("Climbing Holds", np.hstack([image, output]))

    cv2.waitKey(0)

Я пытаюсь поймать цвет на консоли с помощью оператора If при сопоставлении одной из границ. Если я сравниваю напрямую со своим словарем цветов, он не будет работать так, как ожидалось, поскольку все границы проходят через цикл.

Пример оператора If:

if str(lower) == colors["red_lower"]:
    print "red"
elif str(upper) == colors["red_upper"]:
    print "dark red"
elif str(lower) == colors["blue_lower"]:
    print "blue"
elif str(lower) == colors["yellow_lower"]:
    print "yellow"
elif str(lower) == colors["gray_lower"]:
    print "gray

Я пытался отладить, печатая маску и вывод, но они возвращают только ноль кортежей:

 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]

Кто-нибудь знает, как вернуть соответствие маски? Возможно ли использовать cv2.imshow или cv2.read?

1 Ответ

0 голосов
/ 31 августа 2018

Вы можете объединить colors и boundaries в один объект для повторения. В любом случае, объединение данных является хорошей идеей, поскольку нижние / верхние границы дублируются в настоящее время, один раз в boundaries и один раз в виде строк в значениях colors. Такое дублирование не велико, поскольку оно может привести к незначительным ошибкам. Некоторые значения уже выглядят несинхронизированными, поэтому менее подвержено ошибкам хранить их в одном месте.

color_boundaries = {
    "red":    ([0,   0,   255], [127, 0,   255]),
    "blue":   ([255, 38,  0],   [255, 38,  0]),
    "yellow": ([0,   216, 255], [0,   216, 255]),
    "gray":   ([160, 160, 160], [160, 160, 160])
}

for color_name, (lower, upper) in color_boundaries.items():
    # create NumPy arrays from the boundaries
    lower = np.array(lower, dtype = np.uint8)
    upper = np.array(upper, dtype = np.uint8)

    # find the colors within the specified boundaries and apply the mask
    mask = cv2.inRange(image, lower, upper)
    output = cv2.bitwise_and(image, image, mask = mask)

    if mask.any():
        print(f"{color_name}: {mask.sum()}")
...