Wednesday, February 15, 2012

OpenCV Stereo Calibration

Whenever you play with stereo computation, Stereo Calibration plays a crucial step. In this post, I will explain what is Stereo Calibration and what are steps to follow for performing Stereo calibration using  OpenCV.

Why do I need to perform Stereo Calibration?

Stereo cameras can be mainly used in robotics. Calibration of camera is vital to overcome distortions introduced by lens and other misalignment, so that it can be used for further processing. OpenCV makes use of algorithm to perform this stereo camera calibration using standard test images like chessboard or dots. It computes extrinsic parameters (rotational and translational matrix of stereo camera) and intrinsic parameters (focal length, baseline and optic center).


What You need for Stereo Calibration?
  1. Stereo Camera, it may be your custom made two USB camera or two web cams or from professional stereo camera manufacturer.
  2. Print out of chessboard. You can get chessboard from [OpenCV Install Dir]\doc\pattern.png. Don't worry about clarity or resolution problem. It will be of higher resolution and no worries:-)
  3. Once you take print out, paste it on rigid surface. You can use acrylic sheet or card board. 
How to capture chessboard Images for Stereo Calibration?

If you don't have any application to capture chessboard images simultaneously from left and right camera, here is code you can put and compile.

#include "stdafx.h"

//OpenCV specific Headers
#include "cv.h"
#include "highgui.h"

int main()
{
 IplImage *frameL = 0;
 IplImage *frameR = 0;

 CvCapture *captureL = 0;
 CvCapture *captureR = 0;

 int key = 0;
 int iFileName = 0;
 char FileName[MAX_PATH] = "";

 //Initialize left and right camera
 captureL = cvCaptureFromCAM(0);
 captureR = cvCaptureFromCAM(1);

 //Always check for valid frame capture.
 if (!(captureL && captureR))
 {
  printf("\nCannot open initialize webcam!\n" );
  
  //Release CAM Handle.
  cvReleaseCapture(&captureL);
  cvReleaseCapture(&captureR);
  return 0;
 }

 printf("\nPress 's' to capturing image pairs.\nPress 'q' to quit application\n");

 while( key != 'q' ) 
 {
  //Get a frame
  frameL = cvQueryFrame(captureL);
  frameR = cvQueryFrame(captureR);

  //Check for frames
  if(!(frameL && frameR))
   break;

  //Display current frame
  cvShowImage("Left", frameL);
  cvShowImage("Right", frameR);

  //Exit if user press 'q', and save frame if pressed 's'
  key = cvWaitKey(1);


  if(key == 's')
  {
   //Save Left CAM Image.
   sprintf(FileName, "Left%d.jpg",iFileName);
   cvSaveImage(FileName, frameL);

   //Save Right CAM Image.
   sprintf(FileName, "Right%d.jpg",iFileName);
   cvSaveImage(FileName, frameR);

   //Lets update in console on how many images been captured till now.
   printf("\n %d Pairs Captured", iFileName+1);
   iFileName++;
  }
 }

 //Always perform cleanup.
 cvReleaseCapture(&captureL);
 cvReleaseCapture(&captureR);
 return 0;
}

Before compiling this code, dont forget to add OpenCV dependency libraries to Visual Studio project properties. Check how to add opencv dependency library post to know how to do this. The above code will let you to capture and save images from left and right camera in your working directory. Once completed capturing with required number of chessboard images, next steps is to perform stereo calibration. The below image is screenshot of the above code.



How to get source for OpenCV Stereo calibration?

Source code for performing OpenCV Stereo calibration can be found in [OpenCV Install Dir]\samples\cpp\stereo_Calib.cpp. Following are inputs needed for performing stereo calibration using this application.

  1. Number of horizontal corners.
  2. Number if vertical corners.
  3. Chessboard square size in cm.
For chessboard given in OpenCV documents,
number of horizontal corners = 9
number of vertical corners = 6.
Square size depends on paper on which size paper you are taking print out. For A4 size paper, square size will be of ~2.7cm and for A3 size paper it will be ~5.5cm. Its better for you to measure using ruler before providing input for calibration. 

Once stereo calibration is completed, it will save bunch of stereo calibration results as either xml or yml based on what you coded. Stereo Calibration results can be used for remapping and distance computation.
Remapping is used for stereo rectification, where curvature effect due to lens will be rectified. I will tell you on how to perform stereo correspondence to find disparity map of stereo images in my next post:-) Keep following to be updated.

Saturday, October 8, 2011

Circle Detection using OpenCV

Circle detection is an algorithm that detects any number of circles in a given image. OpenCV provides an efficient algorithm that makes use of Hough Transform. This article provides steps and information on how OpenCV detects circle and how to optimize Hough Transform parameters for better circle detection.

You Need
  1. Plain, less textured (non-textured preferred) background.
  2. Test object (Penny or Tennis Ball or simple bottle cap).
Code Snippet
Following is a code snippet that performs circle detection. Here frame is of IplImage that is captured from USB camera.

Here comes steps to be done for better circle detection.
  • Input image should be of gray scale only. Use cvCvtColor to convert color scaled image to gray scale.
//Process Frame for circle detection
cvCvtColor(frame, gray, CV_BGR2GRAY);
  • Perform Guassian smoothing using cvSmooth function with filter size as 9x9 to remove noises or any sharp edges. Filter size should be of odd number.
//Perform Gaussian smoothing to reduce sharp edges and noise.
cvSmooth(gray, gray, CV_GAUSSIAN, 9, 9);
  • Detect circle using cvHoughCircles function by passing gray scale input image. Syntax of cvHoughCircles is given as:
