2. Basic Image Manipulation

Image Data Handling

After I installed OpenCV I wanted to get started with some image manipulations. The concept is pretty simple with Computer Vision being defined as basically “the transformation of data from a still or video camera into either a decision or a new representation” bradski. OpenCV provides a certain procedure for loading the data of the images. So the first thing I did was get comfortable with some of the basic image handling protocol.

# include "stdio.h"
# include "highgui.h"

int main( int argc, char** argv ) {
  IplImage* img = 0;

  if( argc < 2 ) {
    printf( "Usage: Accepts one image as argument\n" );
    exit( EXIT_SUCCESS );
  }

  img = cvLoadImage( argv[1] );

  if( !img ) {
    printf( "Error loading image file %s\n", argv[1]);
    exit( EXIT_SUCCESS );
  }

  cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE )
  cvMoveWindow( "Example1", 100, 100 );
  cvShowImage( "Example1", img );
  cvWaitKey( 0 );
  cvReleaseImage( &img );
  cvDestroyWindow( "Example1" );
  return EXIT_SUCCESS;
  }

Get the code from my Git Repository
If you need help with Git, follow this quick introduction – Getting Started With Git

It’s pretty clear from here why OpenCV is so user friendly, it’s interface is notably intuitive. My impression of the highgui.h header thus far leads me to believe it is host to the display functions which post all of the image data, as it’s name “highgui” suggests.

 IplImage* img = 0;

IplImage is a data structure, it is used to store image data. It got it’s name from it’s home, Intel, and it stands for Image Processing Library (IPL) Image. Here’s a taste of what it looks like.

typedef struct _IplImage {
    int  nSize;         /* sizeof(IplImage) */
    int  ID;            /* version (=0) */
    int  nChannels;     /* Most of OpenCV functions support
                           1,2,3 or 4 channels */
    int  alphaChannel;  /* Ignored by OpenCV */
    int  depth;         /* Pixel depth in bits: IPL_DEPTH_8U,
                           IPL_DEPTH_8S, IPL_DEPTH_16S,
                           IPL_DEPTH_32S, IPL_DEPTH_32F
                           and IPL_DEPTH_64F are supported */
    char colorModel[4]; /* Ignored by OpenCV */
    char channelSeq[4]; /* Ditto */
    int  dataOrder;     /* 0 - interleaved color channels,
                           1 - separate color channels.
                           cvCreateImage can only create
                           interleaved images */
    int  origin;        /* 0 - top-left origin,
                           1 - bottom-left origin
                           (Windows bitmaps style) */
    int  align;         /* Alignment of image rows (4 or 8).
                           OpenCV ignores it and uses
                           widthStep instead */
    int  width;         /* Image width in pixels */
    int  height;        /* Image height in pixels */
    struct _IplROI *roi;/* Image ROI. If NULL, the whole
                               image is selected */
    struct _IplImage *maskROI;     /* Must be NULL */
    void  *imageId;                /* "           " */
    struct _IplTileInfo *tileInfo; /* "           " */
    int  imageSize;     /* Image data size in bytes
                           (==image->height*image->widthStep
                           in case of interleaved data)*/
    char *imageData;    /* Pointer to aligned image data */
    int  widthStep;     /* Size of aligned image row in bytes */
    int  BorderMode[4]; /* Ignored by OpenCV */
    int  BorderConst[4];/* Ditto*/
    char *imageDataOrigin;/* Pointer to very origin of image data
                            (not necessarily aligned) -
                             needed for correct deallocation */
} IplImage; 

Most of it is pretty intuitive, but I’m sure I’ll learn more about some of it’s more obscure data members soon. A problem I faced next was; given an image, how do I extrapolate all of that data? That’s where the next function came in.

IplImage* cvLoadImage(const char* filename, int iscolor);
filename - name of the file to be loaded

iscolor - Specifies colorness of the loaded image:
    If >0, the loaded image is forced to be color 3-channel image;
    If 0, the loaded image is forced to be grayscale;
    If <0 or omitted, the loaded image will be loaded as is
    with the number of channels depending on the file.

This is an impressive function. It parses through it's argument, interprets all the information, and fills in that IplImage structure with all the data and finally returning a pointer to the IplImage. It allocates the appropriate memory size and has support for the following formats

  • Windows bitmaps - BMP, DIB
  • JPEG files - JPEG, JPG, JPE
  • Portable Network Graphics - PNG
  • Portable image format - PBM, PGM, PPM
  • Sun rasters - SR, RAS
  • TIFF files - TIFF, TIF

