Filter löschen
Filter löschen

Returning an array of colors from a double image

24 Ansichten (letzte 30 Tage)
Mark
Mark am 6 Mär. 2022
Kommentiert: kiana am 1 Mai 2024
I am trying to write a function that takes a type double image as input and returns an array of the colors in that image. The returned colors are supposed to be in a matrix form. The colors in my existing image are red, green, blue, white, and yellow. I can't get my head around this. Any suggestions?

Antworten (4)

Voss
Voss am 6 Mär. 2022
% create an image with colors r,g,b,w,y
im = ones(2,4,3);
im(1,1,:) = [1 0 0];
im(1,3,:) = [0 1 0];
im(2,2,:) = [0 0 1];
im(2,4,:) = [1 1 0];
imshow(im);
% get the set of unique colors in the image:
colors = unique(reshape(im,[],3),'rows')
colors = 5×3
0 0 1 0 1 0 1 0 0 1 1 0 1 1 1

Image Analyst
Image Analyst am 6 Mär. 2022
rgbImage = imread('peppers.png');
% Call the function:
colors = GetUniqueColors(rgbImage)
% Define the function:
function colors = GetUniqueColors(rgbImage)
[r, g, b] = imsplit(rgbImage);
colors = unique([r(:), g(:), b(:)], "rows")
end
  11 Kommentare
DGM
DGM am 9 Mär. 2022
That's what my second example does.
Image Analyst
Image Analyst am 9 Mär. 2022
I think @DGM means to replace
colornames = {'w','r','g','b','y'};
by
colornames = {"white", "red", "gr","blue", "yellow"};

Melden Sie sich an, um zu kommentieren.


DGM
DGM am 7 Mär. 2022
Bearbeitet: DGM am 7 Mär. 2022
You can leverage rgb2ind()'s minimum variance quantization to get a best-fit color table of specified length.
A = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/917239/image.png');
[~,CT] = rgb2ind(A,6) % get a color table of at most 6 colors
CT = 6×3
0.0392 0.0392 0.0392 0.2039 0.1686 0.9569 0.9569 0.0549 0.0392 0.8471 0.9569 0.0588 0.9569 0.9569 0.9569 0.0863 0.9569 0.2235
Bear in mind that since these colors were originally close to the extremes of the data range, truncation means that the addition of zero-mean gaussian noise will indeed shift the mean colors of the image, even if the noise mean is zero. I should point out that it's pretty clear the blue, green and yellow patches weren't on their corners to begin with.
If you know that you only want primary + secondary + neutral colors, you can just round the result.
CTrounded = round(CT)
CTrounded = 6×3
0 0 0 0 0 1 1 0 0 1 1 0 1 1 1 0 1 0
Otherwise, you can try to renormalize the values to correct for the inward shift caused by the noise. This assumes that the colors in the image nominally spanned the data range before the noise was added.
CTnormalized = mat2gray(CT)
CTnormalized = 6×3
0 0 0 0.1795 0.1410 1.0000 1.0000 0.0171 0 0.8803 1.0000 0.0214 1.0000 1.0000 1.0000 0.0513 1.0000 0.2009

