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


Loading XML data

March 11, 2008

Let’s begin by creating an XML document.  Here the information I’ll need for a game I’m building:

  • Chord name
  • Keys that make up the chord

The XML information will appear as follows:

<muse>
<chord label="C chord">
<key data="c.mp3"></key>
</chord>
<chord label="D chord">
<key data="d.mp3"></key>
</chord>
</muse>

You can use any text editor to create this document, including Microsoft’s Notepad and the Mac OS X’s TextEdit.  The next thing we do is open Flash to do the Actionscripting to read the XML document we created.  The first part of the ActionScript involves declaring an XML object:

var xml:XML = new XML();

We now have an empty XML container object in which we will place our XML data.  The next step involves creating a loader to load our XML data from an XML document somewhere in our folder.  I’m assuming you created the XML document in the same folder you have saved your Flash file.

var xmlLoader:URLLoader = new URLLoader();

We’ve now just created an empty loader object that we will use in just a minute.  Now we begin the request to call up our XML document which I’ve called “chords.xml”.

xmlLoader.load(new URLRequest("chords.xml"));

Before we can use any of the data inside the XML document, we must wait till it has loaded completely.  So we’ll add an event listener to our loader.

xmlLoader.addEventListener(Event.COMPLETE, loadCompleteHandler);

After that we’ll need to write up our function loadCompleteHandler which will be called when the event COMPLETE gets dispatched.

function loadCompleteHandler (evt:Event):void
{
    xml = XML(evt.target.data);
}

Once it is called, this function will take the data from chords.xml and create an XML object out of it and store the resulting data in our variable xml.  If you compile your Flash file, you won’t see anything on the screen.  Let’s add a dynamic textfield.  Make sure that you set the selectable property off.  Give this textfield an instance name: title.  Now we’ll add a few more lines of code to our previous function loadCompleteHandler.

function loadCompleteHandler (evt:Event):void
{
  xml = XML(evt.target.data);
  title.text = xml.chord[0].@label;
}

The last line inside of the function accesses the top-most chord child of the XML document and reads off the attribute called “label”.  Compile the Flash file and you should get the following output.

Finished Product!