Notice however that I assign it to img. img is a pointer to the IplImage. That data structure is large and bulky, so passing it around by value would be costly in overhead.

Alright, so I've got an image loaded into my program here, how do I output it? What I learned next is that have you create your own windows for data output.

 int cvNamedWindow( const char* name, int flags );
name - Name of the window which is used as window identifier
       and appears in the window caption.

flags - Flags of the window. Currently the only supported flag
        is CV_WINDOW_AUTOSIZE. If it is set, window size is
        automatically adjusted to fit the displayed image while
        user can not change the window size manually.

The first parameter, the character array, is the name I used to refer to this exact window throughout the rest of the program, and the second is the windows size. There is something interesting to note here, the window variable name "Example1" is also the name that appears on the window after it is displayed... I haven't found any workarounds for this yet. I'm not sure if there is a need, but what if you want to make multiple windows with the same name, but need to refer to them independently throughout the program? Please let me know if you find a solution.

Now I noticed when the window appeared it was always in the corner... mathnathan doesn't like this... So a simple little move window function served me great here.

 void cvMoveWindow( const char* name, int x, int y );
name - Name of the window to be relocated.

x - New x coordinate of top-left corner

y - New y coordinate of top-left corner

Remember, "Example1" is now the string literal I had to use to refer to that window. The next two parameters are ints. They simply refer to the (x, y) coordinates where the window's upper left corner will be.

I got an image loaded and a window up, so then I needed to put the image in the window. OpenCV provides a function which displays an IplImage* pointer in an existing window, in my case "Example1".

 void cvShowImage( const char* name, const CvArr* image );
name - The name of the window.

image - The image to be shown.

Now the image is displayed in the window I created. Hooray. Note, if the window was set with CV_WINDOW_AUTOSIZE flag, then the window will resize to fit the image, otherwise the image will be resized to fit in the window.

To make the window go away I simply waited for any key to be pressed.

 int cvWaitKey( int delay=0 );
delay - The delay in milliseconds.

When given a parameter of less than or equal to 0, this function simply pauses the program and waits for a key to be pressed. Any positive integer will pause the program for that many milliseconds. This is the only function within highgui for event handling.

Being the good little C programmer that I am, I freed the allocated memory used to hold the image.

 void  cvReleaseImage( IplImage** image );
image - The IplImage structure you wish to be released.

Be sure to take note that this function expects a pointer to the IplImage*. So you should submit the address using the reference operator ' & '.

Lastly I destroyed the window.

 void cvDestroyWindow( const char* name );
name - The name of the window you wish to destroy.

I'm quite fond of this function, they really gave it a great name. Programming suddenly got way more fun!

Compiling

The program is ready to go, but building it wasn't as easy a gcc myprogram.c it required linking to the OpenCV libraries. This can be a nuisance, however OpenCV makes linking to their stuff a breeze when using CMake. If you're new to CMake and would like a quick introduction, check out my Getting Started with CMake tutorial. When I built OpenCV from source in the previous post, it produced an OpenCVConfig.cmake file (making it easy!) for me to put into my CMakeLists.txt file.

cmake_minimum_required(VERSION 2.6)
 project(examples)

 include($ENV{OpenCV_DIR}/OpenCVConfig.cmake)
 include_directories(${OPENCV_INCLUDE_DIR})

 add_executable(example1 example2-1.cpp)

 target_link_libraries(example1 ${OpenCV_LIBS})

Plain and simply that's all there was too it. I saved that as my CMakeLists.txt file, moved into the build directory, ran cmake, then make, and tested my program with some sample pictures. SUCCESS!

Applying a Gaussian Transformation

Using my new found image handling skills I attempted to smooth an image using cvSmooth(). There are a few minor additions to the previous program.

# include "stdio.h"
# include "highgui.h"
# include "cv.h"

