Sunday, September 15, 2013

OpenCV configuration and installation with MS Visual Studio 2010

Hi everyone. I've decided to take a brake from routines  and do some cool stuff. Have you ever dreamed about   future with a robots? Peaceful future where people can live alongside with robots. Smart robots. So, I would  be happy to bring closer the future like this.  There is  a lot of things should be done to reach my goal. Lets start from something small. Lets start using Computer Vision. OpenCV is the best open source Computer vision library. My First tutorial will be configuring and installing  OpenCV precompiled binaries with MS Visual Studio 2010.
Before we really start, let me note few more things.  This is official website of OpenCV project. There you will find a lot of valuable infos, such as:

  • Documentation
  • Tutorials
  • OpenCV Source code
  • Technical specs
  • etc.

Required Software
  1. Visual Studio 2010
  2. OpenCV binaries
If you don't have VS 2010,  you can easily obtain one by downloading Visual Studio 2010 C++  express edition from microsoft.com.
Second step is downloading OpenCV Library. 

Once you click on requires version of OpenCV, it will redirect you on sourceforge.com, and in few seconds SaveDialog will appear on the screen.


Extract OpenCV files from archive.

Once you finished with file extracting,  you need to  upadate your system PATH variable. In my case it's "C:\OpenCV\opencv\build\x86\vc10\bin" 

