Robust line fitting application example

Contents

Load the image

Read and show the image file

i=imread('img.png');
imshow(i);
title('original image');

Make the image grayscale

The image is, 240 rows x 320 columns. Since it is a color image, each element is composed by three values, for Red, Green and Blue. We prefer to work with a single value per pixel, so we discard color information and make the image grayscale.

size(i)
i=rgb2gray(i);
size(i)
imshow(i);
title('grayscale version');
ans =
   240   320     3
ans =
   240   320

Highlight

Intensity values suddently drop when transversing the left edge from left to right. Let's compute the finite differences by convolving with a simple [1, -1] kernel. Visualize the result, mapping the minimum value (which will be negative) to black, and maximum to white.

edge=conv2(i,[-1,1],'valid');
min(min(edge))
max(max(edge))
imshow(edge,[min(min(edge)),max(max(edge))]);
title('horizontal convolution with [-1,1] kernel');
Warning: CONV2 on values of class UINT8 is obsolete.
         Use CONV2(DOUBLE(A),DOUBLE(B)) or CONV2(SINGLE(A),SINGLE(B)) instead.
ans =
   -23
ans =
    14

Pick points on left edge

We threshold the finite differences image, and pick the (r,c) coordinates of all points greater than one third of the maximum. Note, we are flipping the image here, rows becomes x and cols becomes y.

[x,y]=find(edge>max(max(edge))/2);
scatter(x,y,'k.');
title('edge points');

Fit

Fit a line using both robust fitting and ordinary least squares linear regression, then plot the results.

robfit=robustfit(x,y);
lsfit=polyfit(x,y,1);

hold on;
plot(x,robfit(1)+robfit(2)*x,'g-')
hold on;
plot(x,lsfit(2)+lsfit(1)*x,'r-')
title('least squares (red) and robust (green) fit');

figure
scatter(x,y,'k.');
hold on;
plot(x,robfit(1)+robfit(2)*x,'g-')
hold on;
plot(x,lsfit(2)+lsfit(1)*x,'r-')
v=axis;
axis([v(1),v(2),0,100]);
title('least squares (red) and robust (green) fit, zoomed');