为什么 MATLAB 的 rgb2hsv 返回错误的色调值?

sci*_*ci9 1 python matlab colors image-processing

考虑下图:

图片

下面的 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)
Run Code Online (Sandbox Code Playgroud)

MATLAB 输出

它返回错误的 Hue 值,但 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)
Run Code Online (Sandbox Code Playgroud)

蟒蛇输出

通过在任何图像编辑软件中使用颜色选择器工具,我们可以看到正确的色相值大约是 100 中的 50 或 1 中的 0.5。

截屏

我们如何从 MATLAB 中获得正确的色调值rgb2hsv

Han*_*rse 5

这里有几个问题,导致错误的结论。

在显示的(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
Run Code Online (Sandbox Code Playgroud)

那将是更正后的 Python 输出:

更正的Python输出

我们看到,它与 MATLAB 输出相当。

希望有帮助!


编辑:或者,使用skimage.io.imread代替cv2.imread. 然后,不需要任何转换,因为skimage.io.imread默认情况下使用 RGB 颜色排序。