Activity 12: Correcting Geometric Distortions (partial)

July 31, 2008 at 5:52 pm (Uncategorized)

*note. i still have to implement grayscale interpolation. as of the moment, i only did the pixel coordinate correction.

We can imagine our image as if it was warped through some linear transformation.

To better visualize the problem, we assume that we have a straight grid as pictured in the right side of the above image. However, since the camera has inherent geometrical aberrations, the picture we image would be warped and transformation is given as

where x’ and y’ are the coordinates of the pixels x,y (orig image) in the distorted image. Further, we assume that the transformation is is that of a bilinear function as shown below.

Thus, we have the transformation function as

The values of c are determined from the four vertices of corresponding polygon in the distorted image and ideal image. In this activity, I highlighted my region of interest and measured the actual and ideal pixel location of the region of interest. The green-highlighted section is the ideal locations of the grids.

However, the values of  and are valid in the included polygon.

My code below was executed from this set of instructions (from Dr Soriano’s lecture).

1. Obtain image.

2. From the most undistorted portion of the image, e.g. at the optical axis of the camera, count the number of pixels down and across one box.

3. Generate the ideal grid vertex points (just the coordinates).

4. For each rectangle compute c1 to c8 using pairs of equations (x’s,y’s) from the four corner points.

In compact matrix form, we have and . We can solve for the c’s using

and .

5. Per pixel in the ideal rectangle, determine the location of that point in the distorted image using

6. If the computed distorted location is integer-valued, copy the grayscale value from the distorted image onto the blank pixel. If the location is not integer-valued, compute the interpolated grayscale value using:

im=imread(‘image.jpg’);
im=im2gray(im);
[x,y]=size(im);
ideal=zeros(x,y);
for i=1 : 10 : x
ideal(i, :) =ones(y);
end

for j=1:8:y
ideal(:, j)=ones(x);
end
scf(1);
imshow(ideal, []);
blank=[];
xi=[31; 183; 183; 31];
yi=[48; 50; 97; 95];
T=[31 48 31*48 1; 245 48 245*48 1; 245 95 145*95 1; 31 95 31*95 1];
c14=inv(T)*xi;
c56=inv(T)*yi;
for i=1 : x
for j=1:y
x_im=c14(1)*i+c14(2)*j+c14(3)*i*j+c14(4);
y_im=c56(1)*i+c56(2)*j+c56(3)*i*j+c56(4);
if x_im>=x
x_im=x;
end
if y_im>=y
y_im=y;
end
blank(i, j)=im(round(x_im), round(y_im));
end
end
scf(2);
imshow(blank, []);
//for j=1:10:y
// ideal(:, y)=ones(x);
//end

Permalink Leave a Comment

Activity 11: Camera Calibration

July 29, 2008 at 8:41 pm (Uncategorized)

In this activity, we calibrate a camera to determine the mapping of each location (3D) on an object to its camera image (2D). This is shown in the figure below from Dr Soriano’s lecture.

After some algebra, we are lead to this equation where the “o” subscript refer to the object and the “i” subscript refer to the image. As can be seen, the there are only two equation for the mapping since the image is flat.

In matrix form, the above equation is written as

However, this is for a single image, and we have to append the Q and d matrix as we increase the number of points that will be used to determine the mapping. In compact matrix form, we have

We can solve for the transformation matrix a using some matrix algebra which results to

The image that we have obtained by taking a picture of the checker board is shown below. The location of the points used in determining the mapping is shown in my program.

