• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

tests/testF2.cpp

00001 // A simple test program to verify timing and functionality of the F2 under FCAM
00002 
00003 #include "FCam/F2.h"
00004 #include <cmath>
00005 #include <algorithm>
00006 #include <fstream>
00007 #include <stdio.h>
00008 
00009 typedef std::vector<FCam::Shot> Burst;
00010 
00011 void roiTimingTest() {
00012     using namespace FCam::F2;
00013     using namespace std;
00014     char buf[256];
00015     FILE *fp;
00016 
00017     printf("roiTimingTest: Tabulating frame time changes with ROI\n"
00018            "-------------------------------------------\n");
00019 
00020     fp = fopen("roiTiming.csv", "w");
00021     if (fp == NULL) {
00022         printf("Unable to open stats file roiTiming.csv, exiting\n");
00023         return;
00024     }
00025 
00026     int e[] = {1000,5000,10000,20000,40000,80000};
00027     vector<int> exposures(e, e + sizeof(e)/sizeof(int));
00028 
00029     int ft[] = {15000,20000,40000,80000};
00030     vector<int> frameTimes(ft, ft + sizeof(ft)/sizeof(int));
00031 
00032 //     RowSkip::e rs[] = { RowSkip::none, RowSkip::x2, RowSkip::x3, RowSkip::x4,
00033 //                         RowSkip::x5, RowSkip::x6, RowSkip::x7, RowSkip::x8 };
00034     RowSkip::e rs[] = { RowSkip::none, RowSkip::x2, RowSkip::x4};
00035 
00036     vector<RowSkip::e> rowSkips(rs, rs + 3);
00037 
00038 //     ColSkip::e cs[] = { ColSkip::none, ColSkip::x2, ColSkip::x3, ColSkip::x4,
00039 //                               ColSkip::x5, ColSkip::x6, ColSkip::x7 };
00040     ColSkip::e cs[] = { ColSkip::none, ColSkip::x2, ColSkip::x4};
00041 
00042     vector<ColSkip::e> colSkips(cs, cs + 3);
00043 
00044 //    RowBin::e rb[] = { RowBin::none, RowBin::x2, RowBin::x3, RowBin::x4 };
00045     RowBin::e rb[] = { RowBin::none, RowBin::x2, RowBin::x4 };
00046     vector<RowBin::e> rowBins(rb, rb + 3);
00047 
00048     ColBin::e cb[] = { ColBin::none, ColBin::x2, ColBin::x4 };
00049     vector<ColBin::e> colBins(cb, cb + 3);    
00050 
00051     vector<bool> changeRoiXY(2);
00052     changeRoiXY[0] = false;
00053     changeRoiXY[1] = true;
00054 
00055     int roiXstd = 0;
00056     int roiYstd = 0;
00057     int roiXchg = 500;
00058     int roiYchg = 500;
00059 
00060     int dstRealFT, srcRealFT;
00061     int dstRealExp, srcRealExp;
00062 
00063     Shot srcShot, dstShot;
00064     srcShot.gain = 8;
00065     srcShot.image = FCam::Image(640,480,FCam::UYVY, FCam::Image::Discard);
00066     dstShot = srcShot; 
00067 
00068     Sensor sensor;
00069 
00070     unsigned int burstCount = 10;            
00071     unsigned int n = 6;
00072 
00073     snprintf(buf, 256, "sExp(ms), sFT(ms), sRS, sCS, sRB, sCB, sSX, sSY,   dExp(ms), dFT(ms), dRS, dCS, dRB, dCB, dSX, dSY");
00074     printf(buf); fprintf(fp, buf);
00075     for (unsigned int k=0; k <n ; k++) {
00076         snprintf(buf, 256, ",   exp_ms[%d], ft_ms[%d], avg_dT_ms[%d], std_dT_us[%d], cnt[%d]", k,k,k,k,k);
00077         printf(buf); fprintf(fp, buf);
00078     }
00079     snprintf(buf, 256, "\n");
00080     printf(buf); fprintf(fp,buf);
00081 
00082     for (vector<int>::iterator fTime = frameTimes.begin(); fTime != frameTimes.end(); fTime++) {
00083     for (vector<int>::iterator exp = exposures.begin(); exp != exposures.end(); exp++) {
00084         //    for (vector<bool>::iterator rXY = changeRoiXY.begin(); rXY != changeRoiXY.end(); rXY++) {
00085     for (int sb=0; sb < 3; sb++) {
00086         srcShot.roiStartX = roiXstd;
00087         srcShot.roiStartY = roiYstd;
00088         srcShot.rowSkip = rowSkips[sb]; srcShot.colSkip = colSkips[sb];
00089         srcShot.rowBin = rowBins[sb]; srcShot.colBin = colBins[sb];
00090         srcShot.frameTime = *fTime;
00091         srcShot.exposure = *exp;
00092         for (vector<int>::iterator fTime2 = frameTimes.begin(); fTime2 != frameTimes.end(); fTime2++) {
00093         for (vector<int>::iterator exp2 = exposures.begin(); exp2 != exposures.end(); exp2++) {
00094         for (int sb2 =0; sb2< 3; sb2++) {
00095             dstShot.roiStartX = roiXstd; //*rXY ? roiXchg : roiXstd;
00096             dstShot.roiStartY = roiYstd; //*rXY ? roiYchg : roiYstd;
00097             dstShot.rowSkip = rowSkips[sb2]; dstShot.colSkip = colSkips[sb2];
00098             dstShot.rowBin = rowBins[sb2]; dstShot.colBin = colBins[sb2];
00099             dstShot.frameTime = *fTime2;
00100             dstShot.exposure = *exp2;
00101 
00102             std::vector<Shot> testBurst(n);
00103             
00104             unsigned int i=0;
00105             for (; i < n/2; i++) {
00106                 testBurst[i] = srcShot;
00107             }
00108             for (; i < n; i++) {
00109                 testBurst[i] = dstShot;
00110             }
00111             int chgIndex = n/2;
00112 
00113             sensor.debugTiming(true);
00114 
00115             sensor.capture(dstShot); // Extra frame to allow for nice deltaTs
00116             for (unsigned int i=0; i< burstCount; i++) sensor.capture(testBurst);
00117             
00118             FCam::Time prevT;
00119             {
00120                 Frame::Ptr f = sensor.getF2Frame();
00121                 prevT = f->processingDoneTime;
00122             }
00123             vector<float> dT[n];
00124             float driverExp[n], driverFT[n];
00125             for (unsigned int i=0;i<n;i++) driverExp[i] = driverFT[i] = 0; 
00126 
00127             int testFrames = burstCount * n;
00128             int index = 0;
00129             while (testFrames-- > 0) {
00130                 Frame::Ptr f = sensor.getF2Frame();
00131                 
00132                 float deltaT = (f->processingDoneTime - prevT) / 1000.0;
00133                 prevT = f->processingDoneTime;
00134                 
00135                 dT[index].push_back(deltaT);
00136                 driverExp[index] += f->exposure;
00137                 driverFT[index] += f->frameTime;
00138                 index = (index + 1) % n;
00139             }
00140 
00141             float avg[n];
00142             float std[n];
00143             for (unsigned int k=0;k<n;k++) {
00144                 avg[k] = 0;
00145                 for (unsigned int i=0; i < dT[k].size(); i++) 
00146                     avg[k] += dT[k][i];
00147                 avg[k] /= dT[k].size();
00148 
00149                 std[k] = 0;
00150                 for (unsigned int i=0; i < dT[k].size(); i++) 
00151                     std[k] += (dT[k][i] - avg[k])*(dT[k][i] - avg[k]);
00152                 std[k] = sqrt( std[k] / dT[k].size());
00153             }
00154 
00155             snprintf(buf,256, "%.2f, %.2f, %d, %d, %d, %d, %d, %d,    ",
00156                    srcShot.exposure/1000.f, srcShot.frameTime/1000.f, 
00157                    srcShot.rowSkip, srcShot.colSkip, srcShot.rowBin, srcShot.colBin, 
00158                    srcShot.roiStartX, srcShot.roiStartY);
00159             printf(buf); fprintf(fp, buf);
00160 
00161             snprintf(buf,256, "%.2f, %.2f, %d, %d, %d, %d, %d, %d",
00162                    dstShot.exposure/1000.f, dstShot.frameTime/1000.f, 
00163                    dstShot.rowSkip, dstShot.colSkip, dstShot.rowBin, dstShot.colBin, 
00164                    dstShot.roiStartX, dstShot.roiStartY);
00165             printf(buf); fprintf(fp, buf);
00166             for (unsigned int k=0; k < n; k++) {
00167                 if ( k % 3 == 0) printf("\n\t");
00168                 snprintf(buf,256, ",    %.1f, %.1f, %.2f, %.1f, %d", 
00169                          driverExp[k]/dT[k].size()/1000, driverFT[k]/dT[k].size()/1000,
00170                          avg[k], std[k]*1000, dT[k].size());
00171                 printf(buf); fprintf(fp, buf);
00172             }
00173             snprintf(buf,256,"\n");
00174             printf(buf); fprintf(fp,buf);
00175 
00176             fflush(fp);
00177             if (sensor.framesPending()) {
00178                 printf("!! Still got frames, that's not good\n");
00179             }
00180 
00181         }
00182         }
00183         }
00184     }
00185     }
00186     //    }
00187     }
00188 }
00189 
00190 void syncTest() {
00191     using namespace FCam::F2;
00192     using namespace std;
00193 
00194     printf("syncTest: Testing basic frame-level control\n"
00195            "-------------------------------------------\n");
00196 
00197     // Initialize a sensor
00198     Sensor sensor;
00199     unsigned int n = 10;
00200 
00201     // Create a n-image burst with one image with different parameters
00202 
00203     Burst testShots(1);
00204 
00205     testShots[0].exposure = 1000;
00206     testShots[0].gain = 10;
00207     testShots[0].frameTime = 40000;
00208     testShots[0].image = FCam::Image(640, 480, FCam::UYVY);
00209 
00210     for (unsigned int i=1; i < n;i++) {
00211         testShots.push_back(testShots[0]);
00212         testShots[i].image = FCam::Image(640,480, FCam::UYVY);
00213         if (i >= n/2) testShots[i].exposure = 20000; //25000;
00214     }
00215     testShots[n-1].exposure = 40000;
00216 
00217     sensor.stream(testShots);
00218 
00219     vector<vector<float> > lums(n);
00220     vector<vector<float> > deltaT(n);
00221 
00222     int testFrames = n*10;
00223     FCam::Time prevTime = FCam::Time::now();
00224     bool startup = true;
00225     int startupIgnoreCount = 0; //n-1;
00226 
00227     printf("* Capturing %d frames of a %d-shot burst\n", testFrames, n);
00228     while (testFrames-- > 0) {
00229         unsigned int index;
00230         FCam::Frame::Ptr f = sensor.getFrame();
00231         
00232         for (index=0; index<n ;index++ ) {
00233             if (testShots[index].id == f->shot().id) break;
00234         }
00235         if (index == n) {
00236             printf("Unknown frame returned! Something wrong in the shot cloning, perhaps?\n");
00237             exit(0);
00238         }
00239 
00240         if (startupIgnoreCount-- == 0)
00241             startup=false;
00242 
00243         if (!startup) {
00244             float dt = (f->processingDoneTime-prevTime) / 1000.;
00245             printf("Frame %d: Time from previous frame: %.2f ms, supposed to be %.2f\n", index, dt,
00246                    f->frameTime/1000.);
00247             deltaT[index].push_back(dt);
00248         } 
00249 
00250         prevTime = f->processingDoneTime;
00251             
00252         if (!f->image.valid()) {
00253             printf(" Frame %d Came back with no image data!\n", index);
00254             continue;
00255         } 
00256 
00257         // Calculate some statistics 
00258         unsigned int totalY=0;
00259         unsigned char *yPtr = f->image.data+1; // Offset to get to a Y
00260         unsigned int count=0;
00261         while (yPtr < f->image.data + 2*f->image.size.width*f->image.size.height) {
00262             totalY+= *yPtr;
00263             yPtr += 100;
00264             count++;
00265         }        
00266         lums[index].push_back( ((float)totalY)/count);
00267     }
00268     sensor.stopStreaming();
00269 
00270     printf("Writing stats to syncTest.csv\n");
00271     ofstream stats("syncTest.csv");   
00272     bool done = false;
00273     unsigned int row = 0;
00274     while (!done) {        
00275         int haveData=0;
00276         for (unsigned int i=0;i < n; i++) {
00277             if (row < lums[i].size()) {
00278                 stats << lums[i][row] << ", ";
00279                 haveData++;
00280             } else {
00281                 stats << "-1 ,";
00282             }
00283             if (row < deltaT[i].size()) {
00284                 stats << deltaT[i][row];
00285                 haveData++;
00286             } else {
00287                 stats << "-1";
00288             }
00289             if (i < n-1)
00290                 stats << " ,";
00291         }
00292         stats << endl;
00293         if (haveData == 0) done = true;
00294         row++;
00295     }
00296     stats.close();
00297 
00298     printf("\n\n** Results (Y=sampled luminance per pixel, T=inter-frame time)\n\n");
00299     // Calculate averages, stddevs
00300     vector<float> avgsL(n), stddevsL(n), lowboundL(n), highboundL(n);
00301     vector<float> avgsT(n), stddevsT(n), lowboundT(n), highboundT(n);
00302     for (unsigned int i=0;i<n;i++) {
00303         avgsL[i] = 0;
00304         stddevsL[i] = 0;
00305         for (unsigned int j=0;j < lums[i].size(); j++) {
00306             avgsL[i] += lums[i][j];
00307         }
00308         avgsL[i] /= lums[i].size();
00309         for (unsigned int j=0;j < lums[i].size(); j++) {
00310             stddevsL[i] += (lums[i][j] - avgsL[i])*(lums[i][j] - avgsL[i]);
00311         }
00312         stddevsL[i] /= lums[i].size();
00313         stddevsL[i] = sqrt(stddevsL[i]);        
00314         sort(lums[i].begin(), lums[i].end());
00315         if (lums[i].size()>10) {
00316             lowboundL[i] = lums[i][lums[i].size()/10];
00317             highboundL[i] = lums[i][lums[i].size()*9/10];
00318         } else {
00319             lowboundL[i]=-1;
00320             highboundL[i]=-1;
00321         }
00322         printf("Shot %d cnt %d, Lum: Avg: %.1f, Std: %.1f, 10%%: %f, 90%%: %f\n", i, lums[i].size(), avgsL[i], stddevsL[i], lowboundL[i], highboundL[i]);
00323     }    
00324     printf("\n");
00325     for (unsigned int i=0;i<n;i++) {
00326         avgsT[i] = 0;
00327         stddevsT[i] = 0;
00328         for (unsigned int j=0;j < deltaT[i].size(); j++) {
00329             avgsT[i] += deltaT[i][j];
00330         }
00331         avgsT[i] /= deltaT[i].size();
00332         for (unsigned int j=0;j < deltaT[i].size(); j++) {
00333             stddevsT[i] += (deltaT[i][j] - avgsT[i])*(deltaT[i][j] - avgsT[i]);
00334         }
00335         stddevsT[i] /= deltaT[i].size();
00336         stddevsT[i] = sqrt(stddevsT[i]);
00337         sort(deltaT[i].begin(), deltaT[i].end());
00338         if (deltaT[i].size()>10){
00339             lowboundT[i] = deltaT[i][deltaT[i].size()/10];
00340             highboundT[i] = deltaT[i][deltaT[i].size()*9/10];
00341         } else {
00342             lowboundT[i] = -1;
00343             highboundT[i] = -1;
00344         }
00345         printf("Shot %d, Interframe delay: Avg: %.3f ms, Std: %.2f us, 10%%: %.2f, 90%%: %.2f Exp: %.1f ms\n",
00346                i, avgsT[i], stddevsT[i]*1000, lowboundT[i], highboundT[i], testShots[i].exposure/1000. );
00347     }
00348 
00349     printf("syncTest: Done\n"
00350            "-------------------------------------------\n");
00351 
00352 }
00353 
00354 void basicTest() {
00355     using namespace FCam;
00356     using namespace std;
00357 
00358     printf("basicTest: Testing basic capture in all formats\n"
00359            "-------------------------------------------\n");
00360 
00361     unsigned int n = 15;
00362     F2::Sensor sensor;
00363     F2::Shot testShot;
00364     AsyncFileWriter writer;
00365 
00366     testShot.exposure = 40000;
00367     testShot.frameTime = 0;
00368     testShot.gain = 8;
00369     
00370     // Get 640x480 UYVY images
00371     
00372     printf("=== 640x480 UYVY ===\n");
00373     testShot.image = Image(640,480,UYVY, Image::Discard);
00374     testShot.roiRegionSmaller(sensor.maxImageSize());
00375     for (int i=0;i < n;i++) sensor.capture(testShot);
00376     for (int i=0;i < n;i++) { sensor.getFrame(); printf("\tGot frame %d\n", i); }
00377     
00378     
00379     // Get 5 MP UYVY images
00380     printf("=== 5MP UYVY ===\n");
00381     testShot.image = Image(sensor.maxImageSize(), UYVY, Image::Discard);
00382     testShot.roiRegionSmaller(sensor.maxImageSize());
00383     {
00384         //Frame::Ptr f[n];
00385         for (int i=0;i < n;i++) sensor.capture(testShot);
00386         for (int i=0;i < n;i++) { sensor.getFrame(); printf("\tGot frame %d\n", i); }        
00387         //for (int i=0;i < n;i++) { f[i] = sensor.getFrame(); printf("\tGot frame %d\n", i); }
00388         //for (int i=0;i< n; i++) { char name[256]; snprintf(name,256, "basic_%02d.yuyv", i); saveUYVY(f[i], name); }
00389     }
00390     
00391     
00392     // Get 5 MP RAW images
00393     printf("=== 5MP RAW ===\n");
00394     testShot.image = Image(sensor.maxImageSize(), RAW, Image::Discard);
00395     testShot.roiRegionSmaller(sensor.maxImageSize());
00396     {
00397         //Frame::Ptr f[n];
00398         for (int i=0;i < n;i++) sensor.capture(testShot);
00399         for (int i=0;i < n;i++) { sensor.getFrame(); printf("\tGot frame %d\n", i); }        
00400         //for (int i=0;i < n;i++) { f[i]=sensor.getFrame(); printf("\tGot frame %d\n", i); }        
00401         //for (int i=0;i< n; i++) { char name[256]; snprintf(name,256, "basic_%02d.dng", i); saveDNG(f[i], name); }
00402     }
00403    
00404     // Get 640x480 RAW images
00405     printf("=== 640x480 RAW ===\n");
00406     //sensor.debugTiming(true);
00407     testShot.image = Image(640,480,RAW, Image::AutoAllocate);
00408     testShot.roiRegionSmaller(sensor.maxImageSize());
00409     for (int i=0;i < n;i++) sensor.capture(testShot);
00410     for (int i=0;i < n;i++) { sensor.getFrame(); printf("\tGot frame %d\n", i); }        
00411 
00412     // Get 640x480 UYVY images again
00413     
00414     printf("=== 640x480 UYVY again ===\n");
00415     testShot.image = Image(640,480,UYVY, Image::Discard);
00416     testShot.roiRegionSmaller(sensor.maxImageSize());
00417     for (int i=0;i < n;i++) sensor.capture(testShot);
00418     for (int i=0;i < n;i++) { sensor.getFrame(); printf("\tGot frame %d\n", i); }
00419     
00420 
00421     /*
00422     for (int i=0;i < n;i++) { 
00423         Frame::Ptr f=sensor.getFrame(); 
00424         
00425         printf("\tGot frame %d\n", i); 
00426         char name[256]; snprintf(name,256, "basic_%02d.dng", i); 
00427         writer.saveDNG(f, name);
00428     }
00429     */    
00430 }
00431 
00432 void usage() {
00433     printf("test_F2 Usage:\n\ntest_F2 <test1> <test2> ...\n");
00434     printf("Available tests:\n");
00435     printf("\tb\tBasic\tJust try capturing some frames in UYVY/RAW modes and 640x48/5 MP\n");
00436     printf("\ts\tSync\tTest timing of shot parameter changes\n");
00437     printf("\tr\tRoi Timing\tCollect a lot of statistics. Takes a while, writes roiTiming.csv as it goes\n");
00438 }
00439 
00440 int main(int argc, char **argv) {
00441     if (argc > 1) {
00442         printf("Starting F2 FCam API tests\n"
00443                "===============================\n");
00444         for (int i=1; i < argc; i++) {
00445             switch(argv[i][0]) {
00446             case 'b':
00447             case 'B':
00448                 basicTest();
00449                 break;
00450             case 's':
00451             case 'S':
00452                 syncTest();
00453                 break;
00454             case 'r':
00455             case 'R':
00456                 roiTimingTest();
00457                 break;
00458             default:
00459                 printf("Unknown test %s\n", argv[0]);
00460                 usage();
00461                 break;
00462             };
00463         }
00464         printf("===============================\n"
00465                "Done with tests\n"
00466                );
00467 
00468     } else {
00469         usage();
00470     }
00471 }

Generated on Mon Aug 16 2010 14:25:45 for FCam by  doxygen 1.7.1