Я бы предложил использовать HSV цветового пространства для сравнения цветов, потому что он менее чувствителен к переменному освещению, чем RGB , где зеленый в солнечном свете может быть rgb (20,255,10), нозеленый цвет в тени может быть rgb (3,45,2), в то время как оба будут иметь очень похожий оттенок в цветовом пространстве HSV.
Итак, чтобы начать ...
Создайте небольшой массив 10x1 и сделайте первый пиксель красным, второй оранжевый, затем желтый, зеленый, синий, индиго, фиолетовый, затем черный, средне-серый и белый.Здесь есть таблица .
Затем преобразуйте в HSV цветовое пространство и запишите значения Hue .
Я начал некоторыекод ...
#!/usr/local/bin/python3
import numpy as np
import imageio
import cv2
# Create black image 10x1
im = np.zeros([1,10,3], dtype=np.uint8)
# Fill with colours of rainbow and greys
im[0,0,:]=[255,0,0] # red
im[0,1,:]=[255,165,0] # orange
im[0,2,:]=[255,255,0] # yellow
im[0,3,:]=[0,255,0] # green
im[0,4,:]=[0,0,255] # blue
im[0,5,:]=[75,0,130] # indigo
im[0,6,:]=[238,130,238] # violet
im[0,7,:]=[0,0,0] # black
im[0,8,:]=[127,127,127] # grey
im[0,9,:]=[255,255,255] # white
imageio.imwrite("result.png",im)
hsv=cv2.cvtColor(im,cv2.COLOR_RGB2HSV)
print(hsv)
Проверьте изображение:

Проверьте цвета и с помощью Imagemagick:
convert result.png txt:
# ImageMagick pixel enumeration: 10,1,65535,srgb
0,0: (65535,0,0) #FF0000 red
1,0: (65535,42405,0) #FFA500 orange
2,0: (65535,65535,0) #FFFF00 yellow
3,0: (0,65535,0) #00FF00 lime
4,0: (0,0,65535) #0000FF blue
5,0: (19275,0,33410) #4B0082 indigo
6,0: (61166,33410,61166) #EE82EE violet
7,0: (0,0,0) #000000 black
8,0: (32639,32639,32639) #7F7F7F grey50
9,0: (65535,65535,65535) #FFFFFF white
Теперь посмотрите на массив HSV ниже, а именно на первый столбец ( Hue ).Вы можете видеть, что красный имеет оттенок = 0, оранжевый - 19, желтый - 30 и так далее.Также обратите внимание, что черный, серый и белый имеют нулевую насыщенность, а черные имеют низкое значение , серые имеют среднее значение , а белые имеют высокое значение .
[[[ 0 255 255]
[ 19 255 255]
[ 30 255 255]
[ 60 255 255]
[120 255 255]
[137 255 130]
[150 116 238]
[ 0 0 0]
[ 0 0 127]
[ 0 0 255]]]
Теперь вы можете создать в Python структуру данных, которая будет хранить для каждого цвета:
- Самый низкий включенный оттенок
- Самый высокий включенный оттенок
- Имя
Итак, вы можете использовать:
... see note at bottom for Red
14,23,"Orange"
25,35,"Yellow"
55,65,"Green"
115,125,"Blue"
...
и т. Д. - не указывайте черный, серый и белый в таблице.
Итак, как вы используете это?
Что ж, когда вы получите цвет для проверки, сначала преобразуйте значения R, G и B в HSV и посмотрите на результирующее Насыщенность - что является меройяркости цвета.Яркие цвета будут иметь высокую насыщенность, тогда как более тусклые, сероватые цвета будут иметь низкую насыщенность.
Итак, посмотрите, не превышает ли Насыщенность , скажем, 10% от максимально возможного, например, более 25по шкале 0-255.
Если Насыщенность ниже предела, отметьте Значение и присвойте Черный, если Значение низкий,Серый, если средний, и Белый, если Значение высокое.
Если Насыщенность выше предела, проверьте, находится ли он в нижнем и верхнем пределах одного из вашихЗаписано Оттенки и назовите его соответствующим образом.
Итак, код выглядит примерно так:
def ColorNameFromRGB(R,G,B)
# Calculate HSV from R,G,B - something like this
# Make a single pixel from the parameters
onepx=np.reshape(np.array([R,G,B],dtype=np.uint8),(1,1,3))
# Convert it to HSV
onepxHSV=cv2.cvtColor(onepx,cv2.COLOR_RGB2HSV)
...
...
if S<25:
if V<85:
return "black"
elsif V<170:
return "grey"
return "white"
# This is a saturated colour
Iterate through colour names table and return name of entry with matching Hue
Есть две вещи, о которых нужно знать:
В значениях оттенка для красного есть разрыв, потому что цветовое колесо HSV представляет собой круговое колесо, а значение оттенка для красного находится под углом 0, поэтому значения выше 350 и ниже 10все красные.Так получилось, что OpenCV масштабирует диапазон 0-360 путем деления на 2, что означает, что он получается как 0-180 ..., который аккуратно помещается в один беззнаковый байт.Итак, для Red вам нужно проверить Hue больше 175 и меньше 5, скажем.
Будьте внимательны, чтобы всегда генерировать 8-битное изображение при поиске цветов, поскольку значения оттенков по-разному масштабируются на 16-битных и плавающих изображениях.