x=[0 0 0 0 1 1 2 0 1 0 3 1 0 3 0 2 0 0 0 1 ];
y=[0 1 0 3 0 0 0 1 0 5 0 0 2 0 2 0 5 3 0 0 ];
z=[0 12 3 2 1 2 5 8 1 3 8 9 6 10 7 7 9 10 9];
yi=[127 139 126 164 115 115 102 139 113 191 90 114 152 88 152 101 193 166 125 112];
zi=[200 187 169 161 172 189 175 123 73 200 161 73 57 112 40 91 97 58 138 56];
obj=[];
im=[];
for i=0:length(x)-1
obj(2*i+1, :) =[x(i+1) y(i+1) z(i+1) 1 0 0 0 0 -yi(i+1).*x(i+1) -yi(i+1).*y(i+1) -yi(i+1).*z(i+1)];
obj(2*i+2, :) =[0 0 0 0 x(i+1) y(i+1) z(i+1) 1 -zi(i+1).*x(i+1) -zi(i+1).*y(i+1) -zi(i+1).*z(i+1)];
im(2*i+1)=yi(i+1);
im(2*i+2)=zi(i+1);
end
a=inv(obj’*obj)*obj’*im;
a(12)=1.0;
a=matrix(a, 4, 3)’;
testx=1;
testy=0;
testz=2;
ty=(a(1,1)*testx+a(1,2)*testy+a(1,3)*testz+a(1,4))/(a(3,1)*testx+a(3,2)*testy+a(3,3)*testz+a(3,4));
tz=(a(2,1)*testx+a(2,2)*testy+a(2,3)*testz+a(2,4))/(a(3,1)*testx+a(3,2)*testy+a(3,3)*testz+a(3,4));
ty
tz

We’ve verified that this works with error of a few pixels. As of the moment, more accurate methods of getting the points is needed for a more accurate calibration. In our data, the actual pixel values of (1,0,2) are (114, 172) while the value from the calibration is (122, 177). A possible source of error, other than inaccuracy in getting the pixel values is radial distortion (as was mentioned by Dr Soriano). Another source of error is the high resolution of the image which causes error in choosing which pixel is the corner of the board.

I give my self 9.5/10 because of some inaccuracies encountered. Although i am satisfied enough with the result.

Tnx to Julie for the help with the image. :)

Permalink Leave a Comment

Activity10: Preprocessing of Handwritten Text

July 22, 2008 at 4:57 pm (Uncategorized)

The goal of this activity is to pre-process handwritten text for image processing. The original image I used is

with probability distribution

and 2d fft

We used a vertical mask in manipulating our fft to remove the horizontal lines.The processed fft is:

However, the lines were not removed but merely blurred out. This was not the case in activity 7.

The resulting binarized image is shown below.

The opening operation was used but without much success. We did not use the closing operation since we want to retain the holes of the letters, which is a property of the letters.

Code as follows:

chdir(“/home/jeric/Desktop/ap18645activity10″);
clear all;
getf(“imhist.sce”);
im=imread(“ac10.jpg”);
im=im2gray(im);

if max(im)<=255
im=round(im*255);
end

[val,num]=imhist(im);
h=scf(1);
plot(val, num);

ff=fftshift(fft2(im));
h=scf(2);
imshow(abs(ff), []); xset(“colormap”, hotcolormap(64));

[x,y]=size(im);
newff=ff(:,:);

filter=ones(x,y);
for j=y/2-2:y/2+2
for i=1 :x /2-2
filter(i,j)=0;
end
for i=x/2+ 2 : x
filter(i,j)=0;
end
end

newff=filter.*ff;
h=scf(3);
imshow(abs(newff), []); xset(“colormap”, hotcolormap(64));

h=scf(4);
im2=abs(fft2(newff));
imshow(abs(fft2(newff)), []);

im=im2bw(im, 160/255);

h=scf(5);
imshow(im, []);

se=ones(2,2); //structuring element

im=erode(im, se); //opening
im=dilate(im, se);

im=erode(im, se); //opening
im=dilate(im, se);

[L,n]=bwlabel(im);

h=scf(6);
imshow(im, []); //preprocessed image

Rating: 6, because of the poor resulting image. The goal was not achieved.

Permalink 1 Comment

Activity 9: Binary Operations

July 17, 2008 at 11:26 am (Uncategorized) (, , , , , )

The goal of this activity is to find size of each “cell” in then image. We will be implementing the various techniques we have learned so far in solving the problem.

One of the relevant concepts that we will be implementing is the histogram thresholding to separate the background from the image. Another relevant concept is the opening and closing operations in morphological transformations. Opening is mathematically defined as

which simply means is the dilation of an erosion (see previous entry). Opening has the effect of removing small objects or noise. Closing on the other hand is defined as

which means the erosion of a dilation. It has the effect of removing small holes in the object.

The image above is divided into 9 images of size 256×256 to remove the burden of using too much memory.

My code for the activity is shown below.

getf(“imhist.sce”);
im=imread(‘circ01_01.jpg’);
stacksize(4e7);
pref=‘circ01_0′;

