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

标签 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');

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

Current Histogram

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

enter image description here

另一个图像示例:

Histogram I want

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

最佳答案

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

创建颜色本身的直方图可能是更好的方法(如 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');

这是直方图:

enter image description here

但是,这有一个问题。如果我们改为使用与 my other answer 中完全相同的代码绘制所有色调值的直方图,我们会得到这个:

enter image description here

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

关于matlab - 如何将 RGB 直方图转换为色谱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43503190/

相关文章:

php - 如何使base64图像保存更快?

python - 我可以欺骗 numpy.histogram 使其表现得像 numpy.bincount 吗?

c++ - 强度直方图++

matlab - 如何在幅频响应上使用逆 FFT?

matlab - 在 Matlab 中使用命令行验证集群配置文件

c++ - OpenCV 访问像素的颜色值

python - 是否可以在 Python 图像库 (PIL) 中屏蔽图像?

python - 如何使用Python绘制模拟几何随机变量的直方图?

matlab - 白色像素簇提取

Python 等效于 Matlab 文本扫描