00001
00005 #include "intrinsics.hpp"
00006
00007 double calculateERE( Size imSize,
00008 cv::vector<Point3f>& physicalPoints,
00009 cv::vector< cv::vector<Point2f> >& corners,
00010 const Mat& cameraMatrix,
00011 const Mat& distCoeffs,
00012 bool removeSpatialBias,
00013 bool generateFigure,
00014 bool useUndistortedLocations)
00015 {
00016
00017 bool debug = false;
00018
00019
00020 if (debug) { printf("%s << physicalPoints.size() = (%d)\n", __FUNCTION__, physicalPoints.size()); }
00021 if (debug) { printf("%s << corners.size() = (%d)\n", __FUNCTION__, corners.size()); }
00022
00023 int total_points = corners.size() * corners.at(0).size();
00024
00025 Mat newCamMat;
00026 Mat identity = Mat::eye(3,3,CV_64FC1);
00027
00028 if (useUndistortedLocations) {
00029 newCamMat = getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imSize, 0.0);
00030 newCamMat = newCamMat.inv();
00031 }
00032
00033 double *errValues;
00034
00035 errValues = new double[total_points];
00036
00037 Mat projectionCountGrid, cumulativeErrorGrid;
00038
00039 if (debug) { printf("%s << REACHED (%d)\n", __FUNCTION__, 0); }
00040
00041 if (1) {
00042
00043
00044 double ratio = double(imSize.width) / double(imSize.height);
00045
00046
00047
00048 int desiredBins = min(MAX_BINS, max(MIN_BINS,total_points));
00049
00050 double numRows, numCols;
00051
00052 numRows = pow(desiredBins / ratio , 0.5);
00053 numCols = ratio * numRows;
00054
00055
00056
00057 projectionCountGrid = Mat::zeros(int(ceil(numRows)), int(ceil(numCols)), CV_16UC1);
00058 cumulativeErrorGrid = Mat::zeros(int(ceil(numRows)), int(ceil(numCols)), CV_32FC1);
00059
00060
00061
00062 }
00063
00064 if (debug) { printf("%s << REACHED (%d)\n", __FUNCTION__, 1); }
00065
00066
00067
00068 Mat fsRvec, fsTvec;
00069 cv::vector<Point2f> cornerSet;
00070 cornerSet.resize(physicalPoints.size());
00071
00072 double err = 0.0, xSum = 0, ySum = 0, tSum = 0, xMean = 0, yMean = 0, tMean = 0, xDev = 0, yDev = 0, tDev = 0;
00073
00074 Point2f imLoc, imageDec, predictedDec;
00075
00076
00077
00078 for (unsigned int i = 0; i < corners.size(); i++) {
00079
00080 if (debug) { printf("%s << Set (%d) Solving PnP...\n", __FUNCTION__, i); }
00081
00082 if (debug) { printf("%s << corners.at(%d).size() = (%d)\n", __FUNCTION__, i, corners.at(i).size()); }
00083
00084
00085 solvePnP(Mat(physicalPoints), Mat(corners.at(i)), cameraMatrix, distCoeffs, fsRvec, fsTvec, false);
00086
00087
00088
00089
00090 if (debug) { printf("%s << Projecting points...\n", __FUNCTION__); }
00091
00092
00093 projectPoints(Mat(physicalPoints), fsRvec, fsTvec, cameraMatrix, distCoeffs, cornerSet);
00094
00095
00096
00097
00098 if (debug) { printf("%s << About to start loop through points...\n",__FUNCTION__); }
00099
00100 vector<Point2f> undistortedPoints;
00101
00102 if (useUndistortedLocations) {
00103 undistortPoints(corners.at(i), undistortedPoints, cameraMatrix, distCoeffs, identity, newCamMat);
00104 }
00105
00106
00107 for (unsigned int j = 0; j < cornerSet.size(); j++) {
00108
00109 if (debug) { printf("%s << Point loop (%d)\n", __FUNCTION__, j); }
00110
00111 imageDec = Point2f(corners.at(i).at(j).x, corners.at(i).at(j).y);
00112 predictedDec = Point2f(cornerSet.at(j).x, cornerSet.at(j).y);
00113
00114 double ptError = pow(pow(imageDec.x-predictedDec.x, 2)+pow(imageDec.y-predictedDec.y, 2), 0.5);
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 if (errValues)
00127 {
00128
00129
00130
00131 errValues[i*cornerSet.size()+j] = ptError;
00132
00133
00134 }
00135
00136
00137
00138 if (1) {
00139
00140 if (debug) { printf("%s << Removing spatial bias...\n",__FUNCTION__); }
00141
00142 Point2f testPoint;
00143
00144
00145
00146 if (useUndistortedLocations) {
00147 testPoint = Point2f(undistortedPoints.at(j).x, undistortedPoints.at(j).y);
00148
00149
00150
00151 } else {
00152 testPoint = imageDec;
00153 }
00154
00155
00156 if ((testPoint.x > 0.0) && (testPoint.x < imSize.width) && (testPoint.y > 0.0) && (testPoint.y < imSize.height)) {
00157
00158
00159
00160
00161
00162 int gridRow = round( ( testPoint.y / imSize.height ) * float(projectionCountGrid.rows) - 0.5 );
00163 int gridCol = round( ( testPoint.x / imSize.width ) * float(projectionCountGrid.cols) - 0.5 );
00164
00165
00166
00167 projectionCountGrid.at<unsigned short>(gridRow, gridCol) += 1;
00168 cumulativeErrorGrid.at<float>(gridRow, gridCol) += ptError;
00169
00170
00171
00172
00173
00174 } else {
00175
00176 }
00177
00178 }
00179
00180
00181 if (debug) { printf("%s << A6\n",__FUNCTION__); }
00182
00183
00184 }
00185
00186
00187
00188 if (debug) { printf("%s << A8\n",__FUNCTION__); }
00189
00190 }
00191
00192
00193
00194 if (debug) { printf("%s << B\n",__FUNCTION__); }
00195
00196 if (1) {
00197
00198
00199
00200 tSum = 0.0;
00201 float maxAverageError = 0.0;
00202
00203 Mat heatMap, heatMapCol;
00204
00205 if (generateFigure) {
00206 heatMap = Mat::ones(imSize, CV_8UC1);
00207 heatMapCol = Mat::ones(imSize, CV_8UC3);
00208 }
00209
00210
00211
00212
00213 for (unsigned int iii = 0; iii < projectionCountGrid.rows; iii++) {
00214 for (unsigned int jjj = 0; jjj < projectionCountGrid.cols; jjj++) {
00215
00216 if (projectionCountGrid.at<unsigned short>(iii, jjj) > 0) {
00217 cumulativeErrorGrid.at<float>(iii, jjj) /= float(projectionCountGrid.at<unsigned short>(iii, jjj));
00218
00219
00220
00221 tSum += cumulativeErrorGrid.at<float>(iii, jjj);
00222
00223 if (cumulativeErrorGrid.at<float>(iii, jjj) > maxAverageError) {
00224 maxAverageError = cumulativeErrorGrid.at<float>(iii, jjj);
00225 }
00226
00227 } else {
00228
00229
00230
00231 if (generateFigure) {
00232 unsigned int startRow = round((float(iii) / float(cumulativeErrorGrid.rows)) * float(heatMap.rows));
00233 unsigned int endRow = ceil((float(iii+1) / float(cumulativeErrorGrid.rows)) * float(heatMap.rows));
00234 unsigned int startCol = round((float(jjj) / float(cumulativeErrorGrid.cols)) * float(heatMap.cols));
00235 unsigned int endCol = ceil((float(jjj+1) / float(cumulativeErrorGrid.cols)) * float(heatMap.cols));
00236
00237 for (unsigned int aaa = startRow; aaa < endRow; aaa++) {
00238 for (unsigned int bbb = startCol; bbb < endCol; bbb++) {
00239 heatMap.at<unsigned char>(aaa,bbb) = 0;
00240 heatMapCol.at<Vec3b>(aaa,bbb)[0] = 0;
00241 heatMapCol.at<Vec3b>(aaa,bbb)[1] = 0;
00242 heatMapCol.at<Vec3b>(aaa,bbb)[2] = 255;
00243 }
00244 }
00245 }
00246
00247
00248 }
00249
00250
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259 for (unsigned int iii = 0; iii < projectionCountGrid.rows; iii++) {
00260 for (unsigned int jjj = 0; jjj < projectionCountGrid.cols; jjj++) {
00261
00262 if (projectionCountGrid.at<unsigned short>(iii, jjj) == 0) {
00263 cumulativeErrorGrid.at<float>(iii, jjj) = maxAverageError;
00264 tSum += maxAverageError;
00265 }
00266
00267 }
00268 }
00269
00270
00271
00272 err = tSum / (projectionCountGrid.rows*projectionCountGrid.cols);
00273
00274
00275
00276 if (generateFigure) {
00277
00278 double lim = (1.0/5.0)*ceil(maxAverageError*5.0);
00279
00280 lim = 1.0;
00281
00282
00283
00284 for (unsigned int iii = 0; iii < heatMap.rows; iii++) {
00285 for (unsigned int jjj = 0; jjj < heatMap.cols; jjj++) {
00286
00287 unsigned int quantRow = floor((float(iii+0) / float(heatMap.rows)) * float(cumulativeErrorGrid.rows));
00288 unsigned int quantCol = floor((float(jjj+0) / float(heatMap.cols)) * float(cumulativeErrorGrid.cols));
00289
00290
00291 if (heatMap.at<unsigned char>(iii,jjj) != 0) {
00292 heatMap.at<unsigned char>(iii,jjj) = round(1.0 + 254.0 * (cumulativeErrorGrid.at<float>(quantRow, quantCol) / lim));
00293
00294 heatMapCol.at<Vec3b>(iii,jjj)[0] = heatMap.at<unsigned char>(iii,jjj);
00295 heatMapCol.at<Vec3b>(iii,jjj)[1] = heatMap.at<unsigned char>(iii,jjj);
00296 heatMapCol.at<Vec3b>(iii,jjj)[2] = heatMap.at<unsigned char>(iii,jjj);
00297 }
00298
00299
00300
00301
00302
00303 }
00304 }
00305
00306
00307
00308
00309 cScheme colourMap;
00310 colourMap.load_standard(300, 1);
00311 colourMap.falsify_image(heatMap, heatMapCol);
00312
00313 for (unsigned int iii = 0; iii < heatMap.rows; iii++) {
00314 for (unsigned int jjj = 0; jjj < heatMap.cols; jjj++) {
00315 if (heatMap.at<unsigned char>(iii,jjj) == 0) {
00316 heatMapCol.at<Vec3b>(iii,jjj)[0] = 196;
00317 heatMapCol.at<Vec3b>(iii,jjj)[1] = 196;
00318 heatMapCol.at<Vec3b>(iii,jjj)[2] = 196;
00319 }
00320 }
00321 }
00322
00323 char imageName[256];
00324 sprintf(imageName, "/home/steve/Dropbox/Steve-Peyman/jfr2013/draft/figures/intrinsics/heatmap-%3.3f.jpg", lim);
00325 imwrite(imageName, heatMapCol);
00326
00327
00328
00329
00330
00331
00332 }
00333
00334 if (debug) { printf("%s << B6\n",__FUNCTION__); }
00335
00336 }
00337
00338
00339
00340 if (!removeSpatialBias) {
00341
00342 tSum = 0.0;
00343
00344 for (unsigned int i = 0; i < corners.size(); i++) {
00345 for (unsigned int j = 0; j < cornerSet.size(); j++) {
00346
00347 if (errValues)
00348 {
00349 tSum += errValues[i*cornerSet.size()+j];
00350 }
00351
00352 }
00353 }
00354
00355 err = tSum / (corners.size()*cornerSet.size());
00356
00357
00358
00359 }
00360
00361
00362 if (errValues) { delete[] errValues; }
00363
00364 return err;
00365
00366 }
00367
00368 void optimizeCalibrationSet(Size imSize,
00369 cv::vector< cv::vector<Point2f> >& candidatePatterns,
00370 cv::vector< cv::vector<Point2f> >& testPatterns,
00371 cv::vector<Point3f> row,
00372 vector<int>& selectedTags,
00373 int selection,
00374 int num,
00375 bool debugMode,
00376 bool removeSpatialBias,
00377 bool generateFigure,
00378 bool useUndistortedLocations,
00379 int intrinsicsFlags)
00380 {
00381
00382 if (debugMode) { printf("%s << ENTERED.\n", __FUNCTION__); }
00383
00384 selectedTags.clear();
00385
00386 Mat distributionMap;
00387
00388 if (debugMode) {
00389 distributionMap = Mat::zeros(imSize, CV_8UC1);
00390 }
00391
00392
00393 if (selection == 0) {
00394 return;
00395 }
00396
00397
00398 srand ( (unsigned int)(time(NULL)) );
00399
00400
00401 cv::vector< cv::vector<Point3f> > objectPoints;
00402 Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
00403
00404 cameraMatrix.at<double>(0,2) = (double(imSize.width)-1.0)/2.0;
00405 cameraMatrix.at<double>(1,2) = (double(imSize.height)-1.0)/2.0;
00406 Mat distCoeffs = cv::Mat::zeros(1, 8, CV_64F);
00407 cv::vector<Mat> rvecs, tvecs;
00408
00409
00410 cv::vector< cv::vector<Point2f> > candidatePatternsCpy;
00411 candidatePatternsCpy.assign(candidatePatterns.begin(), candidatePatterns.end());
00412 cv::vector< cv::vector<Point2f> > fullSetCorners;
00413 fullSetCorners.assign(testPatterns.begin(), testPatterns.end());
00414 cv::vector< cv::vector<Point2f> > selectedFrames;
00415 cv::vector< cv::vector<Point2f> > tempFrameTester;
00416 cv::vector< cv::vector<Point2f> > newCorners;
00417
00418
00419 double err;
00420 Mat optimalResults(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_64FC1);
00421 Mat rankedScores(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_64FC1);
00422 Mat rankedIndices(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_8UC1);
00423
00424
00425 Mat distributionDisplay(distributionMap.size(), CV_8UC1);
00426
00427
00428 Mat binMap(30, 40, CV_32SC1);
00429 Mat binTemp(binMap.size(), CV_8UC1);
00430 binMap.setTo(0);
00431
00432
00433 double score, maxScore = 0.0;
00434 int maxIndex = 0;
00435 int rankedFrames[ABSOLUTE_MAX_FRAMES_TO_STORE];
00436 double rankedScoreVector[ABSOLUTE_MAX_FRAMES_TO_STORE];
00437 double *unrankedScores;
00438
00439 vector<int> addedIndices;
00440 double bestScore = 0.0, topScore = 0.0;
00441 int bestIndex;
00442
00443 vector<unsigned int> currentIndices, topIndices, bestIndices;
00444
00445
00446 double prevBestScore = 9e99;
00447 int optimumNum = 0;
00448 unsigned long int possibleCombos;
00449
00450
00451 Mat gaussianMat(binMap.size().height, binMap.size().width, CV_64FC1);
00452 createGaussianMatrix(gaussianMat, 0.3);
00453
00454
00455 int randomNum = 0;
00456 double testingProbability = 1.00;
00457
00458 double bestErr = 9e99;
00459
00460
00461 int nTrials = 20;
00462
00463 double median, p90, p99;
00464
00465 double *values;
00466
00467
00468
00469 values = new double[num*nTrials];
00470
00471
00472
00473
00474
00475
00476
00477 num = min((int)num, (int)candidatePatterns.size());
00478
00479
00480 int nSeeds = 5;
00481 int nSeedTrials = 500;
00482
00483 int *bestSeedSet, *currentSeedSet;
00484
00485 double bestSeedScore = 9e50, currentSeedScore;
00486
00487 bool alreadyUsed;
00488
00489 int newRandomNum;
00490
00491 double radialDistribution[RADIAL_LENGTH];
00492
00493 vector<int> tagNames;
00494
00495 for (unsigned int iii = 0; iii < candidatePatterns.size(); iii++) {
00496 tagNames.push_back(iii);
00497 }
00498
00499
00500 for (int i = 0; i < RADIAL_LENGTH; i++)
00501 {
00502 radialDistribution[i] = 0.0;
00503 }
00504
00505
00506
00507 if (debugMode) { printf("%s << About to enter switch...\n", __FUNCTION__); }
00508
00509 switch (selection)
00510 {
00511
00512 case SCORE_BASED_OPTIMIZATION_CODE:
00513
00514
00515 while (newCorners.size() < (unsigned int)(num))
00516 {
00517 maxScore = 0.0;
00518 maxIndex = 0;
00519
00520
00521 for (unsigned int i = 0; i < candidatePatterns.size(); i++)
00522 {
00523 score = obtainSetScore(distributionMap, binMap, gaussianMat, candidatePatterns.at(i), radialDistribution);
00524
00525 if (score > maxScore)
00526 {
00527 maxScore = score;
00528 maxIndex = i;
00529 }
00530 else if (score < 0)
00531 {
00532 printf("%s << ERROR. Negative score. Returning.\n", __FUNCTION__);
00533 return;
00534 }
00535 }
00536
00537
00538
00539
00540 newCorners.push_back(candidatePatterns.at(maxIndex));
00541
00542 addToDistributionMap(distributionMap, newCorners.at(newCorners.size()-1));
00543 addToRadialDistribution(radialDistribution, newCorners.at(newCorners.size()-1), distributionMap.size());
00544
00545 prepForDisplay(distributionMap, distributionDisplay);
00546 imshow("distributionMap", distributionDisplay);
00547
00548 addToBinMap(binMap, newCorners.at(newCorners.size()-1), distributionMap.size());
00549 convertScaleAbs(binMap, binTemp);
00550 simpleResize(binTemp, distributionDisplay, Size(480, 640));
00551 equalizeHist(distributionDisplay, distributionDisplay);
00552
00553
00554 waitKey( 0 );
00555
00556 candidatePatterns.erase(candidatePatterns.begin()+maxIndex);
00557 }
00558
00559 candidatePatterns.clear();
00560 newCorners.swap(candidatePatterns);
00561 break;
00562
00563 case RANDOM_SET_OPTIMIZATION_CODE:
00564
00565 for (int i = 0; i < num; i++)
00566 {
00567 randomNum = rand() % int(candidatePatterns.size());
00568 newCorners.push_back(candidatePatterns.at(randomNum));
00569 candidatePatterns.erase(candidatePatterns.begin()+randomNum);
00570 selectedTags.push_back(tagNames.at(randomNum));
00571
00572 addToDistributionMap(distributionMap, newCorners.at(i));
00573 prepForDisplay(distributionMap, distributionDisplay);
00574 imshow("distributionMap", distributionDisplay);
00575 waitKey(40);
00576 }
00577
00578 candidatePatterns.clear();
00579 newCorners.swap(candidatePatterns);
00580 break;
00581
00582 case FIRST_N_PATTERNS_OPTIMIZATION_CODE:
00583
00584 while (candidatePatterns.size() > (unsigned int)(num))
00585 {
00586 candidatePatterns.pop_back();
00587 }
00588
00589 for (int i = 0; i < num; i++)
00590 {
00591 addToDistributionMap(distributionMap, candidatePatterns.at(i));
00592 selectedTags.push_back(tagNames.at(i));
00593 prepForDisplay(distributionMap, distributionDisplay);
00594 imshow("distributionMap", distributionDisplay);
00595 waitKey(40);
00596 }
00597
00598 delete[] values;
00599
00600 return;
00601
00602 case ENHANCED_MCM_OPTIMIZATION_CODE:
00603
00604
00605 if (debugMode) { printf("%s << ENTERED. (%d)\n", __FUNCTION__, 2); }
00606 selectedFrames.clear();
00607
00608 unrankedScores = new double[candidatePatternsCpy.size()];
00609
00610 prevBestScore = 9e50;
00611
00612
00613
00614 for (int N = 0; N < num; N++)
00615 {
00616
00617 if (debugMode) { printf("%s << N = (%d / %d)\n", __FUNCTION__, N, num); }
00618
00619 objectPoints.push_back(row);
00620
00621
00622
00623 for (unsigned int i = 0; i < candidatePatternsCpy.size(); i++)
00624 {
00625
00626 if (debugMode) { printf("%s << i = (%d / %d)\n", __FUNCTION__, i, candidatePatternsCpy.size()); }
00627
00628 tempFrameTester.clear();
00629
00630 if (debugMode) { printf("%s << i = (%d / %d) {%d}\n", __FUNCTION__, i, candidatePatternsCpy.size(), 0); }
00631
00632 tempFrameTester.assign(selectedFrames.begin(), selectedFrames.end());
00633
00634 if (debugMode) { printf("%s << i = (%d / %d) {%d}\n", __FUNCTION__, i, candidatePatternsCpy.size(), 1); }
00635
00636 tempFrameTester.push_back(candidatePatternsCpy.at(i));
00637
00638 if (debugMode) { printf("%s << i = (%d / %d) {%d}\n", __FUNCTION__, i, candidatePatternsCpy.size(), 2); }
00639
00640 bool alreadyAdded = false;
00641
00642 for (int k = 0; k < addedIndices.size(); k++)
00643 {
00644
00645 if (debugMode) { printf("%s << k = (%d / %d)\n", __FUNCTION__, k, addedIndices.size()); }
00646
00647 if (i == addedIndices.at(k))
00648 {
00649 alreadyAdded = true;
00650
00651 }
00652 }
00653
00654 if (debugMode) { printf("%s << i = (%d / %d) {%d}\n", __FUNCTION__, i, candidatePatternsCpy.size(), 3); }
00655
00656 if (alreadyAdded == true)
00657 {
00658 err = -1.0;
00659 }
00660 else
00661 {
00662
00663 randomNum = rand() % 1000 + 1;
00664
00665 Mat fovMat, errMat;
00666 double fovScore, errScore;
00667
00668 if (randomNum > (1 - testingProbability)*1000.0)
00669 {
00670
00671
00672
00673
00674
00675
00676 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, intrinsicsFlags);
00677
00678
00679
00680
00681
00682
00683
00684 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs, removeSpatialBias, false, useUndistortedLocations);
00685
00686 }
00687 else
00688 {
00689
00690 err = -1.0;
00691 }
00692
00693 }
00694
00695 if (debugMode) { printf("%s << i = (%d / %d) {%d}\n", __FUNCTION__, i, candidatePatternsCpy.size(), 4); }
00696
00697 unrankedScores[i] = err;
00698
00699
00700
00701
00702 }
00703
00704 bestScore = 9e50;
00705 bestIndex = 0;
00706
00707 if (debugMode) { printf("%s << X {%d}\n", __FUNCTION__, 0); }
00708
00709 for (unsigned int j = 0; j < candidatePatternsCpy.size(); j++)
00710 {
00711
00712 if (debugMode) { printf("%s << j = (%d / %d)\n", __FUNCTION__, j, candidatePatternsCpy.size()); }
00713
00714 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0))
00715 {
00716 bestScore = unrankedScores[j];
00717 bestIndex = j;
00718 }
00719 }
00720
00721 unrankedScores[bestIndex] = 9e50;
00722
00723
00724
00725 selectedFrames.push_back(candidatePatternsCpy.at(bestIndex));
00726
00727
00728 for (unsigned int i = 0; i < candidatePatternsCpy.at(bestIndex).size(); i++)
00729 {
00730 if (debugMode) { printf("%s << i(%d) = (%d / %d)\n", __FUNCTION__, bestIndex, i, candidatePatternsCpy.at(bestIndex).size()); }
00731 candidatePatternsCpy.at(bestIndex).at(i) = Point2f(0.0,0.0);
00732 }
00733
00734 addedIndices.push_back(bestIndex);
00735
00736 if (bestScore < prevBestScore)
00737 {
00738 prevBestScore = bestScore;
00739 optimumNum = N;
00740 }
00741
00742
00743 printf("%s << (%d) frames considered; best generalized error so far = (%f)\n", __FUNCTION__, N+1, prevBestScore);
00744
00745
00746 }
00747
00748 delete[] unrankedScores;
00749
00750 if (debugMode) { printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, optimumNum+1); }
00751
00752 candidatePatterns.clear();
00753 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.begin() + optimumNum+1);
00754
00755 for (int i = 0; i < optimumNum+1; i++)
00756 {
00757 selectedTags.push_back(tagNames.at(addedIndices.at(i)));
00758 }
00759
00760 if (debugMode) {
00761
00762 printf("%s << Attempting to add patterns to distribution map..\n", __FUNCTION__);
00763
00764 for (int iii = 0; iii < candidatePatterns.size(); iii++) {
00765 printf("%s << Adding pattern (%d)..\n", __FUNCTION__, iii);
00766 addToDistributionMap(distributionMap, candidatePatterns.at(iii));
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 if (generateFigure) {
00780
00781
00782 prepForDisplay(distributionMap, distributionDisplay);
00783
00784 imwrite("/home/steve/Dropbox/Steve-Peyman/jfr2013/draft/figures/intrinsics/point_distribution.jpg", distributionDisplay);
00785
00786 }
00787
00788 }
00789
00790
00791
00792
00793 break;
00794
00795 case RANDOM_SEED_OPTIMIZATION_CODE:
00796
00797
00798 selectedFrames.clear();
00799
00800 unrankedScores = new double[candidatePatternsCpy.size()];
00801
00802 prevBestScore = 9e50;
00803
00804
00805
00806
00807
00808 bestSeedSet = new int[nSeeds];
00809 currentSeedSet = new int[nSeeds];
00810
00811
00812
00813 for (int iii = 0; iii < nSeedTrials; iii++)
00814 {
00815
00816 objectPoints.clear();
00817 tempFrameTester.clear();
00818
00819 randomNum = rand() % candidatePatternsCpy.size();
00820
00821 currentSeedSet[0] = randomNum;
00822 objectPoints.push_back(row);
00823
00824
00825 tempFrameTester.push_back(candidatePatternsCpy.at(currentSeedSet[0]));
00826
00827 for (int jjj = 1; jjj < nSeeds; jjj++)
00828 {
00829 do
00830 {
00831 alreadyUsed = false;
00832
00833 randomNum = rand() % candidatePatternsCpy.size();
00834
00835 for (int kkk = 0; kkk < jjj; kkk++)
00836 {
00837 if (randomNum == currentSeedSet[kkk])
00838 {
00839 alreadyUsed = true;
00840 }
00841 }
00842 }
00843 while (alreadyUsed);
00844
00845 currentSeedSet[jjj] = randomNum;
00846
00847 objectPoints.push_back(row);
00848 tempFrameTester.push_back(candidatePatternsCpy.at(currentSeedSet[jjj]));
00849 }
00850
00851 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, intrinsicsFlags);
00852
00853 currentSeedScore = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs, removeSpatialBias, false, useUndistortedLocations);
00854
00855 if (currentSeedScore < bestSeedScore)
00856 {
00857 bestSeedScore = currentSeedScore;
00858
00859 printf("%s << Best seed score [trial = %d]: %f\n", __FUNCTION__, iii, bestSeedScore);
00860
00861 for (int jjj = 0; jjj < nSeeds; jjj++)
00862 {
00863 bestSeedSet[jjj] = currentSeedSet[jjj];
00864 }
00865
00866 }
00867
00868 }
00869
00870 for (int jjj = 0; jjj < nSeeds; jjj++)
00871 {
00872 selectedFrames.push_back(candidatePatternsCpy.at(bestSeedSet[jjj]));
00873 unrankedScores[bestSeedSet[jjj]] = 9e50;
00874
00875
00876 for (unsigned int kkk = 0; kkk < candidatePatternsCpy.at(bestSeedSet[jjj]).size(); kkk++)
00877 {
00878 candidatePatternsCpy.at(bestSeedSet[jjj]).at(kkk) = Point2f(0.0,0.0);
00879 }
00880
00881 addedIndices.push_back(bestSeedSet[jjj]);
00882 }
00883
00884 bestScore = bestSeedScore;
00885
00886
00887 optimumNum = nSeeds-1;
00888
00889 for (int N = nSeeds; N < num; N++)
00890 {
00891
00892 objectPoints.push_back(row);
00893
00894
00895
00896 for (unsigned int i = 0; i < candidatePatternsCpy.size(); i++)
00897 {
00898
00899 tempFrameTester.clear();
00900 tempFrameTester.assign(selectedFrames.begin(), selectedFrames.end());
00901 tempFrameTester.push_back(candidatePatternsCpy.at(i));
00902
00903 bool alreadyAdded = false;
00904
00905 for (int k = 0; k < addedIndices.size(); k++)
00906 {
00907 if (i == addedIndices.at(k))
00908 {
00909 alreadyAdded = true;
00910
00911 }
00912 }
00913
00914 if (alreadyAdded == true)
00915 {
00916 err = -1.0;
00917 }
00918 else
00919 {
00920
00921 randomNum = rand() % 1000 + 1;
00922
00923 Mat fovMat, errMat;
00924 double fovScore, errScore;
00925
00926 if (randomNum > (1 - testingProbability)*1000.0)
00927 {
00928
00929
00930
00931
00932 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, intrinsicsFlags);
00933
00934
00935
00936 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs, removeSpatialBias, false, useUndistortedLocations);
00937
00938 }
00939 else
00940 {
00941
00942 err = -1.0;
00943 }
00944
00945 }
00946
00947 unrankedScores[i] = err;
00948
00949 }
00950
00951 bestScore = 9e50;
00952 bestIndex = 0;
00953
00954 for (unsigned int j = 0; j < candidatePatternsCpy.size(); j++)
00955 {
00956
00957 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0))
00958 {
00959 bestScore = unrankedScores[j];
00960 bestIndex = j;
00961 }
00962 }
00963
00964 unrankedScores[bestIndex] = 9e50;
00965
00966 printf("%s << Best score for %d frame calibration: %f\n", __FUNCTION__, N+1, bestScore);
00967
00968 selectedFrames.push_back(candidatePatternsCpy.at(bestIndex));
00969
00970
00971 for (unsigned int i = 0; i < candidatePatternsCpy.at(bestIndex).size(); i++)
00972 {
00973 candidatePatternsCpy.at(bestIndex).at(i) = Point2f(0.0,0.0);
00974 }
00975
00976 addedIndices.push_back(bestIndex);
00977
00978 if (bestScore < prevBestScore)
00979 {
00980 prevBestScore = bestScore;
00981 optimumNum = N;
00982 }
00983
00984 }
00985
00986 delete[] unrankedScores;
00987
00988 printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, optimumNum+1);
00989
00990 candidatePatterns.clear();
00991 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.begin() + optimumNum+1);
00992
00993 for (int i = 0; i < optimumNum+1; i++)
00994 {
00995 selectedTags.push_back(tagNames.at(addedIndices.at(i)));
00996 }
00997
00998 break;
00999
01000 case EXHAUSTIVE_SEARCH_OPTIMIZATION_CODE:
01001
01002
01003 if (candidatePatternsCpy.size() > 20)
01004 {
01005 printf("%s << Too many frames for exhaustive approach.\n", __FUNCTION__);
01006 break;
01007 }
01008 else
01009 {
01010 printf("%s << Searching for absolute optimum.\n", __FUNCTION__);
01011 }
01012
01013 bestScore = 9e99;
01014
01015
01016 for (int N = 0; N < num; N++)
01017 {
01018
01019 topScore = 9e99;
01020
01021 printf("%s << N(+1) = %d\n", __FUNCTION__, N+1);
01022
01023 objectPoints.push_back(row);
01024
01025 possibleCombos = 1;
01026
01027 possibleCombos = factorial(candidatePatternsCpy.size()) / (factorial(N+1) * factorial(candidatePatternsCpy.size() - N - 1));
01028
01029 printf("%s << possibleCombos = %d\n", __FUNCTION__, possibleCombos);
01030
01031 currentIndices.clear();
01032
01033
01034 for (unsigned int i = 0; i < possibleCombos; i++)
01035 {
01036
01037 tempFrameTester.clear();
01038 getNextCombo(currentIndices, N+1, candidatePatternsCpy.size());
01039
01040 for (int j = 0; j < currentIndices.size(); j++)
01041 {
01042
01043 tempFrameTester.push_back(candidatePatternsCpy.at(currentIndices.at(j)));
01044 }
01045
01046 err = calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, intrinsicsFlags);
01047
01048 Mat fovMat, errMat;
01049 double fovScore, errScore;
01050
01051 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs, removeSpatialBias, false, useUndistortedLocations);
01052
01053 if (err < topScore)
01054 {
01055 topScore = err;
01056 topIndices.clear();
01057 topIndices.assign(currentIndices.begin(), currentIndices.end());
01058 }
01059
01060 if (err < bestScore)
01061 {
01062 bestScore = err;
01063 bestIndices.clear();
01064 bestIndices.assign(currentIndices.begin(), currentIndices.end());
01065 }
01066
01067 }
01068
01069 printf("%s << topScore [(N+1) = %d] = %f\n", __FUNCTION__, N+1, topScore);
01070
01071 for (int j = 0; j < topIndices.size(); j++)
01072 {
01073 printf("%s << topIndices.at(%d) = %d\n", __FUNCTION__, j, topIndices.at(j));
01074 }
01075
01076 }
01077
01078 candidatePatterns.clear();
01079
01080 printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, bestIndices.size());
01081 printf("%s << bestScore = %f\n", __FUNCTION__, bestScore);
01082
01083 for (unsigned int i = 0; i < bestIndices.size(); i++)
01084 {
01085 printf("%s << bestIndices.at(%d) = %d\n", __FUNCTION__, i, bestIndices.at(i));
01086 candidatePatterns.push_back(candidatePatternsCpy.at(bestIndices.at(i)));
01087 }
01088
01089 break;
01090
01091 case BEST_OF_RANDOM_PATTERNS_OPTIMIZATION_CODE:
01092
01093
01094 bestErr = 9e99;
01095
01096 printf("%s << Random trial selection\n", __FUNCTION__);
01097
01098 for (unsigned int k = 0; k < nTrials; k++)
01099 {
01100
01101
01102
01103 objectPoints.clear();
01104 candidatePatterns.clear();
01105 currentIndices.clear();
01106 newCorners.clear();
01107
01108 candidatePatterns.assign(candidatePatternsCpy.begin(), candidatePatternsCpy.end());
01109
01110 for (int N = 0; N < num; N++)
01111 {
01112
01113 objectPoints.push_back(row);
01114 randomNum = rand() % int(candidatePatterns.size());
01115 currentIndices.push_back(randomNum);
01116 newCorners.push_back(candidatePatterns.at(randomNum));
01117 candidatePatterns.erase(candidatePatterns.begin()+randomNum);
01118
01119
01120 err = calibrateCamera(objectPoints, newCorners, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, intrinsicsFlags);
01121
01122 Mat fovMat, errMat;
01123 double fovScore, errScore;
01124 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs, removeSpatialBias, false, useUndistortedLocations);
01125
01126 values[N*nTrials+k] = err;
01127
01128
01129
01130 if (err < bestErr)
01131 {
01132 bestErr = err;
01133 bestIndices.clear();
01134
01135 selectedFrames.clear();
01136
01137 bestIndices.assign(currentIndices.begin(), currentIndices.end());
01138
01139 selectedFrames.assign(newCorners.begin(), newCorners.end());
01140
01141
01142 }
01143 }
01144 }
01145
01146 candidatePatterns.clear();
01147
01148 for (int N = 0; N < num; N++)
01149 {
01150 median = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.5);
01151 p90 = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.9);
01152 p99 = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.99);
01153
01154
01155 }
01156
01157 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.end());
01158
01159 break;
01160 default:
01161
01162 delete[] values;
01163
01164 return;
01165 }
01166
01167
01168 delete[] values;
01169
01170 }