use rgb to caculate three brown ratio
29 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponse acceptée
DGM
le 6 Avr 2024
Modifié(e) : DGM
le 6 Avr 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 commentaires
DGM
le 6 Avr 2024
Modifié(e) : DGM
le 6 Avr 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.
Plus de réponses (2)
Hassaan
le 6 Avr 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
le 8 Avr 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.
0 commentaires
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!