# Returning an array of colors from a double image

22 views (last 30 days)

Show older comments

##### 2 Comments

### Answers (4)

Voss
on 6 Mar 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')

##### 0 Comments

Image Analyst
on 6 Mar 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 Comments

Image Analyst
on 9 Mar 2022

colornames = {'w','r','g','b','y'};

by

colornames = {"white", "red", "gr","blue", "yellow"};

DGM
on 7 Mar 2022

Edited: DGM
on 7 Mar 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

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)

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)

##### 0 Comments

DGM
on 7 Mar 2022

Edited: DGM
on 7 Mar 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)

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)

##### 17 Comments

kiana
on 1 May 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

### See Also

### Community Treasure Hunt

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

Start Hunting!