use rgb to caculate three brown ratio

31 views (last 30 days)
sorry i say more about i want coding which can show light color, dark color, intermediate color ratio
focus is kind and ratio
image = imread('sample.jpeg');
image_double = im2double(image);
percentage_a = image_double(:,:,1) / sum(image_double, 3);
percentage_b = image_double(:,:,2) / sum(image_double, 3);
percentage_c = image_double(:,:,3) / sum(image_double, 3);
disp([num2str(percentage_a) '%']);
disp([num2str(percentage_b) '%']);
disp([num2str(percentage_c) '%']);
and picture like it ( the word we can ignore)

Accepted Answer

DGM
DGM on 6 Apr 2024
Edited: DGM on 6 Apr 2024
The question is unclear. This seems to be what was attempted, but it doesn't make sense given the question statement.
inpict = imread('brown.jpeg');
inpict = im2double(inpict);
% you can take the ratio of RGB channels versus the sum
% but this tells us nothing about the population of brown pixels
% or the three colors themselves
channelratio = mean(inpict./sum(inpict,3),1:2);
channelratio = permute(channelratio,[1 3 2])
channelratio = 1x3
0.5123 0.3567 0.1310
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Instead, I think it makes more sense to find the relative area covered by each of the three brown colors.
% instead of doing this using explicit color matching
% i'm just going to use rgb2ind().
inpict = imread('brown.jpeg');
inpict = im2double(inpict);
ncolors = 4; % three browns and one white
[indpict CT] = rgb2ind(inpict,ncolors,'nodither');
% CT should represent three browns and one near-white.
% find the white tuple, so that we can ignore it.
[~,whidx] = max(sum(CT,2)); % the index of white
bridx = setdiff(1:ncolors,whidx); % the indices of browns
% find the pixels belonging to each brown color
nbrownpix = zeros(1,3);
for k = bridx
nbrownpix(k) = nnz(indpict == k-1); % sum
end
nbrownpix = nbrownpix./numel(indpict) % normalize
nbrownpix = 1x3
0.2576 0.3449 0.3334
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
sum(nbrownpix) % total coverage of brown
ans = 0.9359
This can always be done doing any sort of color segmentation. There are plenty of examples on the forum. I'm just going to use the same colors as before.
% we can segment the image into three masks,
% one for each shade of brown.
inpict = imread('brown.jpeg');
inpict = im2double(inpict);
CT = [0.251 0.1843 0.01569; % middle
0.8902 0.7961 0.6392; % left
0.6196 0.3255 0.01961]; % right
tol = 0.1;
ncolors = size(CT,1);
nbrownpix = zeros(1,ncolors);
for k = 1:ncolors
% reorient tuple along page axis
pickedcolor = permute(CT(k,:),[1 3 2]);
% perform box (range) selection in RGB
boxmask = all(abs(inpict-pickedcolor) <= tol,3);
% sum
nbrownpix(k) = nnz(boxmask);
end
nbrownpix = nbrownpix./numel(boxmask) % normalize
nbrownpix = 1x3
0.2439 0.3253 0.3209
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  4 Comments
bozheng
bozheng on 6 Apr 2024
i mean is it will show light color, dark color, intermediate color ratio= 30%:40%;30%(total is approch 95-100%) sorry and thank
DGM
DGM on 6 Apr 2024
Edited: DGM on 6 Apr 2024
That's what the examples I gave do, although I express the results as unit fractions. Perhaps what's left unclear is which fraction corresponds to each of the three colors. I'll make some modifications. Will update in a bit.
EDIT:
Here are both examples, using very similar output formatting to express the results.
% instead of doing this using explicit color matching
% i'm just going to use rgb2ind().
inpict = imread('brown.jpeg');
inpict = im2double(inpict);
ncolors = 4; % three browns and one white
[indpict CT] = rgb2ind(inpict,ncolors,'nodither');
% CT should represent three browns and one near-white.
% find the white tuple, so that we can ignore it.
[~,whidx] = max(sum(CT,2)); % the index of white
bridx = setdiff(1:ncolors,whidx); % the indices of browns
% find the pixels belonging to each brown color
nbrownpix = zeros(1,3);
for k = bridx
nbrownpix(k) = nnz(indpict == k-1); % sum
end
nbrownpix = nbrownpix./numel(indpict); % normalize
% find order of shades in CT (darkest -> lightest)
[~,idx] = sort(im2gray(permute(CT(bridx,:),[1 3 2]))); % BT601 luma
ordstr = {'darkest','middle','lightest'}; % assuming three shades
for k = 1:numel(idx)
thistuplestr = mat2str(CT(idx(k),:),4);
fprintf('The %s brown is approximately %s in RGB\n', ordstr{k},thistuplestr)
fprintf('It covers %.1f%% of the total image area\n\n',nbrownpix(idx(k))*100)
end
The darkest brown is approximately [0.251 0.1843 0.01569] in RGB
It covers 25.8% of the total image area
The middle brown is approximately [0.6196 0.3255 0.01961] in RGB
It covers 33.3% of the total image area
The lightest brown is approximately [0.8902 0.7961 0.6392] in RGB
It covers 34.5% of the total image area
% we can segment the image into three masks,
% one for each shade of brown.
inpict = imread('brown.jpeg');
inpict = im2double(inpict);
CT = [0.251 0.1843 0.01569;
0.8902 0.7961 0.6392;
0.6196 0.3255 0.01961];
tol = 0.1;
ncolors = size(CT,1);
nbrownpix = zeros(1,3);
for k = 1:ncolors
% reorient tuple along page axis
pickedcolor = permute(CT(k,:),[1 3 2]);
% perform box (range) selection in RGB
boxmask = all(abs(inpict-pickedcolor) <= tol,3);
% sum
nbrownpix(k) = nnz(boxmask);
end
nbrownpix = nbrownpix./numel(boxmask); % normalize
% find order of shades in CT (darkest -> lightest)
[~,idx] = sort(im2gray(permute(CT(bridx,:),[1 3 2]))); % BT601 luma
ordstr = {'darkest','middle','lightest'}; % assuming three shades
for k = 1:numel(idx)
thistuplestr = mat2str(CT(idx(k),:),4);
fprintf('The %s brown is approximately %s in RGB\n', ordstr{k},thistuplestr)
fprintf('It covers %.1f%% of the total image area\n\n',nbrownpix(idx(k))*100)
end
The darkest brown is approximately [0.251 0.1843 0.01569] in RGB
It covers 24.4% of the total image area
The middle brown is approximately [0.6196 0.3255 0.01961] in RGB
It covers 32.1% of the total image area
The lightest brown is approximately [0.8902 0.7961 0.6392] in RGB
It covers 32.5% of the total image area
Intuition should agree with these fractions. The darkest shade is the most occluded by the text, so it has the lowest coverage. The other two shades should have similar coverage.
The results differ slightly. In the first example, the results are mutually-exclusive. In the second, they are not necessarily mutually-exclusive. The second result also relies on some prior sampling to determine the representative colors for each brown region.
FWIW, I tend to regard "percent" as purely a thing that exists in text displays. As far as I'm concerned, "one hundred percent" is written "1". Unless it has a % character appended to it, "100" means "one hundred". Text outputs are for human use, whereas numeric outputs are for programmatic use. That's why I dump unit fractions when asked for percent.

