如何将RGB直方图转换为色谱?

Ric*_*k T 3 matlab image-processing histogram octave matlab-figure

如何转换图像的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');
Run Code Online (Sandbox Code Playgroud)

示例图像以及代码生成的单独RGB直方图:

当前直方图

我试图让直方图看起来像下面的图像,但颜色从红色变为蓝色:

在此输入图像描述

另一个图片示例:

我想要的直方图

PS:我使用的Octave 4.0与MATLAB非常相似.

gno*_*ice 7

在标准颜色表示(如RGB或HSV)和光谱波长之间进行转换存在巨大障碍:许多颜色不能用单一波长的光表示.品红色,粉红色,棕色或任何灰度色等颜色代表不同波长的混合物.因此,生成等效光谱波长是一项更加复杂的工作(您可以在此处此处找到一些有用的想法和链接).

创建颜色的直方图本身可能是更好的方法(在我的其他答案之一中说明),但如果您真的想以简单的方式将颜色与波长联系起来,您可以尝试以下方法......

第一步是将RGB值转换为HSV值,然后创建色调通道的直方图.我会从这里调整我的部分答案来做到这一点.下一步是将色调映射到光的波长,使用从这个答案改编的一些相当粗略的近似值:

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

注意:为使上述功能在Octave中正常工作,可能需要将该set(hBar, ...行更改为以下内容:

set(hBar, 'FaceColor', 'flat', 'EdgeColor', 'none');
set(get(hBar, 'Children'), 'CData', 270:-1:1, 'CDataMapping', 'direct');
Run Code Online (Sandbox Code Playgroud)

这是直方图:

在此输入图像描述

但是,这有一个问题.如果我们在我的其他答案中使用完全相同的代码来绘制所有色调值的直方图,我们会得到:

在此输入图像描述

请注意,当我们丢弃部分色调范围以转换为波长(它们不对应于光谱中的单个波长)时,会有一大群洋红色,粉红色和红色像素被排除在外.将这些结合到结果中将需要从色调到波长的更复杂的转换.