int main( int argc, char** argv ) {
	IplImage* img = 0;
	IplImage* out = 0;

	if( argc < 2 ) {
		printf( "Usage: Accepts one image as argument\n" );
	    exit( EXIT_SUCCESS );
	}

	img = cvLoadImage( argv[1] );

	if( !img ) {
		printf( "Error loading image file %s\n", argv[1]);
	    exit( EXIT_SUCCESS );
	}

	out = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );

	cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
	cvMoveWindow( "Example1", 100, 100 );
	cvNamedWindow( "Output", CV_WINDOW_AUTOSIZE );
	cvMoveWindow( "Output", 300, 100 );
	cvShowImage( "Example1", img );
	cvSmooth( img, out, CV_GAUSSIAN, 3, 3 );
	cvShowImage( "Output", out );
	cvWaitKey( 0 );
	cvReleaseImage( &img );
	cvReleaseImage( &out );
	cvDestroyWindow( "Example1" );
	cvDestroyWindow( "Output" );
	return EXIT_SUCCESS;
}

Get the code from my Git Repository
If you need help with Git, follow my quick introduction - Getting Started With Git

First off, I added cv.h into the mix here. This is where I found all of my Computer Vision toys. To be able to see the before and after I created another pointer to an IplImage* data structure to store the transformed data which I called, out. I learned another method for creating an image without using the cvLoadImage() function, which I garnished here.

 IplImage*  cvCreateImage( CvSize size, int depth, int channels );
size - The images width and height

depth - Bit depth of image elements. Can be one of:
        IPL_DEPTH_8U - unsigned 8-bit integers
        IPL_DEPTH_8S - signed 8-bit integers
        IPL_DEPTH_16U - unsigned 16-bit integers
        IPL_DEPTH_16S - signed 16-bit integers
        IPL_DEPTH_32S - signed 32-bit integers
        IPL_DEPTH_32F - single precision floating-point numbers
        IPL_DEPTH_64F - double precision floating-point numbers

channels - Number of channels per element, pixel, in the image.

I got the size automatically using cvGetSize.

CvSize cvGetSize( const CvArr* arr );
arr - The array header

The function cvGetSize returns number of rows (CvSize::height) and number of columns (CvSize::width) of the input matrix or image. If I were to have the *roi pointer pointing to a subset of the original image, the size of ROI (Region Of Interest) is returned.