Sign in to comment.

More Answers (2)

Hassaan
Hassaan on 6 Apr 2024
image = imread('sample.jpeg'); % Load the image
image_double = im2double(image); % Convert to double precision floating point
% Calculate the sum of RGB values across the third dimension
sum_rgb = sum(image_double, 3);
% Calculate the percentage of each RGB channel relative to the sum
percentage_r = mean(mean(image_double(:,:,1) ./ sum_rgb));
percentage_g = mean(mean(image_double(:,:,2) ./ sum_rgb));
percentage_b = mean(mean(image_double(:,:,3) ./ sum_rgb));
% Display the results
fprintf('Red Channel Percentage: %.2f%%\n', percentage_r * 100);
fprintf('Green Channel Percentage: %.2f%%\n', percentage_g * 100);
fprintf('Blue Channel Percentage: %.2f%%\n', percentage_b * 100);
-----------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
It's important to note that the advice and code are based on limited information and meant for educational purposes. Users should verify and adapt the code to their specific needs, ensuring compatibility and adherence to ethical standards.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.
  1 Comment
bozheng
bozheng on 6 Apr 2024
sorry i say more about i want coding which can show light color, dark color, intermediate color ratio

Sign in to comment.


Image Analyst
Image Analyst on 8 Apr 2024
You could try using kmeans with k=5 for the three browns, black, and white (for the letters). Or you could also use K nearest Neighbors. Demos are attached.

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!