XCgrabberFlex.C

Go to the documentation of this file.
00001 /*!@file Devices/XCgrabberFlex.C Interface with a Silicon imaging digital camera */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Farhan Baluch <fbaluch@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/XCgrabberFlex.C $
00035 // $Id: XCgrabberFlex.C$
00036 //
00037 
00038 #include <cstddef>
00039 #include <string>
00040 
00041 #include "Component/OptionManager.H" // for option alias requests
00042 #include "Devices/DeviceOpts.H"
00043 #include "Image/Image.H"
00044 #include "Image/Pixels.H"
00045 #include "Image/MathOps.H"
00046 #include "Raster/GenericFrame.H"
00047 #include "Raster/Raster.H"
00048 #include "Util/Assert.H"
00049 #include "Util/SimTime.H"
00050 #include "Util/sformat.H"
00051 #include "Video/VideoFrame.H"
00052 
00053 #include "Devices/XCgrabberFlex.H"
00054 
00055 // wait when polling for a frame (in us):
00056 #define XCWAIT 50
00057 //define the imaging board, (we have only one board)
00058 #define UNITMAP 1
00059 #define USEDBUFFER 16
00060 
00061 // ######################################################################
00062 XCgrabberFlex::XCgrabberFlex(OptionManager& mgr,
00063                                  const std::string& descrName,
00064                                  const std::string& tagName,
00065                                  const ParamFlag flags) :
00066   FrameIstream(mgr, descrName, tagName),
00067   itsDims(&OPT_FrameGrabberDims, this, Dims(1920, 1080), USE_MY_VAL),
00068   itsGrabMode(&OPT_FrameGrabberMode, this, VIDFMT_BAYER_GB, USE_MY_VAL),
00069   itsByteSwap(&OPT_FrameGrabberByteSwap, this, false, USE_MY_VAL),
00070   itsWhiteBalTarR(&OPT_FrameGrabberWhiteBalTargetR, this, false, USE_MY_VAL),
00071   itsWhiteBalTarG(&OPT_FrameGrabberWhiteBalTargetG, this, false, USE_MY_VAL),
00072   itsWhiteBalTarB(&OPT_FrameGrabberWhiteBalTargetB, this, false, USE_MY_VAL),
00073   itsWhiteBalRefR(&OPT_FrameGrabberWhiteBalReferenceR, this, false, USE_MY_VAL),
00074   itsWhiteBalRefG(&OPT_FrameGrabberWhiteBalReferenceG, this, false, USE_MY_VAL),
00075   itsWhiteBalRefB(&OPT_FrameGrabberWhiteBalReferenceB, this, false, USE_MY_VAL),
00076   itsGamma(&OPT_XCFrameGrabberGamma, this, 1.0, USE_MY_VAL | ALLOW_ONLINE_CHANGES),
00077   itsFPS(&OPT_FrameGrabberFPS, this, 30.0, USE_MY_VAL)
00078 #ifdef HAVE_XCLIB
00079   ,itsFormatFile(&OPT_XCFormatFileName, this),
00080   itsCameraOk(false),
00081   itsImgBuf(NULL)
00082 #endif
00083 {
00084 #ifdef HAVE_XCLIB
00085   memset(&itsXclib, 0, sizeof(itsXclib));
00086   itsXclib.ddch.len = sizeof(itsXclib);
00087   itsXclib.ddch.mos = XCMOS_LIBS;
00088 
00089   itsStatep = NULL;
00090   itsLastBuf = 0;
00091 #endif
00092 }
00093 
00094 // ######################################################################
00095 void XCgrabberFlex::start1()
00096 {
00097 #ifndef HAVE_XCLIB
00098   LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00099 #else
00100   // open the XC cameralink imaging board
00101   int i;
00102   if(!strcmp(itsFormatFile.getVal().c_str(),"noFile"))
00103     {
00104       LINFO("use default setup configure format");
00105       char* format =(char*)("default");
00106       i = xclib::xclib_open(&itsXclib, NULL,NULL, format, NULL);
00107     }
00108   else
00109     {
00110       LINFO("use input format file as configure file");
00111       char* formatFile = (char*)(itsFormatFile.getVal().c_str());
00112       i = xclib::xclib_open(&itsXclib, NULL, NULL, NULL, formatFile);
00113     }
00114   if(i != 0)
00115     {
00116       LINFO("error code %d\n", i);
00117       LFATAL("can not open the XC camera");
00118     }
00119 
00120   switch(itsGrabMode.getVal())
00121     {
00122     case VIDFMT_BAYER_GB12:        itsBitDepth = 12;  break;
00123     case VIDFMT_BAYER_GR12:        itsBitDepth = 12;  break;
00124     case VIDFMT_BAYER_RG12:        itsBitDepth = 12;  break;
00125     case VIDFMT_BAYER_BG12:        itsBitDepth = 12;  break;
00126     case VIDFMT_BAYER_GB:          itsBitDepth = 8;   break;
00127     case VIDFMT_BAYER_GR:          itsBitDepth = 8;   break;
00128     case VIDFMT_BAYER_RG:          itsBitDepth = 8;   break;
00129     case VIDFMT_BAYER_BG:          itsBitDepth = 8;   break;
00130     default:                       LFATAL("ERROR in specify the xc grab mode");
00131     }
00132 
00133   // list basic camera info
00134   struct xclib::pxdevinfo pxinfo;
00135   memset(&pxinfo, 0, sizeof(pxinfo));
00136   pxinfo.ddch.len = sizeof(pxinfo);
00137   pxinfo.ddch.mos = PXMOS_DEVINFO;
00138 
00139   itsXclib.pxdev.getDevInfo(&(itsXclib.pxdev), UNITMAP, 0, &pxinfo);
00140   LINFO("find %d baords, frame buffer memory = %.4f Kbytes",
00141         pxinfo.nunits,(double)pxinfo.memsize/1024);
00142 
00143   //white balance
00144   WhiteBalance();
00145 
00146   struct xclib::pxlibservice pxlib = itsXclib.pxlib;
00147   struct xclib::xcdevservice xcdev = itsXclib.xcdev;
00148 
00149   // initialize pxvidstate
00150   i = pxlib.allocStateCopy(&pxlib, 0, 0, &itsStatep);
00151   LINFO("allocate state copy (video state), result code: %d", i);
00152 
00153   i = pxlib.initStateCopy(&pxlib, 0, 0,
00154                          itsStatep, &pxinfo, (char*)("default"), PXMODE_DIGI);
00155   LINFO("init state copy (video state), result code: %d",i);
00156   pxlib.defineState(&pxlib, 0, itsStateid, itsStatep);
00157 
00158   //  itsStatep->vidres->x.vidoffset =  640;//1920/2-itsDims.getVal().w()/2;
00159   //itsStatep->vidres->x.vidoffsend = 1920; //1920/2+itsDims.getVal().w()/2;
00160 
00161   LINFO("pxvidimage dims = %d,%d\n",itsStatep->vidres->x.vidoffset,
00162         itsStatep->vidres->x.vidoffsend);
00163 
00164   //! show some info of pxvidstate structure
00165   /*
00166   LINFO("the pxvidimage bayerpattern: %d, %d, %d, %d, %d, %d\n",
00167         itsStatep->vidimage->bp.order,
00168         itsStatep->vidimage->bp.mode,
00169         itsStatep->vidimage->bp.arg[0],
00170         itsStatep->vidimage->bp.arg[1],
00171         itsStatep->vidimage->bp.arg[2],
00172         itsStatep->vidimage->bp.arg[3]);
00173 
00174   LINFO("the pxvidimage colorspace: %d, %d, %d",
00175         itsStatep->vidimage->cs.order,
00176         itsStatep->vidimage->cs.mode,
00177         (int)itsStatep->vidimage->cs.scale);
00178 
00179   LINFO("the pxvid image whitebalance: %d, %d, %d",
00180         itsStatep->vidimage->wb.order,
00181         itsStatep->vidimage->wb.mode,
00182         (int)itsStatep->vidimage->wb.gamma[0][0]);
00183 
00184   LINFO("the pxvid image sharp :%d, %d, %d, %d, %d",
00185         itsStatep->vidimage->sh.order,
00186         itsStatep->vidimage->sh.mode,
00187         itsStatep->vidimage->sh.scale,
00188         itsStatep->vidimage->sh.into[0],
00189         itsStatep->vidimage->sh.from[0]);
00190 
00191   for(int i=0; i<6; i++)
00192     for(int j=0; j<4; j++)
00193       {
00194         itsStatep->vidimage->wb.gamma[i][j] = 100;
00195         itsStatep->vidimage->wb.darkreference[i][j] = 30;
00196         itsStatep->vidimage->wb.darktarget[i][j] = 30;
00197         itsStatep->vidimage->wb.brightreference[i][j] = 120;
00198         itsStatep->vidimage->wb.brighttarget[i][j] = 200;
00199       }
00200   itsStatep->vidimage->wb.mode = 3;
00201   itsStatep->vidimage->wb.order = 1;
00202 
00203   itsStatep->vidimage->sh.order = 1;
00204   itsStatep->vidimage->sh.mode = 3;
00205   itsStatep->vidimage->sh.into[0] = 120;
00206   itsStatep->vidimage->sh.into[1] = 120;
00207   itsStatep->vidimage->sh.into[2] = 120;
00208   itsStatep->vidimage->sh.from[0] = 200;
00209   itsStatep->vidimage->sh.from[1] = 200;
00210   itsStatep->vidimage->sh.from[2] = 200;
00211   itsStatep->vidimage->sh.scale = 2;
00212   itsStatep->vidimage->sh.arg[0] = 1;
00213   itsStatep->vidimage->sh.arg[1] = 1;
00214 
00215   i = xcdev.setCameraConfig(&xcdev, UNITMAP, 0, 0, itsStatep, NULL);
00216   LINFO("set camera config res code: %d", i);
00217   LINFO("after wb, gamma is %d", (int)itsStatep->vidimage->wb.gamma[0][0]);
00218 
00219   i = pxlib.exportStateCopy(&pxlib,0, itsStateid, itsStatep, 0,(char*)
00220                             "trash_xc_format.txt",NULL,NULL,NULL);
00221   LINFO("export state res code: %d", i);
00222   */
00223   i = xcdev.setVideoConfig(&xcdev,UNITMAP, 0, 0, itsStatep, NULL);
00224   LINFO("set video configure code %d", i);
00225 
00226 
00227   i = xcdev.setLiveSeqBuf
00228     (&xcdev, UNITMAP, 0, 0, itsStatep, NULL, 1, USEDBUFFER, 1, 0, 1, 0);
00229   if(i != 0)
00230     {
00231       LINFO("start capture error code %d", i);
00232       LFATAL("the imaging board can not work on live mode\n");
00233     }
00234 
00235   // make sure the camera start to work for capture
00236   // get the captured buffer ID
00237   xclib::pxbuffer_t bufferID =
00238     (xclib::pxbuffer_t)xcdev.getLiveStatus(&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00239   if(bufferID ==0)    LINFO("Grab not ready...");
00240 
00241   while( bufferID == 0 )
00242     { usleep(XCWAIT);
00243       bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00244         (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00245     }
00246 
00247   const unsigned int bufSz = itsDims.getVal().sz() * (int)ceil(itsBitDepth/8);
00248   itsImgBuf = (byte*)malloc(bufSz);
00249 
00250   itsCameraOk = true;
00251 
00252 #endif // HAVE_XCLIB
00253 }
00254 
00255 // ######################################################################
00256 void XCgrabberFlex::stop2()
00257 {
00258 #ifndef HAVE_XCLIB
00259   // don't LFATAL() in stop() since it may be called in a destructor chain
00260   LERROR("you must have XC  support and the xclib library in order to use XCgrabberFlex");
00261 #else
00262   if (itsCameraOk)
00263     {
00264       xclib_close(&itsXclib);
00265       itsCameraOk = false;
00266     }
00267 #endif // HAVE_XCLIB
00268 }
00269 
00270 // ######################################################################
00271 XCgrabberFlex::~XCgrabberFlex()
00272 {
00273 #ifdef HAVE_XCLIB
00274       free(itsImgBuf);
00275 #endif
00276 }
00277 
00278 // ######################################################################
00279 void XCgrabberFlex::WhiteBalance()
00280 {
00281 #ifdef HAVE_XCLIB
00282   /*
00283   LINFO("Please put a white board in front of the camera then press any key");
00284   Raster::waitForKey();
00285 
00286   LINFO("ready for white balance");
00287   pxd_doSnap(UNITMAP, 1, 0);
00288   uint reference[3] = {0,0,0};
00289   uint target[3] = {0,0,0};
00290 
00291   if(0 != pxd_setImageBrightBalance(1,reference,target, 0.0))
00292     LFATAL("can not initial the bright balance");
00293 
00294   double masses[] = {0, 0, 0};
00295   int sz = 99;
00296   ushort* pixels = (ushort*)malloc(sz*sz*sizeof(ushort));
00297   int     midx, midy, i;
00298 
00299   midx = pxd_imageXdim()/2;
00300   midy = pxd_imageYdim()/2;
00301   pxd_readushort(UNITMAP,1,midx-sz/2,midy-sz/2,
00302                  midx+1+sz/2,midy+1+sz/2,pixels,sz*sz,(char*)"RofRGB");
00303   for (i = 0; i < sz*sz; i++)
00304     masses[0] += pixels[i];
00305   pxd_readushort(UNITMAP,1,midx-sz/2,midy-sz/2,
00306                  midx+1+sz/2,midy+1+sz/2,pixels,sz*sz,(char*)"GofRGB");
00307   for (i = 0; i < sz*sz; i++)
00308     masses[1] += pixels[i];
00309   pxd_readushort(UNITMAP,1,midx-sz/2,midy-sz/2,
00310                  midx+1+sz/2,midy+1+sz/2,pixels,sz*sz,(char*)"BofRGB");
00311   for (i = 0; i < sz*sz; i++)
00312     masses[2] += pixels[i];
00313   reference[0] = masses[0]/(sz*sz);
00314   reference[1] = masses[1]/(sz*sz);
00315   reference[2] = masses[2]/(sz*sz);
00316   target[0] = target[1] = target[2]
00317     = std::max(std::max(reference[0], reference[1]), reference[2]);
00318 
00319   if(0 != pxd_setImageBrightBalance(UNITMAP, reference, target, 0.60))
00320     LFATAL("can not do the bright balance");
00321   LINFO("white balance finished");
00322 
00323   free(pixels);
00324   */
00325 
00326 #endif
00327 }
00328 
00329 // ######################################################################
00330 GenericFrameSpec XCgrabberFlex::peekFrameSpec()
00331 {
00332   GenericFrameSpec result;
00333 
00334   result.nativeType = GenericFrame::VIDEO;
00335   result.videoFormat = itsGrabMode.getVal();
00336   result.videoByteSwap = itsByteSwap.getVal();
00337   result.dims = itsDims.getVal();
00338   result.floatFlags = 0;
00339 
00340   return result;
00341 }
00342 
00343 // ######################################################################
00344 SimTime XCgrabberFlex::getNaturalFrameTime() const
00345 {
00346   return SimTime::HERTZ(itsFPS.getVal());
00347 }
00348 
00349 
00350 
00351 // ######################################################################
00352 GenericFrame XCgrabberFlex::readFrame()
00353 {
00354   return GenericFrame(this->grabRaw());
00355 }
00356 
00357 // ######################################################################
00358 VideoFrame XCgrabberFlex::grabRaw()
00359 {
00360 #ifndef HAVE_XCLIB
00361   LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00362   return VideoFrame();  /* can't happen */
00363 #else
00364   ASSERT(itsCameraOk);
00365   int i = 0;
00366 
00367   struct xclib::xcdevservice xcdev = itsXclib.xcdev;
00368   struct xclib::pxlibservice pxlib = itsXclib.pxlib;
00369 
00370   // get the captured buffer ID
00371   xclib::pxbuffer_t bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00372     (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00373 
00374   while( bufferID == itsLastBuf)
00375     {
00376       bufferID = (xclib::pxbuffer_t)xcdev.getLiveStatus
00377         (&xcdev, UNITMAP, 0, PXVIST_DONE | PXVIST_BUFFER);
00378       usleep(100);
00379     }
00380   if(itsLastBuf != 0 && bufferID != (itsLastBuf)%USEDBUFFER + 1)
00381     {
00382       LINFO("last buf id= %4d, curr buf id= %4d",(int)itsLastBuf,(int)bufferID);
00383       LERROR("buffer error: buffer mis order");
00384     }
00385 
00386   pthread_mutex_lock(&qmutex_buf);
00387   itsLastBuf = bufferID;
00388   pthread_mutex_unlock(&qmutex_buf);
00389 
00390   // is the captured image base on byte or uint16 type
00391   int dataMode = (itsBitDepth == 8 ?  PXDATUINT8:PXDATUINT16);
00392 
00393   const unsigned int bufSz = itsDims.getVal().sz() * (int)ceil(itsBitDepth/8);
00394   const unsigned int imgSz = itsDims.getVal().sz();
00395 
00396   //! define the image from frame buffer
00397   struct xclib::pximage pximg;
00398 
00399   i = pxlib.initPximage(&pxlib, UNITMAP,
00400                         &pximg, 1, PXHINTBAYER, 0, itsStateid, bufferID, 0);
00401 
00402   pximg.wind.nw.x = 1920/2 - itsDims.getVal().w()/2;
00403   pximg.wind.nw.y = 1080/2 - itsDims.getVal().h()/2;
00404   pximg.wind.se.x = 1920/2 + itsDims.getVal().w()/2;
00405   pximg.wind.se.y = 1080/2 + itsDims.getVal().h()/2;
00406 
00407   LINFO("pximgsize %d,%d", pximg.wind.nw.x,pximg.wind.se.x);
00408 
00409   if (i<1)
00410     LFATAL("error, can not define a pximage, code: %d",i);
00411 
00412 
00413   if(pximg.ioset(&pximg, PXRXSCAN | PXIWRAP, dataMode, 0x01) < 0)
00414     {
00415       LFATAL("error in ioset, can not set frame buffer read");
00416       return VideoFrame();
00417     }
00418 
00419   if(imgSz !=  pximg.ioread(&pximg, PXRXSCAN | PXIWRAP, itsImgBuf,bufSz,0,0))
00420     {
00421       LFATAL("error in reading frame buffer(size error),"
00422              "expected size = %d", imgSz);
00423       return VideoFrame();
00424     }
00425   return VideoFrame(itsImgBuf,  bufSz, itsDims.getVal(),
00426                     itsGrabMode.getVal(), itsByteSwap.getVal(), false);
00427 
00428 #endif // HAVE_XCLIB
00429 }
00430 
00431 // ######################################################################
00432 void XCgrabberFlex::paramChanged(ModelParamBase* const param,
00433                                    const bool valueChanged,
00434                                    ParamClient::ChangeStatus* status)
00435 {
00436 #ifndef HAVE_XCLIB
00437   LFATAL("you must have XC support and the xclib library in order to use XCgrabberFlex");
00438 #else
00439   FrameIstream::paramChanged(param, valueChanged, status);
00440 #endif // HAVE_XCLIB
00441 }
00442 
00443 // ######################################################################
00444 #ifdef HAVE_XCLIB
00445 xclib::pxbuffer_t XCgrabberFlex::getCurrBufID()
00446 {
00447   xclib::pxbuffer_t tmp;
00448   pthread_mutex_lock(&qmutex_buf);
00449   tmp = itsLastBuf;
00450   pthread_mutex_unlock(&qmutex_buf);
00451   return tmp;
00452 }
00453 #endif
00454 
00455 // ######################################################################
00456 /* So things look consistent in everyone's emacs... */
00457 /* Local Variables: */
00458 /* indent-tabs-mode: nil */
00459 /* End: */
00460 
Generated on Sun May 8 08:40:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3