Clear Filters
Clear Filters

How to apply color to histograms?

28 views (last 30 days)
Roger Breton
Roger Breton on 27 Aug 2022
Commented: Roger Breton on 29 Aug 2022
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');

Answers (2)

Abderrahim. B
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")
  1 Comment
Roger Breton
Roger Breton on 28 Aug 2022
As long as I can make the colormap "equal" to Hue angle values and vary with Chroma? I'll try to search some more about how this could be done... Worth giving a try :-0)
Thank you so much!

Sign in to comment.


Walter Roberson
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
Roger Breton
Roger Breton on 29 Aug 2022
I'm struggling along... So far, I'm getting this graph :
I'm using b = bar3(hue,c);
The Hue angle is the "horizontal" axis (Y) and the "count" is on the "vertical axis" (X) but I need to get the "third dimension. "chroma" (Z). When I use b = bar3(hue,c,36), 36 being the bin count (I probably don't have that argument right?), I get this graph with what looks like an "extruded value" of "36 units" :
I suppose I need to better understand the bar3 function...
Roger Breton
Roger Breton on 29 Aug 2022
From my reading of the documentation, the bar3 function can only display the relationship between two variables. In my case, I could always "color" the bars with the "hue angles", from 0 to 350 degrees, at maximum saturation. It would be a start? But I'm trying to develop a vizualisation to help students understand the distribution of colors in any image. Adobe has a nice site dedicated to the "extraction" of colors out a given RGB image (Color theme from image | Adobe Color) with this interface :
It works great but it does not say anything about the "distribution" of colors in the image such as 1) what is the 'highest Chroma color? 2) Which Hues are used in the image? The "color palette" created are "nice" from an esthetic point of view but can't be related directly to any kind of "models"? Ideally, I'd like to have something like this :
I've done this, painstakingly, using Adobe InDesign. I selected a number of colors from the RGB image, convert those to Lab and then Munsell Notation, to ultimately plot them on a Munsell Hue wheel in an effort to try to understand the "underlying color model" or "color harmonies". That's why I need to identity colors by chroma and hue and then, rank them (in order of chroma), to identify the most saturated colors. In the case of this image, I confess the underlying harmony model is not obvious but in other images, it is :
For now, I'm sticking with the idea of some "bar chart" to illustrate the idea of "distribution of colors" within an image.

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!