Почему rgb2hsv MATLAB возвращает неправильные значения Hue? - PullRequest
1 голос
/ 04 февраля 2020

Рассмотрим следующее изображение:

image

Приведенный ниже код MATLAB возвращает гистограмму значений оттенков:

img1 = imread('img.png');  
img1(img1<1) = 0;
%
img_hsv = rgb2hsv(img1);
hue_img = img_hsv(:,:,1);
array = hue_img(hue_img > 0.1);
histfit(array, 20)

MATLAB output

Возвращает неправильные значения оттенков, но эквивалентный код в Python возвращает правильные значения.

import cv2 
import matplotlib.pyplot as plt
import numpy as np
from skimage import data
from skimage.color import rgb2hsv

img = cv2.imread(r"img.png") 
rgb_img = img 
hsv_img = rgb2hsv(rgb_img) 
hue_img = hsv_img[:, :, 0] 
hue_img[np.where(hue_img > 0.1)] 
array = hue_img[np.where(hue_img > 0.1)] 
plt.hist(array,bins=100)

Python output

Используя инструмент выбора цвета в любом программном обеспечении для редактирования изображений, мы видим, что правильное значение оттенка составляет примерно 50 из 100 или 0,5 из 1.

Screenshot

Как мы можем получить правильные значения оттенков из MATLAB rgb2hsv?

1 Ответ

4 голосов
/ 04 февраля 2020

Здесь есть несколько проблем, которые приводят к ложным выводам.

На показанном снимке экрана (Photoshop?) Значение оттенка составляет 51 ° , а не 51% . Значения оттенков варьируются от 0 ° до 360 °, ср. статья в Википедии о цветовом пространстве HSV . Таким образом, значение оттенка 51 ° равно 14,17% , что соответствует показанной гистограмме MATLAB.

Таким образом, это не код MATLAB, который неверно, но код Python!

OpenCV (cv2) по умолчанию использует порядок цветов BGR, поэтому для img = cv2.imread(r"img.png") мы получаем img с порядком цветов BGR. Теперь используется hsv_img = rgb2hsv(rgb_img), где skimage.color.rgb2hsv ожидает изображение с упорядочением цветов RGB, что приводит к ошибочным Python результатам.

Вот возможное исправление (обратите внимание, ваша диаграмма показывает bins=20) :

img = cv2.imread(r"img.png")
rgb_img = img[:, :, [2, 1, 0]]                  # BGR to RGB
hsv_img = rgb2hsv(rgb_img)
hue_img = hsv_img[:, :, 0]
array = hue_img[np.where(hue_img > 0.1)]
plt.hist(array,bins=20)                         # 20 instead of 100

Это будет исправленный Python вывод:

CorrectedPython output

Видим, это вполне сопоставимо с Выход MATLAB.

Надеюсь, это поможет!


РЕДАКТИРОВАТЬ: В качестве альтернативы, используйте skimage.io.imread вместо cv2.imread. Тогда нет необходимости в каком-либо преобразовании, поскольку skimage.io.imread использует порядок цветов RGB по умолчанию.

...