OK, first part of the job already done. 
Now we should  open Visual Studio,  create new C++ project, and  configure it to use  OpenCV.

  • Run Visual Studio
  • Create new C++ project, select "Win32 Console application"
  • Set Project name (I've used "Tracker2")

Make sure  you are select "Console application" type. Project should be empty.


Great, Project created. Now we need C++  code file for our "OpenCV Hello World " application.
So, Lets adding new C++ file into the project. (I called it same as Project-Tracker2)

Now we need to configure our project to work with OpenCV libraries. 
  • Go to "Property Manager Window"
  • Select Debug folder.
  • Right click and select "Add new project property Sheet".
  • Go to VC++ Directories" - "Include Directories"


Add path "c:\OpenCV\opencv\build\include\" 


  • Go to "Library Directory"
  • Add "C:\OpenCV\opencv\build\x86\vc10\" path to OpenCV libraries

  • Go to "Linker- Input - Additional Dependencies"
  • Add "*d.lib" files from "C:\OpenCV\opencv\build\x86\vc10\lib\ folder"
  • *d- means- Debug version.
  • So in my case, I've added next set of files: 
    • opencv_calib3d246.lib
    • opencv_contrib246.lib
    • opencv_core246.lib
    • opencv_features2d246.lib
    • opencv_flann246.lib
    • opencv_gpu246.lib
    • opencv_haartraining_engine.lib
    • opencv_highgui246.lib
    • opencv_imgproc246.lib
    • opencv_legacy246.lib
    • opencv_ml246.lib
    • opencv_nonfree246.lib
    • opencv_objdetect246.lib
    • opencv_ocl246.lib
    • opencv_photo246.lib
    • opencv_stitching246.lib
    • opencv_superres246.lib
    • opencv_ts246.lib
    • opencv_video246.lib
    • opencv_videostab246.lib
That's all, my congratulations. I did it. 

Just for testing purpose, we will create small "Hello world" app using  our OpenCV configuration.
We will try to identify round object with solid colour. Not a best solution, but good enough for first time.
Open Tracker1.cpp file and paste next code:


// Tracker7.cpp

#include<opencv/cvaux.h>
#include<opencv/highgui.h>
#include<opencv/cxcore.h>

#include<stdio.h>
#include<stdlib.h>

///////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {


 CvSize size640x480 = cvSize(640, 480);   // use a 640 x 480 size for all windows, also make sure your webcam is set to 640x480 !!

 CvCapture* p_capWebcam;      // we will assign our web cam video stream to this later . . .

 IplImage* p_imgOriginal;   // pointer to an image structure, this will be the input image from webcam
 IplImage* p_imgProcessed;   // pointer to an image structure, this will be the processed image
          /* IPL is short for Intel Image Processing Library, this is the structure used in OpenCV 1.x to work with images */

 CvMemStorage* p_strStorage;   // necessary storage variable to pass into cvHoughCircles()

 CvSeq* p_seqCircles;    // pointer to an OpenCV sequence, will be returned by cvHough Circles() and will contain all circles
          // call cvGetSeqElem(p_seqCircles, i) will return a 3 element array of the ith circle (see next variable)
 
 float* p_fltXYRadius;    // pointer to a 3 element array of floats
          // [0] => x position of detected object
          // [1] => y position of detected object
          // [2] => radius of detected object

 int i;        // loop counter
 char charCheckForEscKey;   // char for checking key press (Esc exits program)

 p_capWebcam = cvCaptureFromCAM(0); // 0 => use 1st webcam, may have to change to a different number if you have multiple cameras

 if(p_capWebcam == NULL) {   // if capture was not successful . . .
  printf("error: capture is NULL \n"); // error message to standard out . . .
  getchar();        // getchar() to pause for user see message . . .
  return(-1);        // exit program
 }

           // declare 2 windows
 cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);  // original image from webcam
 cvNamedWindow("Processed", CV_WINDOW_AUTOSIZE);  // the processed image we will use for detecting circles

 p_imgProcessed = cvCreateImage(size640x480,   // 640 x 480 pixels (CvSize struct from earlier)
           IPL_DEPTH_8U,  // 8-bit color depth
           1);     // 1 channel (grayscale), if this was a color image, use 3
 cvWaitKey(2000);



 while(1) {        // for each frame . . .
   
  p_imgOriginal = cvQueryFrame(p_capWebcam);  // get frame from webcam
  
  if(p_imgOriginal == NULL) {     // if frame was not captured successfully . . .
   printf("error: frame is NULL \n");  // error message to std out
   getchar();
   break;
  }

  //cvInRangeS(p_imgOriginal,    // function input
  //     CV_RGB(175,  0,  0),   // min filtering value (if color is greater than or equal to this)
  //     CV_RGB(256,100,100),   // max filtering value (if color is less than this)
  //     p_imgProcessed);    // function output

  

  //cvInRangeS(p_imgOriginal,    // function input
  //     CV_RGB(100,  10,  20),   // min filtering value (if color is greater than or equal to this)
  //     CV_RGB(255,50,50),   // max filtering value (if color is less than this)
  //     p_imgProcessed);    // function output

  cvInRangeS(p_imgOriginal,    // function input
       CV_RGB(110,  0,  0),   // min filtering value (if color is greater than or equal to this)
       CV_RGB(255,50,50),   // max filtering value (if color is less than this)
       p_imgProcessed);    // function output

  p_strStorage = cvCreateMemStorage(0); // allocate necessary memory storage variable to pass into cvHoughCircles()

          // smooth the processed image, this will make it easier for the next function to pick out the circles
  cvSmooth(p_imgProcessed,  // function input
     p_imgProcessed,  // function output
     CV_GAUSSIAN,   // use Gaussian filter (average nearby pixels, with closest pixels weighted more)
     9,      // smoothing filter window width
     9);     // smoothing filter window height

             // fill sequential structure with all circles in processed image
  p_seqCircles = cvHoughCircles(p_imgProcessed,  // input image, nothe that this has to be grayscale (no color)
           p_strStorage,   // provide function with memory storage, makes function return a pointer to a CvSeq
           CV_HOUGH_GRADIENT, // two-pass algorithm for detecting circles, this is the only choice available
           2,     // size of image / 2 = "accumulator resolution", i.e. accum = res = size of image / 2
           p_imgProcessed->height / 4, // min distance in pixels between the centers of the detected circles
           100,      // high threshold of Canny edge detector, called by cvHoughCircles
           80,      // low threshold of Canny edge detector, called by cvHoughCircles
           4,      // min circle radius, in pixels
           400);      // max circle radius, in pixels

  for(i=0; i < p_seqCircles->total; i++) {  // for each element in sequential circles structure (i.e. for each object detected)

   p_fltXYRadius = (float*)cvGetSeqElem(p_seqCircles, i); // from the sequential structure, read the ith value into a pointer to a float

   printf("ball position x = %f, y = %f, r = %f \n", p_fltXYRadius[0],  // x position of center point of circle
                 p_fltXYRadius[1],  // y position of center point of circle
                 p_fltXYRadius[2]); // radius of circle

          // draw a small green circle at center of detected object
   cvCircle(p_imgOriginal,          // draw on the original image
      cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])),  // center point of circle
      3,             // 3 pixel radius of circle
      CV_RGB(0,255,0),         // draw pure green
      CV_FILLED);          // thickness, fill in the circle
   
          // draw a red circle around the detected object
   cvCircle(p_imgOriginal,          // draw on the original image
      cvPoint(cvRound(p_fltXYRadius[0]), cvRound(p_fltXYRadius[1])),  // center point of circle
      cvRound(p_fltXYRadius[2]),       // radius of circle in pixels
      CV_RGB(255,0,0),         // draw pure red
      3);            // thickness of circle in pixels
  } // end for

  cvShowImage("Original", p_imgOriginal);   // original image with detectec ball overlay
  cvShowImage("Processed", p_imgProcessed);  // image after processing

  cvReleaseMemStorage(&p_strStorage);    // deallocate necessary storage variable to pass into cvHoughCircles

  charCheckForEscKey = cvWaitKey(10);    // delay (in ms), and get key press, if any
  if(charCheckForEscKey == 27) break;    // if Esc key (ASCII 27) was pressed, jump out of while loop
 } // end while

 cvReleaseCapture(&p_capWebcam);     // release memory as applicable

 cvDestroyWindow("Original");
 cvDestroyWindow("Processed");

 return(0);
}

Build and run app.
As result you should get something like this:




Feel free ask any questions.

No comments:

Post a Comment