如何转换图像的 RGB 直方图以创建显示组合颜色以及正确颜色波长范围的直方图?
示例代码:
pkg load image
f=imread('/tmp/marbles.jpg');
f=uint8(f); %need to convert back to uint8 to show picture
%Split into RGB Channels
f_red = f(:,:,1);
f_green = f(:,:,2);
f_blue = f(:,:,3);
%Get histValues for each channel
[y_f_red, x] = imhist(f_red);
[y_f_green, x] = imhist(f_green);
[y_f_blue, x] = imhist(f_blue);
subplot (2,1,1); imshow(f);
subplot (2,1,2); plot(x, y_f_red, 'r', x, y_f_green, 'g', x, y_f_blue, 'b');
示例图像以及代码生成的单独 RGB 直方图:
我试图让直方图看起来像下图,但颜色从红色变为蓝色:
另一个图像示例:
PS:我使用的是与 MATLAB 非常相似的 Octave 4.0。
最佳答案
在标准颜色表示(如 RGB 或 HSV)和光谱波长之间进行转换存在巨大障碍:许多颜色不能由单一波长的光表示。洋红色、粉色、棕色或任何灰度颜色等颜色代表不同波长的混合。因此,生成等效光谱波长是一项复杂得多的工作(您可能会找到一些有用的想法和链接 here 和 here)。
创建颜色本身的直方图可能是更好的方法(如 my other answers 之一所示),但如果您真的想以一种简单的方式将颜色与波长相关联,您可以尝试以下方法...
第一步是将 RGB 值转换为 HSV 值,然后创建色调 channel 的直方图。我将改编部分 my answer from here要做到这一点。下一步将是将色调映射到光的波长,使用改编自 this answer 的一些相当粗略的近似值。 :
rgbImage = imread('test_image.png'); % Load image
hsvImage = rgb2hsv(rgbImage); % Convert the image to HSV space
hPlane = 360.*hsvImage(:, :, 1); % Get the hue plane scaled from 0 to 360
binEdges = 0:270; % Edges of histogram bins
N = histc(hPlane(:), binEdges); % Bin the pixel hues from above
wavelength = 620-(170/270).*(0:269); % Approximate wavelength
hBar = bar(wavelength, N(1:end-1), 'histc'); % Plot the histogram
set(hBar, 'CData', 270:-1:1, ... % Change the color of the bars using
'CDataMapping', 'direct', ... % indexed color mapping (360 colors)
'EdgeColor', 'none'); % and remove edge coloring
colormap(hsv(360)); % Change to an HSV color map with 360 points
axis([450 620 0 max(N)]); % Change the axes limits
set(gca, 'Color', 'k'); % Change the axes background color
set(gcf, 'Pos', [50 400 560 200]); % Change the figure size
xlabel('Wavelength (nm)'); % Add an x label
ylabel('Bin counts'); % Add a y label
注意:要使上述内容在 Octave 中正常工作,可能需要将 set(hBar, ...
行更改为以下内容:
set(hBar, 'FaceColor', 'flat', 'EdgeColor', 'none');
set(get(hBar, 'Children'), 'CData', 270:-1:1, 'CDataMapping', 'direct');
这是直方图:
但是,这有一个问题。如果我们改为使用与 my other answer 中完全相同的代码绘制所有色调值的直方图,我们会得到这个:
请注意,当我们抛出部分色调范围以转换为波长(它们不对应于光谱中的单一波长)时,有一大群洋红色、粉红色和微红色像素被排除在外。将这些纳入结果需要更复杂的从色调到波长的转换。
关于matlab - 如何将 RGB 直方图转换为色谱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43503190/