//create filter
se=ones(10,10);
se=mkfftfilter(se, ‘binary’, 4);

area=[];
counter=1

//scan images
for i=1:9
im=imread(strcat([pref,string(i),'.jpg']));
im=im2gray(im);
im=im2bw(im, 205/255);
im=erode(im, se); //opening
im=dilate(im, se);
im=dilate(im, se); //closing
im=erode(im, se);
[L,n]=bwlabel(im);
//scan regions
for j=1:n
area(counter)=length(find(L==j));
counter=counter+1;
end
end

scf(10);
histplot(length(area),area);
x=find(area<600 & area>450);
scf(11)
histplot(length(x), area(x));
a=area(x);
a=sum(a)/length(x) //area
y=stdev(area(x)) //error

The ‘pref’ variable is used to defined the prefix of the subimage, and concatenates it with a counter for loop with the 9 sub-images. We also used the ‘bwlabel’ command which looks for continuous regions in a binary image and labels them accordingly.

The histogram yields:

We can see that bwlabel has considered overlapping cells as one. However, we limit our interest to areas with less than 800 pixels  and greater than 400 pixels to increase the accuracy the calculation of the average of the cell. As can be seen below, there are regions that were labeled by bwlabel that was extremely small and some regions that were labeled were very large. Thus, setting a limit to the acceptable area is necessary.

The calculated areas is area=538.15 with std deviation of std=22.645. We are confident that this is indeed within the limits of the accepted area. To check the validity of our results, we took a subimage and calculated the area of the “cells”. The subimage that we took has completely separted cell, which ensures that the area we calculate is the area of a cell, and not the area of compounded/joint cells.

I gave myself a rating of 10 because i believe that i was able to do the activity right.

Collaborators: Cole, Julie.

Permalink Leave a Comment

Activity 8: Morphological Transforms

July 15, 2008 at 9:04 pm (Uncategorized)

Dilation and Erosion are morphological transform where we have a binary image (white/1 foreground and black/0 background). Dilation is mathematical defined as

where A is the image and B is called the structuring element where the dilation is based. In lay terms (or in more comprehensible terms), Is the set that involves all z’s which are translations of a reflected B that when intersected with A is not the empty set. This can be illustrated as

On the other hand, erosion is mathematically defined as

or in more comprehensible terms,  is  the set  of all  points z such  that  B  translated by z  is contained in A. The effect of erosion is to reduce the image by the shape of B. This can be illustrated as

(based on Dr Soriano’s lecture)

In this activity, we used different images (circle, square, hollow square, triangle and cross) and varying structuring elements shown here:

The results of the morphological transform are shown below. The code is

se1=ones(4,4); //square
se2=ones(2,4); //rectangle
se3=ones(4,2); //rectangle
se4=[0 0 1 0 0; 0 0 1 0 0; 1 1 1 1 1; 0 0 1 0 0; 0 0 1 0 0]; //cross

im=imread(‘cross.PNG’);
im=im(:,:,1);
er1=erode(im, se1, [1,1]);
er2=erode(im, se2, [1,1]);
er3=erode(im, se3, [1,1]);
er4=erode(im, se4, [3,3]);

di1=dilate(im, se1, [1,1]);
di2=dilate(im, se2, [1,1]);
di3=dilate(im, se3, [1,1]);
di4=dilate(im, se4, [3,3]);

scf(1);
subplot(2,2,1);
imshow(se1);
subplot(2,2,2);
imshow(se2);
subplot(2,2,3);
imshow(se3);
subplot(2,2,4);
imshow(se4);

scf(2);
subplot(2,2,1);
imshow(er1);
subplot(2,2,2);
imshow(er2);
subplot(2,2,3);
imshow(er3);
subplot(2,2,4);
imshow(er4);

scf(3);
subplot(2,2,1);
imshow(di1);
subplot(2,2,2);
imshow(di2);
subplot(2,2,3);
imshow(di3);
subplot(2,2,4);
imshow(di4);

Circle Dilation

Circle Erosion

Cross

Cross Dilate

Cross Erode

hollow

Hollow Dilate

Hollow Erode

Square

Square Dilate

Square Erode

Triangle

triangle dilate

triangle erode

I will give my self 10 pts here since the actual and predicted are in good correspondence.

