Calibrating stereo cameras

Finally, a post not related to just setting stuff up!

The reason we need to calibrate the individual cameras is to undo the effect of lens distortion, etc. Then we need to calibrate our rectified individual cameras in relation to each other to get a calibrated stereo camera where the image coordinates from the cameras are transformed such that resulting image planes coincide. This means that for each point in the image, its corresponding point in the other image can be found by looking only along a horizontal line.

Okay, so first we printed out a chessboard pattern on a piece of A4. This is used by the OpenCV functions for the calibration.

Figure 1 – Chessboard pattern.

We then stuck that on a flat piece of wood, to avoid any distortion, and measured the size of the squares (which turned out to be 2.6 cm).

Then we took multiple pictures of the chessboard in different positions and orientations. We modified our earlier program for capturing images for this.

void CaptureCalibrationImages()
{
    Mat left, right;                                 //Declare matrices for storing the recieved images

    int num = 0;                                    // Variable to increment filename for saving images

    ///Reading from cameras sequentially
    CvCapture* capture1 = cvCaptureFromCAM(1);      //Capture stream for left camera
    CvCapture* capture2 = cvCaptureFromCAM(2);      //Capture stream for right camera
    
    if(capture1 && capture2)
    {
        clock_t start = clock();                    //Note current time
        while(true) 
        {
            left = cvQueryFrame(capture1);          //Get frame from left camera
            imshow("left", left);                   //Display frame from left camera

            right=cvQueryFrame(capture2);           //Get frame from right camera
            imshow("right", right);                 //Display frame from right camera

            ///A rudimentary timer to capture images every 3 seconds.
            clock_t end = clock() - start;                          //Note time elapsed
            double time = (double) end / (double)CLOCKS_PER_SEC;    //Convert time elapsed to seconds
            
            if(time >= 3)
            {
                cout << "Picture number "<< intToString(num) << endl;
                imwrite("CalibrationImages/left" + intToString(num) + ".ppm", left);   //Write left image to disc
                imwrite("CalibrationImages/right" + intToString(num) + ".ppm", right); //Write right image to disc
                num++;                                                                 //Increment file count 
                start = clock();                                                       //Reset the timer (essentially)
            }

            int c = waitKey(5);    //Listen for keystroke
            if(c == 'c') break;    //Exit if user presses 'c'
        }
    } else printf("Failure in capture\n");
}

Figure 2 – A small subset of the left and right pictures we took.

We then created a text file with the paths to the images, a small subset of which is below:

CalibrationImages/left0.ppm
CalibrationImages/right0.ppm
CalibrationImages/left2.ppm
CalibrationImages/right2.ppm
CalibrationImages/left3.ppm
CalibrationImages/right3.ppm
CalibrationImages/left4.ppm
CalibrationImages/right4.ppm
CalibrationImages/left5.ppm
CalibrationImages/right5.ppm
CalibrationImages/left6.ppm

Then I downloaded the software provided here, compiled it in my Virtual Machine running Xbuntu (this is what I created the virtual machine for).

I executed the output with in the following way:

./stereo_calibrate list.txt 9 6 2.6

The program then starts showing the detected chessboards in all of the images.

Followed by the stereo rectified images.

Notice how the same points now lie on the same horizontal line.

There is something funny going on in the botton right of the left image, so we probably need ot recalibrate with more images in more positions, but we’ll do that when we receive our own camera.

And that’s it! The calibration is done. The program outputs several matrices saved in xml files that represent the calibration parameters.

I’ll go over what these are and how to use them to rectify images within our own program in the next post. Until then, toodles!

Hassan

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s