The next parameter is an int, and is the bit depth of the image elements. Lastly it wants the number of channels for the image. That is the number of channels per element (pixel), which can be 1, 2, 3 or 4. The channels are interleaved, for example the usual data layout of a color image is: b0 g0 r0 b1 g1 r1... Although in general IPL image format can store non-interleaved images as well and some of OpenCV can process it, cvCreateImage() creates interleaved images only.... How sad... :(

And finally here is the transformation.

void cvSmooth( const CvArr* src,
               CvArr* dst,
               int smoothtype=CV_GAUSSIAN,
               int param1=3,
               int param2=0,
               double param3=0 );
src - The source image, to be smoothed.
dst - The destination image, where to save the image.
smoothtype - Smoothing algorithm to be employed
  CV_BLUR_NO_SCALE (simple blur with no scaling) - summation over a
       pixel param1×param2 neighborhood. If the neighborhood size may
       vary, one may precompute integral image with cvIntegral function.
  CV_BLUR (simple blur) - summation over a pixel param1×param2
       neighborhood with subsequent scaling by 1/(param1•param2).
  CV_GAUSSIAN (gaussian blur) - convolving image with param1×param2
       Gaussian kernel.
  CV_MEDIAN (median blur) - finding median of param1×param1
       neighborhood (i.e. the neighborhood is square).
  CV_BILATERAL (bilateral filter) - applying bilateral 3x3 filtering
       with color sigma=param1 and space sigma=param2.
param1 - The first parameter of smoothing operation.
param2 - The second parameter of smoothing operation. In case
         of simple scaled/non-scaled and Gaussian blur if param2
         is zero, it is set to param1.
param3 - n case of Gaussian parameter this parameter may specify
         Gaussian sigma (standard deviation). If it is zero, it is
         calculated from the kernel size:

              sigma = (n/2 - 1)*0.3 + 0.8
                      n=param1 for horizontal kernel
                      n=param2 for vertical kernel.

         Using standard sigma for small kernels (3×3 to 7×7) gives
         better speed. If param3 is not zero, while param1 and param2
         are zeros, the kernel size is calculated from the sigma.

Your source image and destination image are self explanatory, the next parameter is your smoothing algorithm and
the other 3 parameters depend on the smooth type, here is another reference to the various smooth types. brasdki

I then displayed the output image in the "Output" window and was a good little C programmer and cleaned up after myself.

So those are the changes in the new program. It takes an image as input, makes a copy, creates two windows, displays one image, runs the other through a smoothing filter, then displays that one aswell! Easy stuff. Here is the output I received after running a picture of myself through the filter. COOL!!

References

I'm studying from Gary Bradski's Learning OpenCV

Posted in OpenCV Journey | 4 Comments

Performances

Here are a few performances I’ve done…

The Ocean Etude by Chopin

Fantasie Impromtu by Chopin

Final Fantasy VII Main Theme by Nobuo Uematsu

Posted in Performances | 3 Comments

Somethings need to be Experienced

This whole blogging thing is relatively new for me. I’m more of the proud, quiet type… Which led me to look at blogs as a sort of online diary. Why would a strong, proud man like myself need a diary?! Wrong. No matter how much I read, watch, study, discuss, or just ponder on different experiences, once I’ve experienced them I can rarely say that I anticipated them affecting me in the manners they did. Blogging is certainly no exception. Before beginning my first blog Getting Started with Git I told myself that I had nothing to blog about. Then my good friend Ian Johnson told me to just blog about what I do. I’m a mathematics tutor at Florida State University, and I’d be hard pressed to tell you something I enjoy more than helping others. So I thought I can just write helpful blogs about things I do. After my first post I had over 400 views and 7 subscribers. Knowing I can help so many people with just one article is a difficult feeling to describe. So if you’re like me and you think you’ve got things figured out and you don’t need to try this or that because you know all about it, I’m here to tell you, you probably don’t. Somethings just need to be experienced.

Posted in Nonrandom Thoughts | 1 Comment

Getting Started with CMake

CMake is a sophisticated, cross-platform, open-source build system developed by Kitware in 2001. CMake is the name used to refer to the entire family of tools: CMake, CTest, CDash, and CPack. These tools are used to…

  • CMake – An intelligent build system used to build simple, to very elaborate projects.
  • CTest, CDash – These are used to test and debug your projects.
  • CPack – A packaging tool that finalizes your project for distribution.

CMake simplifies the potentially monstrous build system into a few easy to write files. It is targeted towards C and C++ and is usable with various compiler/OS support. At the risk of over simplifying things, CMake looks at your project and sees a ‘file system’. You tell it where all your files are at, what you want it to do with them, and it does it. In a nut shell it’s really that easy. More elaborately however, CMake is wonderful for it’s design to support complex directory hierarchies. When you use CMake it will locate include files, libraries, executables, other optional build directives, then link everything for you. No more messy Makefiles.

CMake basically requires one thing, a CMakeLists.txt file. We’ll start with a simple example.

Here is a very simple program I wrote in C called fib.c which lists the Fibonacci Sequence up to a given value. That value is passed to the main function when it is called.

# include "stdio.h"
# include "stdlib.h"

int main( int argc, char** argv) {
	if ( argc > 2 || argc == 1 ) {
		printf("Fibonacci takes one postitive integer greater\
                         than two as it's argument\n");
		return EXIT_SUCCESS;
	}
	int a, b;
	a = 0;
	b = 1;
	printf( "%d", b );
	for( int i = 0; i + a <= atof( argv[1] ); b = i ) {
		i = a + b;
		a = b;
		printf( ", %d", i );
	}
	printf("\n");
	return EXIT_SUCCESS;
}

So let's say you'd like to compile this and give it a go. We could just compile it directly with one line...

        gcc -std=c99 fib.c

Notice we need a -std flag. We set it to c99 because loop initial declarations are only allowed in c99 mode. Alternatively you could just change that in your gcc compiler to use by default. Another option would be to use a Makefile..... Nah... Or we could use CMake. I declare the winner to be CMake.

Download

Let's make sure we have CMake on our systems, I'm using Ubuntu 10.04.

      sudo apt-get install cmake cmake-curses-gui

The cmake-curses-gui provides a somewhat-helpful-gui (a lot like the Windows version) if that's what you're into. There is pretty much no setup required here, we just need to make our CMakeLists.txt file in the main directory of our project, then run CMake from our build folder.

Setup Project

fib is the name of the folder/main directory, where the fib.c file is, as well as the soon to be disclosed CMakeLists.txt file. It's a good programming practice to do all of your builds in a build folder. Not doing so clutters your project folder with a bunch of confusing files. You'll see this after we run cmake. So let's set this up.

       mkdir /where/you/want/your/project/fib
        cd fib
        mkdir build

So this is what your project file system looks like.

        fib
       /
    build

Now use your favorite text editor (should be vim ;-) ) to create your own fib.c file, as well as a CMakeLists.txt file in your fib directory.

