Converting Pixels to Line
1. Reading image
clear all;clc;
I = imread('pic24.jpg');
I = im2bw(I);
imshow(I);
2. Finding all the pixels with the value of '1'
[y,x] = find(I==1);
imshow(I);
hold on;
plot(x,y);
3. Use the "polyfit" function to fit polynomial to data, in our case, since it is a straight line, we use 1st order polynomial or a linear equation Y = M*X + C
p = polyfit(x,y,1);
disp(p);
-0.7873 158.3164
4. Find the image size and create the X and Y based on the coefficients of "p".
sz = size(I);
X = 1:sz(2);
Y = p(1) * X + p(2);
5. Display the result
imshow(I);
hold on;
plot(X,Y);
Detecting Objects' Motion in 2 Subsequence Images
1. Reading image and comparing 2 images side by side
clear all;clc;
Ia = imread('pic23a.jpg');
Ib = imread('pic23b.jpg');
subplot(121);imshow(Ia);
subplot(122);imshow(Ib);
2. Finding the location of green object in 2 images
a. Set the threshold value for green color
p/s: I can't make the "&" appear in text, so the text aboved is in image format.
b. Find the location of the green object
[y1,x1] = find(Ia_green==1);
[y2,x2] = find(Ib_green==1);
c. Find the centroid of the green object
x1 = round(mean(x1));
y1 = round(mean(y1));
x2 = round(mean(x2));
y2 = round(mean(y2));
3. Putting 2 images together and show the movement of the objects
figure;
imshow(Ia); hold on;
imshow(Ib);
alpha(.5);
plot(x1,y1,'r*');
plot(x2,y2,'ro');
plot([x1,x2],[y1,y2]);
The '*' indicates the start point of the object while the 'o' is the stop point of the object. Other objects' movement could be found by modifying the step number 2.
Hough Transform For Circle Detection - with unknown radius (I)
For detection circle with unknown radius, another parameter need to be make as variable, which is, the radius R.
Let's see how to perform this:
1. Reading image and the convert to binary image. After that, the location of the value '1' is found using 'find' function. (assume the image is already preprocess, if not, the 'edge' function might help)
clear all;clc;
I = imread('pic22.bmp');
I =im2bw(I);
[y,x]=find(I);
[sy,sx]=size(I);
imshow(I);
2. Find all the require information for the transformatin. the 'totalpix' is the numbers of '1' in the image.
totalpix = length(x);
3. Preallocate memory for the Hough Matrix. The R is known in the range from 1 to 50, so we reserve 50 "layers" for the HM matrix.
HM = zeros(sy,sx,50);
R = 1:50;
R2 = R.^2;
sz = sy*sx;
4. Performing Hough Transform. Notice the accumulator is located in the inner for loop.
for cnt = 1:totalpix
for cntR = 1:50
b = 1:sy;
a = (round(x(cnt) - sqrt(R2(cntR) - (y(cnt) - [1:sy]).^2)));
b = b(imag(a)==0 & a>0);
a = a(imag(a)==0 & a>0);
ind = sub2ind([sy,sx],b,a);
HM(sz*(cntR-1)+ind) = HM(sz*(cntR-1)+ind) + 1;
end
end
5. Find for the maximum value for each layer, or in other words, the layer with maximum value will indicate the correspond R for the circle.
for cnt = 1:50
H(cnt) = max(max(HM(:,:,cnt)));
end
plot(H,'*-');
6. Extract the information from the layer with maximum value, and overlap with the original image.
[maxval, maxind] = max(H);
[B,A] = find(HM(:,:,maxind)==maxval);
imshow(I); hold on;
plot(mean(A),mean(B),'xr')
text(mean(A),mean(B),num2str(maxind),'color','green')
7. This example use the "for loop" extensively, and the speed of the program is rather slow. Vectorized the code might speed up the execution time, we wee see it in the next example. :)
Hough Transform For Circle Detection - with known radius (II)
1. Reading image and the convert to binary image. After that, the location of the value '1' is found using 'find' function. (assume the image is already preprocess, if not, the 'edge' function might help)
clear all;clc;
I = imread('pic21.bmp');
I =im2bw(I);
[y,x]=find(I);
[sy,sx]=size(I);
imshow(I);
2. Find all the require information for the transformatin. the 'totalpix' is the numbers of '1' in the image.
totalpix = length(x);
3. Preallocate memory for the Hough Matrix. Try to play around with the R, or the radius to see the different results.
HM = zeros(sy*sx,1);
R = 36;
R2 = R^2;
4. Performing Hough Transform. Notice that no "for-loop" in this portion of code.
a. Preparing all the matrices for the computation without "for-loop"
b = 1:sy;
a = zeros(sy,totalpix);
y = repmat(y',[sy,1]);
x = repmat(x',[sy,1]);
b = repmat(b',[1,totalpix]);
b. The equation for the circle
a = (round(x - sqrt(R2 - (y - b).^2)));
c. Removing all the invalid value in matrices a and b
b = b(imag(a)==0 & a>0);
a = a(imag(a)==0 & a>0);
ind = sub2ind([sy,sx],b,a);
d. Reconstruct the Hough Matrix
val = ones(length(ind),1);
data=accumarray(ind,val);
HM(1:length(data)) = data;
HM2 = reshape(HM,[sy,sx]);
5. Showing the Hough Matrix
cla
imshow(HM2,[]);
6. Finding the location of the circle with radius of R
[maxval, maxind] = max(max(HM2));
[B,A] = find(HM2==maxval);
imshow(I); hold on;
plot(mean(A),mean(B),'xr')
Hough Transform For Circle Detection - with known radius (I)
The second approach would be more flexible especially when we want to modified the Hought Transform to detect other shape other than line. In this example, a modified version of Hough Transform is used to detect the circle instead of line.
In this case, instead of transforming the pixel to rho and theta domain, we use the circle equation --> (x-a)^2 + (y-b)^2 = R^2 to map the pixel to a-b domain. Let's see how to perform this:
1. Reading image and the convert to binary image. After that, the location of the value '1' is found using 'find' function. (assume the image is already preprocess, if not, the 'edge' function might help)
clear all;clc;
I = imread('pic20.bmp');
I =im2bw(I);
[y,x]=find(I);
[sy,sx]=size(I);
imshow(I);
2. Find all the require information for the transformatin. the 'totalpix' is the numbers of '1' in the image.
totalpix = length(x);
3. Preallocate memory for the Hough Matrix. Try to play around with the R, or the radius to see the different results.
HM = zeros(sy,sx);
R = 34;
R2 = R^2;
4. Performing Hough Transform. Notice the accumulator is located in the inner for loop. This portion of codes will map the original image to the a-b domain.
b = 1:sy;
for cnt = 1:totalpix
a = (round(x(cnt) - sqrt(R2 - (y(cnt) - [1:sy]).^2)));
for cnt2 =1:sy
if isreal(a(cnt2)) & a(cnt2)>0
HM(cnt2,a(cnt2)) = HM(cnt2,a(cnt2)) + 1;
end
end
end
5. Showing the Hough Matrix
imshow(HM,[]);
6. Finding the location of the circle with radius of R
[maxval, maxind] = max(max(HM));
[B,A] = find(HM==maxval);
imshow(I); hold on;
plot(mean(A),mean(B),'xr')
Simple Code for Hough Transform
1. Reading image and the convert to binary image. After that, the location of the value '1' is found using 'find' function. (assume the image is already preprocess, if not, the 'edge' function might help)
I = imread('pic20.jpg');
I =im2bw(I);
[y,x]=find(I);
[sy,sx]=size(I);
imshow(I);
2. Find all the require information for the transformatin. the 'totalpix' is the numbers of '1' in the image, while the 'maxrho' is used to find the size of the Hough Matrix
totalpix = length(x);
maxrho = round(sqrt(sx^2 + sy^2));
3. Preallocate memory for the Hough Matrix. The resolution for both rho and theta are set to one.
HM = zeros(2*maxrho,180);
4. Performing Hough Transform. Notice the accumulator is located in the inner for loop.
for cnt = 1:totalpix
cnt2 = 1;
for theta = -pi/2:pi/180:pi/2-pi/180
rho = round(x(cnt).*cos(theta) + y(cnt).*sin(theta));
HM(rho+maxrho,cnt2) = HM(rho+maxrho,cnt2) + 1;
cnt2 = cnt2 + 1;
end
end
theta = rad2deg(-pi/2:pi/180:pi/2-pi/180);
rho = -maxrho:maxrho-1;
imshow(uint8(HM),[],'xdata',theta,'ydata',rho);
xlabel('\theta'),ylabel('\rho')
axis on, axis normal;
title('Hough Matrix');
5. Done! However, the code is quite slow, anyway, it works!
Signature of Binary Objects
This example illustrates a simple way of converting the boundary of binary object into a 1-dimentional representation, or signature. One of the purpose of this conversion is to reduce the complexity of the representation for classification purpose. Let's have a look on how to convert the object to signature and compare the signature for different object shapes.
1. Original image (value 0 represent background while 1 represents object).
S = imread('pic19.jpg');
S = im2bw(S);
imshow(S);
2. Get the boundary and plot them on top of the original image.
[B,L,N,A] = bwboundaries(S);
imshow(S);
for cnt = 1:N
hold on;
boundary = B{cnt};
plot(boundary(:,2), boundary(:,1),'r');
hold on;
text(mean(boundary(:,2)), mean(boundary(:,1)),num2str(cnt));
end
figure;
subplotrow = ceil(sqrt(N));
3. Plot the signature of each object.
for cnt = 1:N
boundary = B{cnt};
[th, r]=cart2pol(boundary(:,2)-mean(boundary(:,2)), ...
boundary(:,1)-mean(boundary(:,1)));
subplot(subplotrow,N/subplotrow,cnt);
plot(th,r,'.');
axis([-pi pi 0 50]);
xlabel('radian');ylabel('r');
title(['Object ', num2str(cnt)]);
end
More details explanation could be found from the image processing reference book which could be found at the site bar of this page