• 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 Thu Jul 15 2010 17:51:29 for FCam by  doxygen 1.7.1