CMake Syntax

Here is the CMakeLists.txt file used to compile the fib.c program.

#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(fibonacci)

#Sends the -std=c99 flag to the gcc compiler
add_definitions(-std=c99)
#This tells CMake to fib.c and name it fibonacci
add_executable(fibonacci fib.c)

The basic syntax of CMake consists of three things; comments, commands, and white spaces. A comment is made by beginning a line with the '#' character

       #Chocolate Curry is my favorite

And a command is constructed with the command name, opening parenthesis, whitespace separated arguments, and a closing parenthesis.

        command(arg1 agr2 agr3 ...)

The basic data type in CMake is a string. You can even create lists of strings using the set command.

        set(VAR a b c)

This creates variable VAR which is composed of three strings a, b, and c. Referencing a variable should look familiar to most of you. ${VAR} is the correct syntax to refer to the list of strings VAR at a later time. For instance these three command calls are the same.

        command(${VAR})
        command(a b c)
        command(a;b;c)

You can also separate strings with semicolons. Placing quotations around anything will allow it to be read as a string. For instance, the following command

        command("${VAR}")

will read in "${VAR}" not "a b c". CMake syntax also provides some useful flow control options. First is the if else logic structure.

        # some_command will be called if the variable's value is not:
        # empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND.
        if(var)
           some_command(...)
        endif(var) 

They also provide looping commands, foreach and while.

        set(VAR a b c)
        # loop over a, b,c with the variable f
        foreach(f ${VAR})
            message(${f})
        endforeach(f) 

Simple function and macro constructions are also supported.

        # define a macro hello
        macro(hello MESSAGE)
            message(${MESSAGE})
        endmacro(hello)
        # call the macro with the string "hello world"
        hello("hello world")
        # define a function hello
        function(hello MESSAGE)
            message(${MESSAGE})
        endfunction(hello)

Lastly CMake also supports all of your common Regular Expressions

  • ^ Matches at beginning of a line or string
  • $ Matches at end of a line or string
  • . Matches any single character other than a newline
  • [ ] Matches any character(s) inside the brackets
  • [^ ] Matches any character(s) not inside the brackets
  • [-] Matches any character in range on either side of a dash
  • * Matches preceding pattern zero or more times
  • + Matches preceding pattern one or more times
  • ? Matches preceding pattern zero or once only
  • () Saves a matched expression and uses it in a later replacement

For a more detailed description of CMake syntax go here.

Building The Project

So back to the CMakeLists.txt file to build our example

#Specify the version being used as well as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(fibonacci)

#Sends the -std=c99 flag to the gcc compiler
add_definitions(-std=c99)
#This tells CMake to fib.c and name it fibonacci
add_executable(fibonacci fib.c)

CMake is case insensitive, thus it does not distinguish between command() and COMMAND(). I prefer all lowercase because it is faster to type. so here is the breakdown of the CMakeLists.txt

  • cmake_minimum_required(VERSION 2.6) - This signifies the version of CMake that you're using and allows you to pass the language into documentation.
  • project(fibonacci) - This allows you to name your project and you can later on refer to the project as a whole using this string.
  • add_definitions(-std=c99) - This command sends arguments to the compiler, which CMake will choose for you unless otherwise told so.
  • add_executable(fibonacci fib.c) - This does the magic. Here CMake takes fib.c, and using all of the libraries it was handed (none in this simple example) compiles it into the output file named fibonacci.

Beautiful, we're almost done. Now we want to compile things. Once run for the first time CMake will configure itself to your system, and place the binaries (your output files) into the directory you called it from. This is where we cd into the build folder, and run

        cmake ..

The ' .. ' argument is the same as the one used in BASH, it tells CMake to execute from the CMakeLists.txt in the previous directory. This call just produced your Makefile, so let's finish it off with the last command.

        make

