How to apply color to histograms?
21 views (last 30 days)
Show older comments
My goal is to analyze RGB images based on Chroma and Hue. For this purpose, I first convert from RGB to CIE Lab, and then from CIE Lab to CIE Lch. At this point, I plot the data using histogram2, which may not necessarily be best suited for the task. This is the result :
As you can see, it's a little unintuitive (to interpret). I added X, Y and Z labels but that's not enough. What I'd like to do is to change the default "blue" color to match the underlying color values. For this, I need to convert back from Lch to Lab and then from Lab to RGB, so that I have the color specification in a form Matlab can understand.
Problem is I don't know how to supply the color 'argument' to the histogram2 function? Does it work with a colormap?
I attached the code. The the sample image I use is in TIFF (I converted to PNG for this post).
Any help is appreciated.
--- < Here is my code (seems I cannot attach BOTH the code and the Image?)
% Read the image in from disk
img = imread('Cible Mesh RGB 12x13.png');
% Convert from uint8 RGB (0 to 255) to float RGB values (0 to 1.0)
img_double = im2double(img);
% Convert from RGB to CIE Lab, with D50 White point (instead of D65)
img2Lab = rgb2lab(img_double, 'WhitePoint','d50');
% --------------------------------------------------------------------------------------
% Transform image in N Rows x 3 Columns :
% First Column = CIE L*
% Second Column = CIE a*
% Third Column = CIE b*
LabIMG = round(reshape(permute(img2Lab,[3 1 2]),3,[])); % <<<<--------------------------
% --------------------------------------------------------------------------------------
% Swaps rows and columns to have a 156 x 3 matrix
LabIMGVerticale = transpose(LabIMG); % reshape(X,[],3)
% Compute Hue Angle for each row
Hrad = mod(atan2(LabIMGVerticale (:,3),LabIMGVerticale (:,2)),2*pi);
HueAngle = Hrad*180/pi;
% Compute Chroma for each row
Chroma = sqrt(LabIMGVerticale(:,2).^2 + LabIMGVerticale(:,3).^2);
% Create Lch matrix
Lch = [LabIMGVerticale(:,1) Chroma HueAngle];
% Sort matrix in descending chroma order
% Use 'negative' order
Lch_DescendingChroma = sortrows(Lch,-2);
% Create new array from 1st Column (L*)
L = Lch_DescendingChroma(:,1,:);
% Create new array from 2nd Column (chroma)
c = Lch_DescendingChroma(:,2,:);
% Create new array from 3rd Column (hue angle)
hue = Lch_DescendingChroma(:,3,:);
% Show data in 3D histogram
histogram2(c,hue,36);
title('Distribution of Colors (bin=36)');
xlabel('CIE Chroma');
ylabel('CIE Hue Angle');
zlabel('Count');
0 Comments
Answers (2)
Abderrahim. B
on 27 Aug 2022
Hi!
Not sure if this is what you want, but the concept is there. Work on the histogram handle and use colormap.
websave("cibleMesh_rgb.tif", "https://www.mathworks.com/matlabcentral/answers/uploaded_files/1109700/Cible%20Mesh%20RGB%2012x13.png") ;
% Read the image in from disk
img = imread('cibleMesh_rgb.tif');
% Convert from uint8 RGB (0 to 255) to float RGB values (0 to 1.0)
img_double = im2double(img);
% Convert from RGB to CIE Lab, with D50 White point (instead of D65)
img2Lab = rgb2lab(img_double, 'WhitePoint','d50');
% --------------------------------------------------------------------------------------
% Transform image in N Rows x 3 Columns :
% First Column = CIE L*
% Second Column = CIE a*
% Third Column = CIE b*
LabIMG = round(reshape(permute(img2Lab,[3 1 2]),3,[])); % <<<<--------------------------
% --------------------------------------------------------------------------------------
% Swaps rows and columns to have a 156 x 3 matrix
LabIMGVerticale = transpose(LabIMG); % reshape(X,[],3)
% Compute Hue Angle for each row
Hrad = mod(atan2(LabIMGVerticale (:,3),LabIMGVerticale (:,2)),2*pi);
HueAngle = Hrad*180/pi;
% Compute Chroma for each row
Chroma = sqrt(LabIMGVerticale(:,2).^2 + LabIMGVerticale(:,3).^2);
% Create Lch matrix
Lch = [LabIMGVerticale(:,1) Chroma HueAngle];
% Sort matrix in descending chroma order
% Use 'negative' order
Lch_DescendingChroma = sortrows(Lch,-2);
% Create new array from 1st Column (L*)
L = Lch_DescendingChroma(:,1,:);
% Create new array from 2nd Column (chroma)
c = Lch_DescendingChroma(:,2,:);
% Create new array from 3rd Column (hue angle)
hue = Lch_DescendingChroma(:,3,:);
% Show data in 3D histogram
hisH = histogram2(c,hue,36);
title('Distribution of Colors (bin=36)');
xlabel('CIE Chroma');
ylabel('CIE Hue Angle');
zlabel('Count');
hisH.FaceColor = 'flat' ;
colormap("hsv")
Walter Roberson
on 27 Aug 2022
Pass
'FaceColor', 'flat'
to histogram2() to cause the colors to be controlled by the colormap.
However, the color choice will be according to the height. There is no documented way to provide color that varies with position.
Effectively to get color that varies with position, you would have to do the counting yourself and use bar3(). bar3() returns surface() objects that have a CData property that can be arbitrary.
4 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!