MATLAB Answers


Color segmentation (image processing)

Asked by Brian
on 23 Mar 2011

We are studying broadcast spawning fish behavior. To do so, we created a flow tank in which red and blue beads represent egg and sperm. We will be taking pictures and processing the images to determine if the egg and sperm were "fertilized." Fertilization in our model depends solely on if the egg and sperm were close enough to each other.

In order to differentiate between blue and red beads, we are trying to do color segmentation to create different matrices for red and blue bead centroids respectively. We tried both color-based segmentation using K-means clustering and using the L*a*b color space, but ended up with errors in each.

The codes work when we use the picture in the tutorial, but not when we try to input our own image. We have tried shrinking the size of the image, but that still didn't work. Our image has only three colors: red, blue, and the black background.

Any suggestions? Has anyone else had similar problems and found solutions?

Any help is greatly appreciated. Thank you.

K-means clustering code: %from

Ic = imread('Img00624.jpg'); figure, imshow(Ic), title('Color Image')

cform = makecform('srgb2lab'); lab_Ic = applycform(Ic,cform);

ab = double(lab_Ic(:,:,2:3)); nrows = size(ab,1); ncols = size(ab,2); ab = reshape(ab,nrows*ncols,2);

%Clustering is a way to separate groups of objects. K-means clustering treats each object as having a location in space. It finds partitions such that objects within each cluster are as close to each other as possible, and as far from objects in other clusters as possible. K-means clustering requires that you specify the number of clusters to be partitioned and a distance metric to quantify how close two objects are to each other.

%Since the color information exists in the 'a*b*' space, your objects are pixels with 'a*' and 'b*' values. Use kmeans to cluster the objects into three clusters using the Euclidean distance metric. nColors = 3; % repeat the clustering 3 times to avoid local minima [cluster_idx cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', 'Replicates',3);

pixel_labels = reshape(cluster_idx,nrows,ncols); imshow(pixel_labels,[]), title('image labeled by cluster index'); hold on;

segmented_images = cell(1,3); rgb_label = repmat(pixel_labels,[1 1 3]);

for k = 1:nColors color = Ic; color(rgb_label ~= k) = 0; segmented_images{k} = color; end

imshow(segmented_images{1}), title('objects in cluster 1'); imshow(segmented_images{2}), title('objects in cluster 2'); imshow(segmented_images{2}), title('objects in cluster 3');

L*a*b color space code: Ic = imread('test2.png'); figure, imshow(Ic), title('Color Image') load regioncoordinates;

nColors = 6; sample_regions = false([size(Ic,1) size(Ic,2) nColors]);

for count = 1:nColors sample_regions(:,:,count) = roipoly(Ic,region_coordinates(:,1,count), region_coordinates(:,2,count)); end

%imshow(sample_regions(:,:,2)),title('sample region for red');

cform = makecform('srgb2lab'); lab_Ic = applycform(Ic,cform);

a = lab_Ic(:,:,2); b = lab_Ic(:,:,3); color_markers = zeros([nColors, 2]);

for count = 1:nColors color_markers(count,1) = mean2(a(sample_regions(:,:,count))); color_markers(count,2) = mean2(b(sample_regions(:,:,count))); end %calculates the mean 'a*' and 'b*' value for each area that you extracted with riopoly. These values serve as your color markers in 'a*b*' space.

disp(sprintf('[%0.3f,%0.3f]',color_markers(2,1),color_markers(2,2))); % displays the average color of the red sample region in 'a*b*' space

% each color marker now has an 'a*' and a 'b*' value.

color_labels = 0:nColors-1; % creates an array that contains color labels. i.e. 0=background 1=red 2=blue

a = double(a); b = double(b); distance = zeros([size(a), nColors]); %initializes matrices to be used in the nearest neighbor classification

for count = 1:nColors distance(:,:,count) = ( (a - color_markers(count,1)).^2 + (b - color_markers(count,2)).^2 ).^0.5; end

[~, label] = min(distance,[],3); label = color_labels(label); %contains a color label for each pixel in the image. use this to separate objects in the original image by color (done below) clear value distance; % performs classification

rgb_label = repmat(label,[1 1 3]); segmented_images = repmat(uint8(0),[size(Ic), nColors]);

for count = 1:nColors color = Ic; color(rgb_label ~= color_labels(count)) = 0; segmented_images(:,:,:,count) = color; end

figure, imshow(segmented_images(:,:,:,1)), title('red objects') figure, imshow(segmented_images(:,:,:,2)), title('blue objects') figure, imshow(segmented_images(:,:,:,3)), title('black objects')


Can you provide a sample image please?

Please format your code (check the '{} code' widget when you edit the question), its hard to read.
Hope you had a look at Steve's series of posts on L*a*b color space segmentation:

Log in to comment.

1 Answer

Answer by neo
on 14 Apr 2011

hi...i am a bigener in matlab...andi have a project about color image segmentaion...can u help meeee.....i try to run this code in matlab for exemple..""but it didn't please help me......


Log in to comment.

Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

MATLAB Academy

New to MATLAB?

Learn MATLAB today!