Thanks to Julie and JC for the help. :)

Permalink Leave a Comment

Activity 7: Enhancement in the Frequency Domain

July 10, 2008 at 9:52 am (Uncategorized)

Varying the frequency of a sinusoid image has the effect of changing the peaks of the fft. Higher frequencies correspondes to fft peaks farther from (0,0) which is expeceted.

and their corresponding FT

Rotation of the image consequently rotates the FFT but on the other direction

And multiply sine and cosine results in peaks of coordinates which are the peak of the sine and cosine.

-oOo-

Fingerprint Enhancement

We now apply some filtering techniques to enhance this finger print sample.

clear all;
im=imread(“finger.jpg”);
im=im2gray(im);
im=im-mean(im);
ff=fft2(im);
h=scf(1);
imshow(abs(fftshift(ff)), []); xset(“colormap”, hotcolormap(64)); //show fft of image

//make exponential high pass filter

filter=mkfftfilter(im, ‘exp’, 30);
filter=fftshift(1-filter);

//perform enhanment
enhancedft=filter.*ff;
enhanced=real(fft2(enhancedft));
h=scf(2);
imshow(enhanced, []);

h=scf(3);
imshow(abs(fftshift(fft2(enhanced))), []); xset(“colormap”, hotcolormap(64));

Orignal Image

FT of the original image

Filter

Enhanced fingerprint

FT of the enhanced finger print.

-oOo-

Line Removal In Lunar Image

We have an image here of a images of the moon with strong vertical lines, and to enhance it, we have to remove the those lines.

Looking at the fft, we can see that this white lines are produced by the frequency components encircled (which has symmetry so you can see the corresponding intensity on the right-half) because of the lines’ periodicity. The goal then, is to make a filter to lessen the amplitude of the frequencies encircled*.

I made a mask that cuts off the horizontal line at which the encircled frequencies above lie. However, i retained the a portion near the center to retain some information. The mask looks like this:

The masked fft looks like this:

Finally, the enhanced image looks like this

and there are no more vertical lines present. :)

Code:

clear all;
stacksize(4e7);
im=imread(“luna.png”);
im=im2gray(im);
im=im; //-mean(im);
ff=fft2(im);
h=scf(1);
ff=fftshift(ff);
imshow(abs(ff), []); xset(“colormap”, hotcolormap(64));

[x,y]=size(im);
enhancedft=ff;
for i=(x+1)/2-2:(x+1)/2+2
enhancedft(i,1:(y+2)*11/24)=0;
enhancedft(i,(y+2)*13/24:y)=0; //immediate process the ft.
end
enhanced=abs(fft2(enhancedft));

h=scf(2);
imshow(abs(enhancedft), []); xset(“colormap”, hotcolormap(64));
h=scf(3);
imshow(enhanced ,[]);

*Note: The fft is bright because i removed the mean first of the image before performing fft, however, in the actual processing, i did not remove the mean of the image from the image matrix.

I have hints from: http://www.roborealm.com/help/FFT.php

Score: 10. Since i was able to do all of the task, and am proud of the removal of the vertical lines.:)

Collaborators: Julie, Cole, Leil, Benj

Permalink 1 Comment

Activity 6: Fourier Transform Model of Image

July 8, 2008 at 11:15 am (Uncategorized) (, , , , )

Activity 6-A: Familiarization with discrete FT

Doing the Fourier transform on a circle :

yields

However, the FFT algorithm inverts the quadrants of the FT plane and this has to be corrected using the fftshift() command. This process yields the correct FT of a circle whose analytical solution is the Airy circle, as shown in the figure below

Performing an FFT on th FFT of an image results to the original image, and is one of the properties of FFT. The image below indeed confirms this.

I = imread(‘circle.bmp’);
Igray = im2gray(I);
FIgray = fft2(Igray); //remember, FIgray is complex
h=scf(1);
imshow(abs((FIgray)), []); xset(“colormap”, hotcolormap(64));
h=scf(2);
imshow(abs(fftshift(FIgray)),[]); xset(“colormap”, hotcolormap(64));
h=scf(3);
imshow(abs(fft2(FIgray)), []); xset(“colormap”, hotcolormap(64));

-oOo-

Convolution

Convolution is process wherein the product of two functions f and g has the effect of transforming f and g.