Now if you ls into the build folder you'll see all kinds of stuff.

  • CMakeCache.txt - Think of this as a configuration file. It has many advanced settings to optimize the build process for large projects. (Such as building the Linux Kernel! ;-) )
  • CMakeFiles (directory) - This has a lot of the stuff CMake uses under the hood to build your project. I recommend you poke around through there and take a look at stuff...
  • cmake_install.cmake - Your install file. We didn't use one in this program.
  • fibonacci - Hooray it's our program!
  • Makefile - remember your last command 'make'? This is the Makefile produced by Cmake, this is really what it all came down to.

You've Now built a program using CMake. If you'd like to see a more sophisticated example of Cmake look for my series on OpenCV under the Computer Vision tab. I use Cmake there to link all of the OpenCV libraries, and even make some of my own.

Strengthen Your CMake Muscles Here

  • CMake Documentaion is a great source for basic tutorials and examples.
  • The Wiki Page has a lot of community support and is frequently updated. Check it out for learning cool tricks and shortcuts in CMake.
Posted in CMake | 45 Comments

How NOT to be a hacker

Too often I come across examples like this. The difference between a hacker and a cracker is not what they do, but their attitude. I’m pretty sure this guy didn’t know about Matroska media containers as a fetus, which means he had to learn about it one day. Everyone else does too. Hackers are productive and respectable, this is an example of how NOT to behave on the internet.

Posted in Nonrandom Thoughts | 1 Comment

Getting Started with Git

Git is a very powerful DVCS ( Distributed Version Control System ). It is a program that allows you to back up and share all of your code, while providing an efficient interface for collaboration with other programmers. I think social coding and open source is an excellent practice, so I want to promote more awareness of Git and give a short tutorial of how to get started.

Download

The first thing you want to do is download all the git components.

    sudo apt-get install git-core git-gui git-doc

This next step may be a little difficult for beginners, so I’ll document it well. If you understand key-value pairing and public key authentication, you can skim through this and just get the commands. If you already have a key then skip to the next section.

Generate A Public/Private Key

To generate a key we’ll use a built in keygen to create an RSA (Rivest, Shamir, Adleman) key-value pair. At the risk of over simplifying things, RSA is a form of encryption that uses a hash table to generate a value from a given key. Basically you give it a special key, it runs it through the hash function and spits out your value. Hashing is a very powerful technique that has a wide range of uses, here however we use it to create a public/private key which is often used as a form of online identity verification/signature.

    ssh-keygen -t rsa -C "mathnathan@gmail.com"

the ‘ -t ‘ flag specifies which type of key to create (we’re using the RSA hash function) then, the ‘ -C ‘ flag allows us to append a comment, here it’s your email. It will ask you where to save the key, I recommend saving it to the default location (Press Enter). Then you are to enter your passphrase, this should be a strong passphrase that only you know. It then saves your identification in the aforementioned directory.

Register Your Key With Github

We need to copy our key from the newly created id_rsa.pub file. We can use xclip to automatically copy everything in the file to the clipboard.

    sudo apt-get install xclip
    cat ~./ssh/id_rsa.pub | xclip -sel clip

cat means to concatenate. ~./ssh/id_rsa.pub is the file extension to your public key. | xclip -sel clip funnels the output from cat into xclip where it copies it to the clipboard.

Now we create an account at github.

  • Click on the Sign up Now button, and select the free account at the top.
  • Do the typical account registration dance until you have an account.
  • Click on the Account Settings link from the top tool bar.
  • Select SSH Public Keys from the links on the left.
  • Choose Add another public key

Leaving the title blank will use your email let’s do that, then simply left-click in the key text box and select paste. Then Click Add key

Customize Your Git Environment

Here we’re going to set a few environment variables to make your Git experience smoother. Each variable has three scopes.

  • –system – This is a system wide variable change.
  • –global – This is a user wide variable chane.
  • Then there is a .gitconfig file in each project directory

Each subsequent scope overrides the pervious. e.g. Changing the GIT_COMMITTER_EMAIL variable in the –global scope overrides the GIT_COMMITTER_EMAIL variable in the –system scope. So let’s set up your variables.

    git config --global user.name "mathnathan"
    git config --global user.email "mathnathan@gmail.com"

There are a few things Git does without being connected through SSH, so you should set up your account token to allow Git that freedom.

  • Click on Account Settings
  • Click on Account Admin
  • Copy your API Token from there

and paste it here…

    git config --global github.user mathnathan
    git config --global github.token 0123456789abcdef0123456789abcdef