DGM
DGM am 7 Mär. 2022
Bearbeitet: DGM am 7 Mär. 2022
Oh okay I totally misunderstood the question. Round 2:
A = imread('patchchart.png');
patchmask = rgb2gray(A)>40;
patchmask = bwareaopen(patchmask,100); % remove positive specks
patchmask = ~bwareaopen(~patchmask,100); % remove negative specks
patchmask = imclearborder(patchmask); % get rid of outer white region
patchmask = imerode(patchmask,ones(10)); % erode to exclude edge effects
imshow(patchmask)
% segment the image
[L N] = bwlabel(patchmask);
% get average color in each mask region
patchcolors = zeros(N,3);
for p = 1:N % step through patches
patchmk = L==p;
Apatch = A(patchmk(:,:,[1 1 1]));
patchcolors(p,:) = mean(reshape(Apatch,[],3),1);
end
patchcolors = patchcolors./255; % normalize
% specify a correlated list of colors and color names
colornames = {'w','r','g','b','y'};
colorrefs = [1 1 1; 1 0 0; 0 1 0; 0 0 1; 1 1 0];
% find color distances in RGB
D = patchcolors - permute(colorrefs,[3 2 1]);
D = squeeze(sum(D.^2,2));
% find index of closest match for each patch
[~,idx] = min(D,[],2);
% look up color names
patchnames = reshape(colornames(idx),4,4)
patchnames = 4×4 cell array
{'b'} {'y'} {'w'} {'y'} {'y'} {'w'} {'w'} {'r'} {'w'} {'y'} {'r'} {'r'} {'g'} {'w'} {'w'} {'r'}
Alternatively, instead of doing the distance minimization the long way, you could just use rgb2ind() to do that work:
% find index of closest match for each patch
idx = rgb2ind(permute(patchcolors,[1 3 2]),colorrefs) + 1;
% look up color names
patchnames = reshape(colornames(idx),4,4)
patchnames = 4×4 cell array
{'b'} {'y'} {'w'} {'y'} {'y'} {'w'} {'w'} {'r'} {'w'} {'y'} {'r'} {'r'} {'g'} {'w'} {'w'} {'r'}
  17 Kommentare
kiana
kiana am 25 Apr. 2024
Thanks alot
That was a great help.
kiana
kiana am 1 Mai 2024
Hi
I want have the matrix color of proj_1 so i correct it first first i find circles in proj_1 and org_1 and then correct the proj_1
but when I want to find colors I come up with a problem i it gives the wrong colors
can you help me to solve this problem ?
if contains(filename, 'proj')
image_db = loadImage_proj(filename);
% Find circle centers in the projection image
circle_centres = findCircles_proj(image_db, filename);
% Display circle centerscv
%figure(1), imshow(circle_centres);
% Correct image distortion based on the found circle centers
corrected = correctImage_proj(circle_centres, image_db, filename);
rgb = corrected;
%saturationIncrease = 0.01; % Increase saturation by 0.3
%valueAdjustment = 100; % Decrease value by 0.2 to make it darker
%rgb = enhanceYellowColor(rgb, saturationIncrease, valueAdjustment);
%rgb = imerode(rgb,ones(5));
%rgb = medfilt3(rgb,[11 11 1]);
%rgb = imadjust(rgb,stretchlim(rgb,0.05));
rgb = medfilt3(rgb,[7 7 1]); % median filter to suppress noise
rgb = imadjust(rgb,stretchlim(rgb,0.05)); % increase contrast
patchmask = rgb2gray(rgb)>0.101;
patchmask = bwareaopen(patchmask,100); % remove positive specks
patchmask = ~bwareaopen(~patchmask,100); % remove negative specks
patchmask = imclearborder(patchmask); % get rid of outer white region
patchmask = imerode(patchmask,ones(10)); % erode to exclude edge effects
imshow(patchmask)
% segment the image
[L N] = bwlabel(patchmask);
% get average color in each mask region
patchcolors = zeros(N,3);
for p = 1:N % step through patches
patchmk = L==p;
Apatch = rgb(patchmk(:,:,[1 1 1]));
patchcolors(p,:) = mean(reshape(Apatch,[],3),1);
end
patchcolors = patchcolors./255;
% try to snap the centers to a grid
S = regionprops(patchmask,'centroid');
C = vertcat(S.Centroid);
climits = [min(C,[],1); max(C,[],1)];
C = round((C-climits(1,:))./range(climits,1)*3 + 1);
% reorder color samples
idx = sub2ind([4 4],C(:,2),C(:,1));
patchcolors(idx,:) = patchcolors;
% specify a correlated list of colors and color names
colornames = {'w','r','g','b','y'};
colorrefs = [1 1 1; 1 0 0; 0 1 0; 0 0 1; 1 1 0];
% find color distances in RGB
D = patchcolors - permute(colorrefs,[3 2 1]);
D = squeeze(sum(D.^2,2));
% find index of closest match for each patch
[~,idx] = min(D,[],2);
% look up color names
patchnames = reshape(colornames(idx),4,4)
%figure(3);
%subplot(1, 2, 1), imshow(rgb), title('corrected Image');
%subplot(1, 2, 2), imshow(patchmask), title('color Image');
end

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Images finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by