Developing C programs on Mac OS X using Xcode 3.0

April 13, 2008

Having switched to a Mac a few months ago, I was interested in finding out how to program in C using the software available on my Mac. Xcode 3.0 does the job. If you want to write a C program, just follow along:

Open Xcode 3.0 and click File > New Project. Select the arrow next to “Command Line Utility” and choose Standard Tool. Give your project a name and a location in which to store all the files that Xcode will build for you.

Now select Window > Organizer. Next, you’ll want to open a finder window and browse for the location of the name of the project folder you created earlier. Drag and drop that folder into the Organizer window. You’ll notice that it shows up there.

Click the arrow next to the project folder to see the files inside this folder. Next, to access the main C file, you can double click the file main.c, or you can click on the bottom icon the furthest to the right to open the editor in the Organizer window.

The next thing you’ll want to do is click the Build button, the one with the hammer. Finally, click the Run button. There you have it: you’re first C program on a Mac.


Edge Detection Simulation

April 6, 2008

The following example demonstrates edge detection on a black and white image. I wrote the code in MATLAB.

clear;
clc;

% Define kernel parameters
sigma = 4;
size = 4;

% Initialize dimensions of kernel matrix
xKerMax = 3;
yKerMax = 3;

% Initialize dimensions of source image
yMax = 326;
xMax = 640;

% Initialize the kernel matrix
kernel = zeros(3, 3);

% Initialize the destination image
dstImg = zeros(yMax – (yKerMax – 1),xMax – (xKerMax – 1));

% Compute elements of kernel matrix
for yKer = 1:yKerMax
for xKer = 1:xKerMax
if( mod((yKer – 1)*yKerMax + xKer, 2) == 0)
kernel(yKer, xKer) = -1;
else
kernel(yKer, xKer) = 0;
end
if( (yKer – 1)*yKerMax + xKer == 5)
kernel(yKer,xKer) = sigma;
end
end
end

% Plot kernel
%figure(3),surf(xKer,yKer,kernel);

% Load the source Image
srcImg = imread(‘bw.jpg’);

% Convert data in image to double
srcImg = im2double(srcImg);

% Plot the data in source image
figure(1), imshow(srcImg);

% Carry out convolution
for y = 1:(yMax – (yKerMax – 1))
for x = 1:(xMax – (xKerMax – 1))
for yKer = 1:yKerMax
for xKer = 1:xKerMax
dstImg(y,x) = dstImg(y,x) + srcImg(y + yKer – 1, x + xKer – 1)*kernel(yKer, xKer);
end
end
end
end

dstImg = im2uint8(dstImg);

figure(2), imshow(dstImg);

The source image before filtering

The filtered image

By altering the part of the code involving the convolution, we can create a binary image that may give us a clearer picture of the outlines of the image. The change is as follows:

% Carry out convolution
for y = 1:(yMax – (yKerMax – 1))
for x = 1:(xMax – (xKerMax – 1))
for yKer = 1:yKerMax
for xKer = 1:xKerMax
dstImg(y,x) = dstImg(y,x) + srcImg(y + yKer – 1, x + xKer – 1)*kernel(yKer, xKer);
end
end
if (dstImg(y,x) <= 0)
dstImg(y,x) = 0;
else
dstImg(y,x) = 1;
end
end
end

This yields the following binary image:

The binary image


What does the # mean before the include?

April 2, 2008

That’s the question I had been asked a few months ago while on the phone with an interviewer from the MathWorks. I didn’t have a clue. All I knew was that you typed it all the time when you wanted to make sure you could use the printing functions in your main function. I finally wanted to put this question to rest, so I did a little research.

The # sign in C++ is a directive that says “handle this with the preprocessor” while the include statement means “make everything in the provided file available to this program” [1].

The “<” and “>” tell the preprocessor that the file located inside the angle brackets is located in the standard search path [1].

We may ask: “Exactly what does the #include do?  It copies the content of the file specified inside the quotation marks or the angle brackets, and places it in the file at the location where the #include appears [2].

References:

[1] “What does #include <stdio.h> stand for in c program?” Yahoo! Answers. April 2, 2008. http://answers.yahoo.com/question/index?qid=20080103071957AAKM9jX

