# use rgb to caculate three brown ratio

6 views (last 30 days)

Show older comments

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)

##### 0 Comments

### Accepted Answer

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])

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

sum(nbrownpix) % total coverage of brown

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

##### 4 Comments

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

% 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

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.

### More Answers (2)

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.

Image Analyst
on 8 Apr 2024

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!