Also, the convolution theorem states that the Fourier transform of a convolution is the product of the individual Fourier transform times a constant k.

In optics, this concept can be applied to lenses wherein we have an original image f and a lens g. Thus, with a finite lens, we can never reconstruct an image 100%.

We obtain the FT of the letter J and obtained

After fftshift, we had

And doing an fft again results to an inverted J.

We now convolve the image with a circular aperture and this results to:

We can see that the image has been blurred because of the finite size of the aperture. We then investigate the effect of varying the lens/aperture size with the resulting image. From our simulations, we saw that decreasing the size of the lens decreases the clarity of the image, as show in the following figure.

clear all;
r=imread(’smallest.bmp’);
a=imread(‘letters.bmp’);
rgray = im2gray(r);
agray = im2gray(a);
Fr = fftshift(rgray);
Fa = fft2(agray);

FRA = Fr.*(Fa);
IRA = fft2(FRA); //inverse FFT
FImage = abs(IRA);
h=scf(1);
imshow(FImage, []);

-oOo-

Template Matching

We performed template matching of the images. From the text below, we located areas where they have a high degree of correlation and similarity with the template “A”. There is a high degree of correlation in places where there is high degree of similarity.

Places with high correlation is indicated by bright white spots. However, the image is upside-down and left-side right. Rotating the image of the correlation would correspond would yield a direct correspondence with the places in the original text.

words=imread(“word.bmp”);
a=imread(“A.bmp”);
words=im2gray(words);
a=im2gray(a);
ftwords=fft2(words);
fta=fft2(a);
correlation=ifft(fta.*conj(ftwords));
imshow(abs(fftshift(correlation)), []); xset(“colormap”, hotcolormap(256);

-oOo-

Edge Detection

We performed edge-detection using vertical, and horizontal filters using the command imcorrcoef(). This command is similar to template matching but instead uses a kernel template, and doesn’t care with the size of the template and the image.

let=imread(“L.bmp”);
let=im2gray(let);
hor = [-1 -1 -1; 2 2 2; -1 -1 -1];
vert= [-1  2 -1; -1 2 -1;-1  2 -1];
von = [-1 -1 -1; -1 8 -1; -1 -1 -1];
pattern=von //im2gray(vert);
c=imcorrcoef(let, pattern);
imshow(c);

We can see from the figure above that the correlation technique is helpful in finding the horizontal and vertical edges of the letter L. But we want to get the outline of an image, we can use the “von” pattern located above that locates only boundaries may it be horizontal or vertical.

Rating: 9.5 because i wasn’t reading some of the instruction although i was able to perform all the required tasks.

Acknowledgments: Julie, Cole, Benj and Lei.

Permalink Leave a Comment

Activity 5: Physics Measurements from Discrete Fourier Transform

July 3, 2008 at 9:24 am (Uncategorized) (, )

Discrete Fourier Transform is a mathematical construct where you determine the frequency component of a signal, very much like breaking down white light (signal) to its frequency components (colors). Fourier transform can be done numerically using

-oOo-

Performing FFT (code provided by Dr. Soriano)

T = 2;
N = 256;
dt = T/256;
t = [0:dt:(N-1)*dt];
f = 5;
y = sin(2*%pi*f*t);
f1 = scf(1); plot(t,y);

FY = fft(y);
F = 1/(2*dt);
df = 2*F/256;
f = [-(df*(N/2)):df:df*(N/2 -1)];

f2 = scf(2); plot(f, fftshift(abs(FY)));

-oOo-

The method of getting Fourier transform of images is somewhat similar to the process of getting the FT of temporal signals. In the case of images, we use the pixels as our discrete time, and we now perform spatial FT. Two dimensional FT can be done using

fft2=fft(fft(im).’).’

The algorithm above as mention in the Mathworks (Matlab) perform 1d FT along each column of im and them perform FT along the row of the result.

Sine wave (f=5, T=2)

We investigate the effect of varying the number of samples N with the Fourier Transfrom. From the plot below, we can see that by increasing the number of N, we widen the domain of our FT.


On the other hand, by having the total time fixed and increasing N (and effectively decreasing dt), we find that there is not much difference on the peak frequency, and the amplitude is half the value of N. This is because we are adding more signals components as compared to with lower N.

Permalink 1 Comment