Better "probabilities"?
Show older comments
I created a small script in which I present two random colors to the user. See attached script.

As you can see, on the left, are the two RGB colors calculated using "rand" function. On the left is the colors plotted on an CIE ab diagram. I intend to use this script with my students to discuss "Color Harmonies". This is a "diad". Next up, is a "trad".
First question
What I'd like to know is how "effective" is the rand function? Would there be more "advanced" ways of coming up with those two colors?
The motivation behind this script is to get the students thinking "outside of the box", to move them away from getting "inspiration" from all kinds of "real-world" objects and only look at the "sensation" produced b the colors.
Second question
I would like to explore generating random colors from my Munsell Book of Color 1600 measured CIE Lab colors. This is how I bring in my Munsell color data from an Excel file:
% Import TAB-delimited file
file_path = 'Munsell Glossy All Colors Extracted (2024 03 21) TAB.txt';
my_table = readtable(file_path, 'Delimiter', '\t', 'ReadVariableNames', false);
MunsellNotationTMP = my_table{:, 1}; % Text data
MunsellNotation = string(MunsellNotationTMP);
HVCcolumns_Lab = my_table{:, 2:4}; % Numeric data
HVC_Lab = [HVCcolumns_Lab(:, 1), HVCcolumns_Lab(:, 2), HVCcolumns_Lab(:, 3)];
Answers (1)
John D'Errico
on 13 May 2024
Edited: John D'Errico
on 13 May 2024
1 vote
How effective is rand? I'm not sure what you mean by "effective", or for that matter, "advanced". It is a state of the art random number generator. So no, you cannot do better in terms of randomness, and what you did with it seems reasonable. Perhaps only with the caveat that you could, randomly, have two colors that were very near each other, even indistinguishable to the eye. I don't know if that is an issue. If it was, then you could test to see if the distance (in terms of Euclidean distance when mapped to L*a*b* perhaps) between the two colors generated is too small, and if so, then generate a new set until you get colors that are significantly different.
Anyway, in terms of randomness, literally any random number generator would arguably be sufficient for a simple problem like this. You don't need sophistication.
Your second question is not a question at all, as it looks like you stopped writing before you asked anything. You read in a set of Munsell colors. Then what? Are you looking to choose randomly from that set? RANDI might be useful then, to choose a random index into that set.
8 Comments
Roger Breton
on 13 May 2024
Do you want to choose two (or N) different colors from your list? In that case you'd want to use randperm (which selects without replacement) instead of randi (which selects with replacement) to generate indices into your list of colors.
rng default
x = randperm(6, 4) % No duplicates selected
rng default
x = randi(6, [1 4]) % 6 selected twice
Roger Breton
on 13 May 2024
Roger Breton
on 13 May 2024
Walter Roberson
on 13 May 2024
Yes, that would work.
However, to avoid 5R 4/12 and 5B 3/2 coming up again, you should randperm() more entries -- and then "use them up" 2 at a time.
Unless, that is, you are fine with (say) 5R 4/12 coming up as long as it was not in combination with 5B 3/2 . To permit repetitions of individual colours but not pairs of colours, keep a history of what has been generated. (Sort the history so that the lower number of each pair is first -- saves trouble later checking whether any particular proposed new pair has already been generated or the reverse pair was already generated)
Thanks for posting your script. I like it because it teaches me about CIE LAB color representation, which I have heard of, but never investigated.
If you use randi() with the imported list of Munsell colors, you will, of course, sample that list uniformly.
Your script chooses random colors that are uniformly distributed in RGB space. But this does not mean you will sample a*,b* space uniformly. Let's see:
% Make color array that fills RGB cube uniformly with 1e4 points.
%[r,g,b]=meshgrid(0:.05:1,0:.05:1,0:.05:1);
%crgb=[reshape(r,[],1),reshape(g,[],1),reshape(b,[],1)];
crgb=rand(1e4,3);
c8rgb=[hsv(6);[0,0,0];[1,1,1]]; % 8 corners of the RGB cube
% convert to CIELAB
clab=rgb2lab(crgb);
c8lab=rgb2lab(c8rgb);
fprintf('L*: min=%.1f, max=%.1f.\n',min(clab(:,1)),max(clab(:,1)))
fprintf('a*: min=%.1f, max=%.1f.\n',min(clab(:,2)),max(clab(:,2)))
fprintf('b*: min=%.1f, max=%.1f.\n',min(clab(:,3)),max(clab(:,3)))
figure
plot(clab(:,2),clab(:,3),'k.')
grid on; xlabel('a*'); ylabel('b*'); axis equal; hold on
scatter(c8lab(:,2),c8lab(:,3),100,c8rgb,"filled")
subplot(211), histogram(clab(:,2),[-110:10:100],Normalization='probability');
xlabel('a*'); ylabel('Probability') % histogram of a*
subplot(212), histogram(clab(:,3),[-110:10:100],Normalization='probability');
xlabel('b*'); ylabel('Probability') % histogram of b*
The first plot shows the a*,b* values coresponding to points that fill the RGB cube. The corners of the RGB cube are shown. The black and white corners are both at a*,b*=(0,0).
The histogram plots show the probabilities of a* and b* in the ranges shown. The non-flatness of the histograms shows the non-uniformity of the sampling of a*, b* space. If I were to compute the joint histogram surface, it would show how some a*,b* combinations are sampled rarely or never.
Roger Breton
on 14 May 2024
Roger Breton
on 21 May 2024
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