Create a Repository and Get Coding

Now you just need to create a repository and begin coding! First logon to your github account.

  • Click on the Dashboard link from the tool bar at the top.
  • Click on the New Repository button
  • Choose a project-name
  • Keep the description short and sweet.
  • Now click the Create Repository button.

Now cd into the directory where you plan to have your project files, then running init will establish a git database which will keep track of your progress and allow you to share your code, and join the social coding network!

    cd /into/your/project/directory
    git init

There are a few basic git commands you should get comfortable with…

    git add filename
    git commit -m "this is what I've done"
    git remote add origin git@github.com:mathnathan/project-name.git
    git push origin master
  • The add command puts your filename in the staging area ready to be committed. That means you’re finished editing it for now and are ready to work on another.
  • The commit -m “this is what I’ve done” saves your changes with a comment about what you’ve done to your local git database
  • The git remote add origin git@github.com:mathnathan/project-name.git tells git where it is sending your local database when you use the push command.
  • Once you’re finished editing for the day, or you want to back everything up, you can push your local data base which is at the master branch in your git file system to your origin which should now be git@github.com:mathnathan/project-name.git

Strengthen Your Git Muscles Here

  • Help at Github – This is a good place to come for trouble shooting, checking FAQS, or asking the github community for help.
  • Pro Git – This is the best resource for learning everything Git.

Contact me on github and let me know how this tutorial worked for you! Happy Coding.

Posted in Git | 1 Comment

1. Compiling OpenCV

Alright so I have a hard-on for Computer Vision and Machine Learning, and I’m pumped to be getting into it. I’m going to document my experiences learning OpenCV here, and eventually start some cool projects. Please help me out, and provide some feedback!

Download

*NOTE: CMake is now the only method of building OpenCV SVN snapshots.*

*NOTE: Gijs Molenaar has now built OpenCV 2.1 packages for Ubuntu, bless his sweet little soul.*

    $ sudo add-apt-repository ppa:gijzelaar/opencv2
    $ sudo apt-get update
    $ sudo apt-get install opencv
    $ sudo apt-get install libopencv-dev
    $ sudo apt-get install python-opencv
    $ sudo apt-get install opencv-doc

Check here for more documentation on installing the Ubuntu packages Ubuntu Installation.
If you want to learn CMake, check my Getting Started with CMake tutorial.

There are a bunch of dependencies that I needed for reading and writing different image and movie formats. I got them all in one fell swoop.

    $ sudo apt-get install build-essential libgtk2.0-dev
      libavcodec-dev libavformat-dev libjpeg62-dev libtiff4-dev
      cmake libswscale-dev libjasper-dev

There was one of two things I could have done.

  1. Download the stable up to date version of OpenCV from Source Forge.
  2. Or my choice, get the cutting edge magic from Willow Garage’s SVN. (I’m so gonna work there one day…)
    $ sudo apt-get install subversion
    $ cd ~/where/you/want/opencv/installed
    $ svn co https://code.ros.org/svn/opencv/trunk

Installation

So next I just hopped into the opencv folder that I downloaded and as stated above used CMake to build it

    $ cd opencv
    $ cmake .

The ‘ . ‘ arguement sent into cmake told it to look for the CMakeLists.txt file in the current directory. This generated the Makefile for me, so the last step I did was to simply build it.

    $ make

Next I had to configure the library, so I opened the config file with the following command

    $ sudo vim /etc/ld.so.conf.d/opencv.conf

Since I installed it on Linux I had to add the following line to the bottom of the file, which was empty for me… Not a problem I guess.

    /usr/local/lib

Then since I told it where to look for everything at and all the files had been built, I just configured it with the following command

    $ sudo ldconfig

Lastly was a little icing on the cake, I put the extension of Intel’s performance primitives package (IPP) into my .bashrc file. I don’t have the optimization primitives by the way, I just thought it’d be nice to have this here in case I somehow become an OpenCV wizard and need them.

    $ sudo vim /etc/bash.bashrc

Then add this at the very bottom of the file…

    /PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
    export PKG_CONFIG_PATH

HUZZAH! That’s that. Then I just reset my computer and got going on some OpenCV examples! Yay!

Now check the next section on image handling – 2. Basic Image Manipulation.

References

I’m studying from Gary Bradski’s Learning OpenCV

Posted in OpenCV Journey | 10 Comments