BumbleBee Calibration Extraction and Usage

Scott Larsen, Feb 2005

Intro

This is intended to be useful/helpful information for simple usage of the bumblebee cameras using the PointGrey SDK. I once extracted specific camera information, but then found un-measurable (to my rough timer implementation) cost of extracting directly the rectified images. So my code does that. In this document, my code is presented, then notations and information about usage that is not in my code.

My Usage

In my projects, I use a simple OOP wrapper around the following code


/**************************************************/
/***
 * Copyright (C) 2003 - $Date$
 * E. Scott Larsen and
 // The University of North Carolina at Chapel Hill
 //------------------------------------------------------------------------------
 // Permission to use, copy, modify, distribute and sell this software and its 
 // documentation for any purpose is hereby granted without fee, provided that 
 // the above copyright notice appear in all copies and that both that copyright 
 // notice and this permission notice appear in supporting documentation. 
 // Binaries may be compiled with this software without any royalties or 
 // restrictions. 
 //
 // The author(s) and The University of North Carolina at Chapel Hill make no 
 // representations about the suitability of this software for any purpose. 
 // It is provided "as is" without express or implied warranty.
 // -----------------------------------------------------------------------------
 **/
/**************************************************/
/**************************************************/
#include <digiclops.h>
#include <triclops.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <time.h>
/**************************************************/
#define DIGERROR(ee) {DigiclopsError e = ee;if (e){printf("DigiclopsError: %s at %s %d\n",digiclopsErrorToString(e),__FILE__,__LINE__);exit(13);}}
#define TRIERROR(ee) {TriclopsError e = ee;if (e){printf("TriclopsError: %s at %s %d\n",triclopsErrorToString(e),__FILE__,__LINE__);exit(13);}}
/**************************************************/
DigiclopsContext digiclops;
TriclopsContext triclops;
unsigned char * image_mem;
/**************************************************/
void init(){
  image_mem = new unsigned char[640*480*2];
  DIGERROR (digiclopsCreateContext(&digiclops));
  DIGERROR (digiclopsInitialize(digiclops,0));
  DIGERROR (digiclopsGetTriclopsContextFromCamera(digiclops,&triclops));
  DIGERROR (digiclopsStart(digiclops));
  DIGERROR (digiclopsSetImageTypes(digiclops,STEREO_IMAGE|RIGHT_IMAGE|LEFT_IMAGE));
  DIGERROR (digiclopsSetImageResolution(digiclops,DIGICLOPS_FULL));
  DIGERROR (digiclopsSetFrameRate(digiclops,DIGICLOPS_FRAMERATE_100));
  TRIERROR (triclopsSetResolutionAndPrepare(triclops,480,640,480,640));
  TRIERROR (triclopsSetImageBuffer(triclops,&image_mem[640*480*0],TriImg_RECTIFIED,TriCam_LEFT));
  TRIERROR (triclopsSetImageBuffer(triclops,&image_mem[640*480*1],TriImg_RECTIFIED,TriCam_RIGHT));
}
/**************************************************/
void cleanup(){
  delete[] image_mem;
  DIGERROR (digiclopsStop(digiclops));
  DIGERROR (digiclopsDestroyContext(digiclops));
  TRIERROR (triclopsDestroyContext(triclops));
}
/**************************************************/
void capture(unsigned char *& left,unsigned char *& right){
  struct _timeb start,end,mid;
  _ftime(&start);
  DIGERROR (digiclopsGrabImage(digiclops));
  TriclopsInput triclopsInput;
  DIGERROR (digiclopsExtractTriclopsInput(digiclops,STEREO_IMAGE,&triclopsInput));
  TRIERROR (triclopsPreprocess(triclops,&triclopsInput));
  _ftime(&mid);
  double time1 = (double)mid.time*1000. + (double)mid.millitm;
  time1 -= (double)start.time*1000. + (double)start.millitm;
  memcpy(left,image_mem[640*480*0],640*480*1*sizeof(unsigned char));
  memcpy(right,image_mem[640*480*1],640*480*1*sizeof(unsigned char));
  _ftime(&end);
  double time = (double)end.time*1000. + (double)end.millitm;
  time -= (double)start.time*1000. + (double)start.millitm;
  //  printf("Grab: %f\t and copy: %f fps\r",1000./time1,1000./time);
}
/**************************************************/
/**$Author$                            **/
/**$Date$                  **/
/**$Revision$                              **/
/**************************************************/
/***************************************************
 * $Id$
 **************************************************/

Additional Usage

For getting camera configurations, the Triclops Stereo Vision SDK Manual would be the best reference, stating on page 95 (96 in the pdf). I'll outline the available calls here: (all are prefixed by the string "triclops", e.g. triclopsGetBaseline is the function to call for the first one.

GetBaseline

obtain the baseline in meters

GetDeviceConfiguration

I don't remember using this, I'm not sure what it does

GetFocalLength

in pixels for the selected output resolution. This is the same for both images if they're rectified

GetImageCenter

x,y image coordinates of the center if using a pinhole model

GetTriclopsToWorldTransform

I don't remember using this or the details

*To*

There are a handful of functions to convert between spaces, mostly between disparity and world spaces

[Un]RectifyPixel

it may be possible to extract something that we're having trouble extracting via these two functions, e.g. reverse engineering some missing callibration value.

?

I had thought there was a call to get the radial distortion parameters, but I can't seem to find them. You can definately turn on/off radial distortion correction when you're extracting rectified images, and the resulting images are properly different. But I can't seem to be able to find the right function for this.

Further, in the Digiclops SDK Installation Guide, it shows these, that I've never used.

GetCameraProperty

whitebalance values, gain values, shutter settings, etc. These can also be set through SetCameraProperty. Also, specific registers can be read and set.

-

All Images have a timestamp field ("low-level 1394 bus timestamp ... a relative timestamp that wraps around every 128 seconds.") Maybe useful.

Summary

It's very easy to extract properly rectified images, but I don't have code still around for extracting these other parameters. With access to a camera, perhaps I could play around with this more.
Note: there is a digiclopsReadPPMToDigiclopsImage() function. This may be handy in coding for dealing with static images (or images from a file) alongside the functionality given. Perhaps not.


Last modified: Mon Jan 31 16:04:27 Eastern Standard Time 2005