sci9
sci9

Reputation: 776

Why does MATLAB's rgb2hsv return wrong Hue values?

Consider the following image:

image

The below MATLAB code returns a histogram of the Hue values:

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

It returns wrong Hue values, but the equivalent code in Python returns the correct values.

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

By using a color picker tool in any image editing software, we can see that the correct Hue value is about 50 out of 100 or 0.5 out of 1.

Screenshot

How we can get correct Hue values from MATLAB's rgb2hsv?

Upvotes: 1

Views: 562

Answers (1)

HansHirse
HansHirse

Reputation: 18925

There are several issues here, which lead to false conclusions.

In the shown (Photoshop?) screenshot, the Hue value is 51°, not 51%. Hue values range from 0° to 360°, cf. the Wikipedia article on the HSV colorspace. So, a Hue value of 51° equals 14.17%, which is in accordance to the shown MATLAB histogram.

So, it's not the MATLAB code, which is wrong, but the Python code!

OpenCV (cv2) per default uses BGR color ordering, so for img = cv2.imread(r"img.png"), we get img with BGR color ordering. Now, hsv_img = rgb2hsv(rgb_img) is used, where skimage.color.rgb2hsv awaits an image with RGB color ordering, which leads to the erroneous Python results.

Here's a possible fix (notice, your diagram shows 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

That'd be the corrected Python output:

CorrectedPython output

We see, it's quite comparable to the MATLAB output.

Hope that helps!


EDIT: Alternatively, use skimage.io.imread instead of cv2.imread. Then, there's no need for any conversion, since skimage.io.imread uses RGB color ordering per default.

Upvotes: 5

Related Questions