[2] “Preprocessor”. April 3, 2008. http://en.wikipedia.org/wiki/Preprocessor


Convolution Unconvoluted

April 1, 2008

Convolution is a big topic in image processing. It’s a lot easier than people write it out to be. Let’s begin with a 5 x 5 pixel image; that is, we have a total of 25 pixels. You can think of this image as a matrix of 5 rows and 5 columns. Here’s a picture:

Convolution is a mathematical binary operation, which means you need two of something before you can perform a convolution. Just like addition, subtraction, division, and multiplication need two of something before you add, subtract, divide, or multiply respectively, convolution is no different.

The other piece of info we need before we carry out a convolution is what we call a Kernel. Don’t get thrown off by this, it’s just a name. Perhaps you can recall your early days in elementary school where you were taught similar names for the more familiar operations. Take division for example: you learned there are names such as the divisor, the dividend, and the quotient—all corresponding to the numbers carrying out a particular function within the operation of division. You can’t divide if you only have a dividend: you need a divisor as well. We can do this for subtraction also: you have the minuend, subtrahend, and difference. Complicated? Here’s a picture:

Just remember these are just naming conventions and are a shorthand notation of referring to “this” or “that” without any ambiguity.

Before we explain the intricacies of convolution, let’s begin with the elementary ideas. Imagine you have an ice cube holder. If you fill the ice cube holder to the brim and let the water freeze, you get ice cubes stuck together on a plane of water. Suppose you cut out a 2 x 3 plane of cubes, that is, you have a plane of ice filled with two rows of cubes and three columns of cubes. Suppose also that we have the kind of ice cube tray only Costco would sell: a tray that fits 25 ice cubes, 5 rows and 5 columns. Without rotating the 2 x 3 plane of ice cubes, find all possible ways of placing those cubes neatly inside the 5 x 5 ice cube tray. Here’s a picture:

Now let us choose the convention of placing a thumbtack on the top left corner of the 2 x 3 plane of ice cubes. Placing the 5 x 5 ice cube tray on a white sheet of paper, let’s also write numbers to denote the rows and columns of the tray. We begin with row 0 and finish off at row 4. Likewise, we begin with column 0 and finish off at column 4. Here’s a picture:

Every time we place our 2 x 3 plane of ice cubes inside the 5 x 5 tray, we take note of where the thumbtack is pointing to. If we place the 2 x 3 plane of ice cubes in the very top left-hand side of the 5 x 5 tray, the thumbtack points to the location row 0 column 0, which we will write as (0,0). Why do we have the thumbtack? I’ll get to that soon. At this point, I want you to make a leap from the current visual analogy and do a little math. Suppose there are numbers inside every hole in the ice cube tray. Suppose also there are numbers locked inside every cube of the 2 x 3 ice cube plane. Having placed the 2 x 3 ice cube plane on the location (0,0), multiply the numbers inside inside the ice cube tray with the numbers inside the 2 x 3 ice cube plane. Here’s the rule: you can’t multiply a number that lives in the hole in a tray with a number in an ice cube that does not lie inside that hole. Once you’ve carried out all those multiplications (which should be a total of 6 multiplications, since your 2 x 3 ice cube plane is made up of 6 ice cubes in total), add the results to obtain the final result.

Having found the result corresponding to the location (0,0), I’ll tell you now that this result is the number you store in a new ice cube tray at row 0 column 0, which is (0,0). You do this for every possible way you can place the 2 x 3 ice cube plane inside the original 5 x 5 ice cube tray, making sure that you keep track of where the thumbtack is. The reason the thumbtack is important is because it tells you exactly where you should store the result you obtain in your new ice cube tray.

In the end, you should end up with a new ice cube tray that has a 4 x 3 size, that is, four rows and 3 columns.

From here, it should be easy to make the shift to talking about images, pixels, mathematical convolution, kernel, input and output images, and dimensionality.

References:

“Convolution.” April 1, 2008. ©2003 R. Fisher, S. Perkins, A. Walker and E. Wolfart., http://homepages.inf.ed.ac.uk/rbf/HIPR2/convolve.htm