All posts for the month March, 2010

MATLAB functions well as a simplified platform for rapid robotics development and prototyping.  Lately I’ve been working with it to perform image analysis for basic movement control.  The first project had the robot follow an colored sign.

My approach used Lab colorspace and a kmeans algorithm for fast detection rather than the typical brute force YUV colorspace object labeling.  In this example we will assume the function is passed an image, a colorA double, and a colorB double.

First one must change the image to the Lab colorspace.  More on the benefits of this later.

img = imresize(img, 0.3);
cform = makecform(‘srgb2lab’);
cf_Img = applycform(img,cform);

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

The first set of commands transforms an RGB image to Lab.  The second part isolates out the a and b components of the image.  The L is disregarded because it causes too many white balance headaches.  The a and b contain all the color information.

nColors = 3;

[cluster_idx cluster_center] = kmeans(ab,nColors);

distance = zeros(1,nColors);
for x = 1:nColors
distance(x) = sqrt((cluster_center(x,1)-colorA)^2+(cluster_center(x,2)-colorB)^2);
[smal, index] = min(distance);

Next we set how many blobs we want to be in our image.  Kmeans works by grouping the image into sets that are related by color.  The more sets we have, the more definition.  Next we execute the actual kmeans algorithm which gives us the output image and the central color point of each blob.  Remeber the colorA and colorB this function was passed?  Well that is the color of the blob we are looking for.  The next part of the function figures out which of those colors is closest to what we wanted.

After that’s done things are pretty simple:

for x = 1:length(cluster_idx)
if cluster_idx(x) == index
cluster_idx(x) = 1;
cluster_idx(x) = 0;

binImg = reshape(cluster_idx,nrows,ncols);

This part makes everything in the desired group a 1, and everything else a 0.  This creates a binary image that works with all the other built in functions.  For example:

s = regionprops(binImg, ‘centroid’);
outCentroid = cat(1, s.Centroid);

Gives you the centroid of the blob, and:

outArea = bwarea(binImg)

Gives you the area of the blob.  It’s pretty neat.  Using the built in functions can give you a lot of speed improvements too.