MATLAB Answers

Color segmentation (image processing)

Asked by Brian

Brian (view profile)

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 http://www.mathworks.com/products/image/demos.html?file=/products/demos/shipping/images/ipexhistology.html

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

Sean de Wolski

Sean de Wolski (view profile)

on 23 Mar 2011

Can you provide a sample image please?

Ashish Uthama

Ashish Uthama (view profile)

on 23 Mar 2011

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: http://blogs.mathworks.com/steve/2011/02/04/more-on-segmenting-in-a-b-space/

1 Answer

Answer by neo

neo (view profile)

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.."http://blogs.mathworks.com/steve/2011/02/04/more-on-segmenting-in-a-b-space/"but it didn't work....so please help me......

Join the 15-year community celebration.

Play games and win prizes!

Learn more

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!