Color segmentation (image processing)

4 views (last 30 days)
Brian
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 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')
  2 Comments
Sean de Wolski
Sean de Wolski on 23 Mar 2011
Can you provide a sample image please?
Ashish Uthama
Ashish Uthama 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/

Sign in to comment.

Answers (1)

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

Products

Community Treasure Hunt

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

Start Hunting!