CvSeq* cvHoughCircles(CvArr* image, CvMemStorage* circleStorage, int method, double dp, double minDist, double param1=100,  double param2=100, int minRadius=0, int maxRadius=0 )
For parameters explanation, check out here.

//Detect circles in left frame.
circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 2, 20, 100, 155, 20, 300); 
  • cvHoughCircles returns number of detected circles.
  • Next step is to draw detected circle using cvCircle function. In above code snippet, l[0],l[1] defines x,y coordinate of detected circle centre. l[2] defines radius of detected circle.
for(i = 0; (circles-> total)  >= 2 ? i  < 1 : i < circles->total; i++)
{
l = (float*)cvGetSeqElem(circles, i);
//Draw detected Circle border.
cvCircle(frame, cvPoint(cvRound(l[0]),cvRound(l[1])), cvRound(l[2]), CV_RGB(255,0,0), 3, 8, 0 );
}

Tuning cvHoughCircles
With improper tuning of Hough Transform parameter, either more number of circles are drawn or none of circles are detected. So you have to wisely tune parameters for better result.

- minDist parameter defines minimum distance between circles that has to be detected. If this is too large, circles are '''missed'''. If small, more number of unwanted circles are drawn.
- param1 should be 3/4th lesser than param2. Else no circles will be detected.
- minRadius defines minimum radius of circles to be detected. This can be zero for non-textured background.
- maxRadius defines maximum radius of circle to detect.

By proper tuning of these parameters, objects like coins, ball can be detected well. The main drawback and time consuming part is trial and error of tuning Hough Transform parameters and if improper values are choosen, this transform detects irrelevant non circled area. But once properly tuned, you can play with it to do any operation like depth calculation of object from camera.


Above image shows coins being detected using Hough Transform. Your comments are welcomed:-)  Have Fun!!!

Friday, October 7, 2011

How to Install OpenCV on Windows and Use with Visual Studio 8 2005

Hi all, this section is starter for OpenCV (Computer Vision). It provides steps, procedure and gives idea on how to setup OpenCV 2.3v and build for windows using CMake 2.8 and Visual Studio 8 2005. If you are new to OpenCV, then this article is for you newbies.:-)

Where to Download?
  • You can download latest version of OpenCV for windows from SourceForge.
  • Download CMake 2.8 from CMake original site. Download binary package for Win32. It will specified as Win32 Installer.
Build Procedure using CMake and Visual Studio
CMake is a cross platform maker, open build source system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files.

Follow the instruction given below to create solution file and to build OpenCV library on windows.
  • In CMake windows, select your OpenCV2.3 folder as source folder and make OpenCV2.3/build as your build folder. 
  • After filing up these paths, no need to change any of the settings, just click Configure. 
  • You will be prompted to select your Visual Studio version and also select whether it is 32 bit or 64 bit. 
  • Once you click finish, it will list out all flag and settings for cross platform making. 
  • Click Configure till all red flag goes on. Click Generate to create VS solution file in your OpenCV build directory.  
 Work of CMake is over, now its time to build solution file to create dynamic link library (.dll) and static library (.lib).

Visual Studio
You need to build OpenCV.sln file created in build directory by CMake. Open solution file in Visual Studio.  

  • Goto Tools->Options to open Options window. Select VC++ projects under Projects and solution tree.
  •  Select Include Files from Show Directories for  droplist and add entry as below.
    • C:\OpenCV2.3\include\opencv
    • C:\OpenCV2.3\include\opencv2  
    •  Click OK to apply settings.
    •  Build solution in both release and debug mode.
    Check whether all projects succeeded with 0 failure. Check your build directory OpenCV2.3\build\bin' and OpenCV2.3\build\lib for opencv_calib3d230, opencv_core230, opencv_highgui230 and other important files. Next step is to create a sample application using OpenCV library.

    Sample Program
    Create a windows console application and create a HelloWorld c file. Create or copy some image in your working directory (see below for working directory path) and name it as Image or you can change file name according to your program.

    #include "cv.h"
    #include "cvaux.h"
    #include "highgui.h"
    
    int main(int argc, char* argv[])
    {
    IplImage* img = cvLoadImage( "Image.jpg", 1 );
    cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
    cvShowImage("Example1", img);
    cvWaitKey(0);
    cvReleaseImage( &img );
    cvDestroyWindow( "Example1" );
    return 0;
    }
    •  Before compiling your code, right click on your projects and select properties. You need to specify libraries to link your project with OpenCV. In properties window, select Linker->input and add additional libraries as opencv_core230.lib, opencv_highgui230.lib, opencv_imgproc230.lib  in release and debug type. Be careful that for debug version there will be d suffix to library name (eg., opencv_imgproc230d.lib).
    •  Next, Right click on your project in solution explorer and select properties. Expand Configuration properties tree and follow instructions below.
      •  Under C/C++ root, select General and put following entry in Additional Include Directories.
        • C:\OpenCV2.3\include\opencv
        • C:\OpenCV2.3\include\opencv2
      • Under Linker root, select General and put following entry in Additional Library Directories.
        • C:\OpenCV2.3\build\lib\debug, for debug version.
        • C:\OpenCV2.3\build\lib\release, for release version.
      • Select Debugging option under Configuration properties root. Add your built dll path in working directory as  OpenCV2.3\build\bin\debug for debug and OpenCV\build\bin\release  for release configuration.
    Now build your solution and a simple console application will create a window displaying image you have given. 
    Based on your project, you need to include your libraries to project properties. Your comments are welcomed:-)