00001
00005 #include "extrinsics.hpp"
00006
00007 double calculateExtrinsicERE(int nCams,
00008 cv::vector<Point3f>& physicalPoints,
00009 cv::vector< cv::vector<Point2f> > *corners,
00010 Mat *cameraMatrix,
00011 Mat *distCoeffs,
00012 Mat *R,
00013 Mat *T)
00014 {
00015
00016 int ptsPerSet = physicalPoints.size();
00017 int numFrames = corners[0].size();
00018
00019 Mat *fsRvec, *fsTvec, *esRvec, *esTvec;
00020 fsRvec = new Mat[nCams];
00021 fsTvec = new Mat[nCams];
00022 esRvec = new Mat[nCams];
00023 esTvec = new Mat[nCams];
00024
00025 cv::vector<Point2f> *estimatedPattern, *projectedPattern;
00026 estimatedPattern = new cv::vector<Point2f>[nCams];
00027 projectedPattern = new cv::vector<Point2f>[nCams];
00028
00029 for (int k = 0; k < nCams; k++)
00030 {
00031 estimatedPattern[k].resize(physicalPoints.size());
00032 projectedPattern[k].resize(physicalPoints.size());
00033 }
00034
00035 double *errors;
00036
00037 double tSum = 0;
00038
00039 double xError, yError;
00040
00041 int maxCapacity = numFrames*ptsPerSet*nCams;
00042
00043 errors = new double[maxCapacity];
00044
00045 Mat physPtsMat = Mat(physicalPoints);
00046 Mat cornersMat;
00047
00048 int index = 0;
00049
00050 for (int i = 0; i < numFrames; i++)
00051 {
00052
00053 for (int k = 0; k < nCams; k++)
00054 {
00055
00056 cornersMat = Mat(corners[k].at(i));
00057
00058 solvePnP(physPtsMat, cornersMat, cameraMatrix[k], distCoeffs[k], fsRvec[k], fsTvec[k], false);
00059
00060 projectPoints(Mat(physicalPoints), fsRvec[k], fsTvec[k], cameraMatrix[k], distCoeffs[k], estimatedPattern[k]);
00061
00062 esRvec[k] = R[k] * fsRvec[0];
00063
00064 esTvec[k] = fsTvec[0] + T[k];
00065
00066 projectPoints(Mat(physicalPoints), esRvec[k], esTvec[k], cameraMatrix[k], distCoeffs[k], projectedPattern[k]);
00067
00068 for (unsigned int j = 0; j < estimatedPattern[k].size(); j++)
00069 {
00070
00071 xError = abs(projectedPattern[k].at(j).x - estimatedPattern[k].at(j).x);
00072 yError = abs(projectedPattern[k].at(j).y - estimatedPattern[k].at(j).y);
00073
00074 errors[index] = pow(pow(xError, 2)+pow(yError, 2), 0.5);
00075
00076 tSum += (errors[index] / (double(ptsPerSet) * double(nCams)));
00077
00078 index++;
00079 }
00080
00081 }
00082 }
00083
00084 double err = tSum / double(numFrames);
00085
00086 delete[] fsRvec;
00087 delete[] fsTvec;
00088 delete[] esRvec;
00089 delete[] esTvec;
00090
00091 delete[] estimatedPattern;
00092 delete[] projectedPattern;
00093
00094 delete[] errors;
00095
00096
00097
00098 return err;
00099
00100 }
00101
00102 double obtainMultisetScore(int nCams, vector<Mat>& distributionMap, vector<Mat>& binMap, vector<vector<double> >& distances, cv::vector<cv::vector<Point2f> > *corners, int index)
00103 {
00104 double score = 0.0;
00105 double *viewScore;
00106 viewScore = new double[nCams];
00107
00108 cv::vector<Point> hull;
00109 cv::vector<Point2f> hull2;
00110 double area;
00111 cv::vector<cv::vector<double> > distancesCpy;
00112
00113
00114
00115 Point centroid, center;
00116
00117 double *distFromCenter, *proportionOfView;
00118 distFromCenter = new double[nCams];
00119 proportionOfView = new double[nCams];
00120
00121 printf("KHAAAN!!! 2\n");
00122
00123
00124 for (int k = 0; k < nCams; k++)
00125 {
00126 printf("K00\n");
00127 center = Point((distributionMap.at(k).size().width-1)/2, (distributionMap.at(k).size().height-1)/2);
00128
00129 printf("K01\n");
00130
00131 convexHull(Mat(corners[k].at(index)), hull2);
00132
00133 convertVectorToPoint(hull2, hull);
00134
00135 printf("K02\n");
00136
00137 centroid = findCentroid(hull);
00138 distFromCenter[k] = distBetweenPts(centroid, center);
00139
00140 printf("K03\n");
00141
00142 area = contourArea(Mat(hull));
00143 proportionOfView[k] = area;
00144
00145
00146
00147
00148
00149 viewScore[k] = 1/(distBetweenPts(centroid, center));
00150
00151
00152 score += viewScore[k];
00153 }
00154
00155 delete[] viewScore;
00156
00157 delete[] distFromCenter;
00158 delete[] proportionOfView;
00159
00160
00161
00162
00163
00164
00165
00166 return score;
00167 }
00168
00169 void optimizeCalibrationSets(cv::vector<Size> imSize,
00170 int nCams,
00171 Mat *cameraMatrix,
00172 Mat *distCoeffs,
00173 cv::vector<Mat>& distributionMap,
00174 cv::vector< cv::vector<Point2f> > *candidateCorners,
00175 cv::vector< cv::vector<Point2f> > *testCorners,
00176 cv::vector<Point3f> row,
00177 int selection, int num,
00178 cv::vector<cv::vector<int> >& tagNames,
00179 cv::vector<cv::vector<int> >& selectedTags,
00180 int flags)
00181 {
00182
00183 srand ( time(NULL) );
00184
00185 cv::Mat currentBest_cameraMatrix[MAX_CAMS], currentBest_distCoeffs[MAX_CAMS];
00186
00187
00188
00189
00190 if (selection == 0)
00191 {
00192 return;
00193 }
00194
00195 char windowName[20];
00196
00197 int randomNum = 0;
00198 cv::vector<Mat> distributionDisplay(nCams);
00199 cv::vector<Mat> binMap(nCams);
00200 cv::vector<Mat> binTemp(nCams);
00201 cv::vector<cv::vector<double> > distances(nCams);
00202
00203
00204 double score, maxScore = 0.0;
00205 int maxIndex = 0;
00206
00207
00208 double *unrankedScores;
00209 unrankedScores = new double[candidateCorners[0].size()];
00210
00211 vector<int> addedIndices;
00212 double bestScore = 0.0;
00213 int bestIndex;
00214 double err;
00215
00216
00217 double prevBestScore = 9e99;
00218 int optimumNum = 0;
00219
00220 double testingProbability = 1.00;
00221
00222 cv::vector< cv::vector<Point3f> > objectPoints;
00223
00224 cv::vector< cv::vector< cv::vector<Point2f> > > originalFramesCpy;
00225 cv::vector< cv::vector< cv::vector<Point2f> > > selectedFrames;
00226 cv::vector< cv::vector< cv::vector<Point2f> > > tempFrameTester;
00227 cv::vector< cv::vector< cv::vector<Point2f> > > newCorners;
00228
00229 originalFramesCpy.resize(nCams);
00230 selectedFrames.resize(nCams);
00231 tempFrameTester.resize(nCams);
00232 newCorners.resize(nCams);
00233
00234
00235
00236 for (int i = 0; i < nCams; i++) {
00237
00238 cameraMatrix[i].copyTo(currentBest_cameraMatrix[i]);
00239 distCoeffs[i].copyTo(currentBest_distCoeffs[i]);
00240
00241 imSize.at(i) = distributionMap.at(i).size();
00242
00243 distributionDisplay.at(i) = Mat(distributionMap.at(i).size(), CV_8UC1);
00244 binMap.at(i) = Mat(30, 40, CV_32SC1);
00245 binTemp.at(i) = Mat(binMap.at(i).size(), CV_8UC1);
00246 binMap.at(i).setTo(0);
00247
00248
00249 originalFramesCpy.at(i).assign(candidateCorners[i].begin(), candidateCorners[i].end());
00250
00251
00252 }
00253
00254 Mat E[MAX_CAMS], F[MAX_CAMS], Q;
00255 Mat R[MAX_CAMS], T[MAX_CAMS];
00256
00257
00258
00259 TermCriteria term_crit;
00260 term_crit = TermCriteria(TermCriteria::COUNT+ TermCriteria::EPS, 30, 1e-6);
00261
00262 bool alreadyAdded = false;
00263
00264
00265
00266
00267 int nSeeds = 3;
00268 int nSeedTrials = 50;
00269
00270 int *bestSeedSet, *currentSeedSet;
00271
00272 double bestSeedScore = 9e50, currentSeedScore;
00273
00274 bool alreadyUsed;
00275
00276
00277
00278 switch (selection)
00279 {
00280
00281 case SCORE_BASED_OPTIMIZATION_CODE:
00282
00283
00284 while (newCorners.at(0).size() < (unsigned int)(num))
00285 {
00286
00287 printf("%s << newCorners.at(0).size() = %d; num = %d\n", __FUNCTION__, newCorners.at(0).size(), num);
00288
00289 maxIndex = 0;
00290 maxScore = 0;
00291
00292
00293 for (unsigned int i = 0; i < candidateCorners[0].size(); i++)
00294 {
00295 score = obtainMultisetScore(nCams, distributionMap, binMap, distances, candidateCorners, i);
00296 printf("%s << Frame [%d] score %f\n", __FUNCTION__, i, score);
00297 if (score > maxScore)
00298 {
00299 maxScore = score;
00300 maxIndex = i;
00301 }
00302 else if (score < 0)
00303 {
00304 printf("%s << ERROR. Negative score. Returning.\n", __FUNCTION__);
00305 delete[] unrankedScores;
00306 return;
00307 }
00308 }
00309
00310 printf("%s << Top scoring frame-set #%d gets %f\n", __FUNCTION__, maxIndex, maxScore);
00311
00312 for (int k = 0; k < nCams; k++)
00313 {
00314
00315
00316 newCorners.at(k).push_back(candidateCorners[k].at(maxIndex));
00317
00318
00319 addToDistributionMap(distributionMap.at(k), newCorners.at(k).at(newCorners.at(k).size()-1));
00320
00321
00322 equalizeHist(distributionMap.at(k), distributionDisplay.at(k));
00323
00324
00325 sprintf(windowName, "distributionMap-%d", k);
00326
00327
00328
00329
00330
00331
00332
00333
00334 addToBinMap(binMap.at(k), newCorners.at(k).at(newCorners.at(k).size()-1), distributionMap.at(k).size());
00335
00336
00337 convertScaleAbs(binMap.at(k), binTemp.at(k));
00338
00339
00340
00341
00342 simpleResize(binTemp.at(k), distributionDisplay.at(k), Size(480, 640));
00343
00344
00345 equalizeHist(distributionDisplay.at(k), distributionDisplay.at(k));
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 candidateCorners[k].erase(candidateCorners[k].begin()+maxIndex);
00359
00360
00361 }
00362
00363
00364
00365
00366 }
00367
00368 for (int k = 0; k < nCams; k++) {
00369 candidateCorners[k].clear();
00370 newCorners.at(k).swap(candidateCorners[k]);
00371 }
00372
00373
00374 break;
00375
00376 case RANDOM_SET_OPTIMIZATION_CODE:
00377
00378
00379 for (int i = 0; i < num; i++)
00380 {
00381 randomNum = rand() % candidateCorners[0].size();
00382
00383 for (int k = 0; k < nCams; k++)
00384 {
00385 newCorners.at(k).push_back(candidateCorners[k].at(randomNum));
00386
00387 addToDistributionMap(distributionMap.at(k), newCorners.at(k).at(i));
00388 equalizeHist(distributionMap.at(k), distributionDisplay.at(k));
00389 sprintf(windowName, "distributionMap-%d", k);
00390
00391
00392 }
00393
00394
00395
00396 }
00397
00398 for (int k = 0; k < nCams; k++) {
00399 candidateCorners[k].clear();
00400 newCorners.at(k).swap(candidateCorners[k]);
00401 }
00402
00403 break;
00404
00405 case FIRST_N_PATTERNS_OPTIMIZATION_CODE:
00406
00407 while (candidateCorners[0].size() > (unsigned int)(num))
00408 {
00409 for (int k = 0; k < nCams; k++)
00410 {
00411 candidateCorners[k].pop_back();
00412 }
00413 }
00414
00415 for (int i = 0; i < num; i++)
00416 {
00417
00418 for (int k = 0; k < nCams; k++)
00419 {
00420
00421 addToDistributionMap(distributionMap.at(k), candidateCorners[k].at(i));
00422 equalizeHist(distributionMap.at(k), distributionDisplay.at(k));
00423 sprintf(windowName, "distributionMap-%d", k);
00424 imshow(windowName, distributionDisplay.at(k));
00425
00426 }
00427
00428
00429
00430 }
00431
00432 delete[] unrankedScores;
00433
00434 return;
00435
00436 case ENHANCED_MCM_OPTIMIZATION_CODE:
00437
00438
00439
00440
00441 for (int k = 0; k < nCams; k++) {
00442 selectedFrames.at(k).clear();
00443 }
00444
00445 prevBestScore = 9e50;
00446
00447
00448
00449
00450 for (int N = 0; N < num; N++) {
00451
00452
00453
00454 Mat iterationBest_cameraMatrix[MAX_CAMS], iterationBest_distCoeffs[MAX_CAMS];
00455
00456 for (int k = 0; k < nCams; k++) {
00457
00458 currentBest_cameraMatrix[k].copyTo(iterationBest_cameraMatrix[k]);
00459 currentBest_distCoeffs[k].copyTo(iterationBest_distCoeffs[k]);
00460
00461 }
00462
00463 objectPoints.push_back(row);
00464
00465 double prev_best_err = -1.0;
00466
00467
00468 for (unsigned int i = 0; i < originalFramesCpy.at(0).size(); i++) {
00469
00470
00471
00472 for (int k = 0; k < nCams; k++) {
00473 tempFrameTester.at(k).assign(selectedFrames.at(k).begin(), selectedFrames.at(k).end());
00474 tempFrameTester.at(k).push_back(originalFramesCpy.at(k).at(i));
00475 }
00476
00477
00478
00479 alreadyAdded = false;
00480
00481
00482 for (unsigned int k = 0; k < addedIndices.size(); k++) {
00483 if (i == int(addedIndices.at(k))) {
00484 alreadyAdded = true;
00485 }
00486 }
00487
00488
00489
00490 Mat working_cameraMatrix[MAX_CAMS], working_distCoeffs[MAX_CAMS];
00491
00492
00493 if (alreadyAdded == true) {
00494 err = -1.0;
00495 } else {
00496 randomNum = rand() % 1000 + 1;
00497
00498
00499
00500 if (randomNum > (1.0 - testingProbability)*1000.0) {
00501
00502 R[0] = Mat::eye(3, 3, CV_64FC1);
00503 T[0] = Mat::zeros(3, 1, CV_64FC1);
00504
00505
00506
00507
00508 for (int k = 0; k < nCams; k++) {
00509
00510 currentBest_cameraMatrix[k].copyTo(working_cameraMatrix[k]);
00511 currentBest_distCoeffs[k].copyTo(working_distCoeffs[k]);
00512
00513 }
00514
00515 for (int k = 0; k < nCams-1; k++) {
00516
00517
00518
00519 stereoCalibrate(objectPoints,
00520 tempFrameTester.at(0), tempFrameTester.at(k+1),
00521 working_cameraMatrix[0], working_distCoeffs[0],
00522 working_cameraMatrix[k+1], working_distCoeffs[k+1],
00523 imSize[0],
00524 R[k+1], T[k+1], E[k+1], F[k+1],
00525 term_crit,
00526 flags);
00527
00528 }
00529
00530 err = calculateExtrinsicERE(nCams, objectPoints.at(0), testCorners, working_cameraMatrix, working_distCoeffs, R, T);
00531
00532
00533
00534 if ( (err != -1.0) && ( (prev_best_err == -1.0) || (err < prev_best_err) ) ) {
00535 prev_best_err = err;
00536
00537 for (int k = 0; k < nCams; k++) {
00538
00539 working_cameraMatrix[k].copyTo(iterationBest_cameraMatrix[k]);
00540 working_distCoeffs[k].copyTo(iterationBest_distCoeffs[k]);
00541
00542 }
00543 }
00544
00545 } else {
00546 err = -1.0;
00547 }
00548
00549 }
00550
00551
00552
00553 unrankedScores[i] = err;
00554 }
00555
00556
00557
00558 bestScore = 9e50;
00559 bestIndex = 0;
00560
00561 for (unsigned int j = 0; j < originalFramesCpy.at(0).size(); j++) {
00562
00563 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0.0)) {
00564 bestScore = unrankedScores[j];
00565 bestIndex = j;
00566 }
00567 }
00568
00569
00570
00571 unrankedScores[bestIndex] = 9e50;
00572
00573 printf("%s << Best score for %d frameset calibration: %f\n", __FUNCTION__, N+1, bestScore);
00574
00575
00576 for (int k = 0; k < nCams; k++)
00577 {
00578 selectedFrames.at(k).push_back(originalFramesCpy.at(k).at(bestIndex));
00579
00580 if (bestScore < prevBestScore) {
00581
00582 iterationBest_cameraMatrix[k].copyTo(currentBest_cameraMatrix[k]);
00583 iterationBest_distCoeffs[k].copyTo(currentBest_distCoeffs[k]);
00584 }
00585
00586 }
00587
00588
00589
00590
00591
00592 addedIndices.push_back(bestIndex);
00593
00594 if (bestScore < prevBestScore)
00595 {
00596 prevBestScore = bestScore;
00597 optimumNum = N;
00598 }
00599
00600
00601
00602 }
00603
00604
00605
00606
00607
00608 printf("%s << Optimum number of framesets for calibration = %d\n", __FUNCTION__, optimumNum+1);
00609
00610
00611
00612 for (int k = 0; k < nCams; k++)
00613 {
00614 currentBest_cameraMatrix[k].copyTo(cameraMatrix[k]);
00615 currentBest_distCoeffs[k].copyTo(distCoeffs[k]);
00616
00617 candidateCorners[k].clear();
00618 candidateCorners[k].assign(selectedFrames.at(k).begin(), selectedFrames.at(k).begin() + optimumNum+1);
00619 }
00620
00621 break;
00622
00623 case RANDOM_SEED_OPTIMIZATION_CODE:
00624
00625
00626 printf("%s << Initiating Random N-seed accumulative search [seeds = %d; seed trials = %d]\n", __FUNCTION__, nSeeds, nSeedTrials);
00627
00628 for (int k = 0; k < nCams; k++)
00629 {
00630 selectedFrames.at(k).clear();
00631 }
00632
00633
00634 unrankedScores = new double[originalFramesCpy.at(0).size()];
00635
00636 prevBestScore = 9e50;
00637
00638
00639
00640
00641
00642 bestSeedSet = new int[nSeeds];
00643 currentSeedSet = new int[nSeeds];
00644
00645 R[0] = Mat::eye(3, 3, CV_64FC1);
00646 T[0] = Mat::zeros(3, 1, CV_64FC1);
00647
00648
00649
00650 for (int iii = 0; iii < nSeedTrials; iii++)
00651 {
00652
00653
00654
00655 objectPoints.clear();
00656
00657 randomNum = rand() % originalFramesCpy.at(0).size();
00658
00659 currentSeedSet[0] = randomNum;
00660 objectPoints.push_back(row);
00661
00662
00663
00664 for (int k = 0; k < nCams; k++)
00665 {
00666 tempFrameTester.at(k).clear();
00667 tempFrameTester.at(k).push_back(originalFramesCpy.at(k).at(currentSeedSet[0]));
00668 }
00669
00670
00671
00672 for (int jjj = 1; jjj < nSeeds; jjj++)
00673 {
00674 do
00675 {
00676 alreadyUsed = false;
00677
00678 randomNum = rand() % originalFramesCpy.at(0).size();
00679
00680 for (int kkk = 0; kkk < jjj; kkk++)
00681 {
00682 if (randomNum == currentSeedSet[kkk])
00683 {
00684 alreadyUsed = true;
00685 }
00686 }
00687 }
00688 while (alreadyUsed);
00689
00690 currentSeedSet[jjj] = randomNum;
00691
00692 objectPoints.push_back(row);
00693
00694 for (int k = 0; k < nCams; k++)
00695 {
00696 tempFrameTester.at(k).push_back(originalFramesCpy.at(k).at(currentSeedSet[jjj]));
00697 }
00698
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 for (int k = 0; k < nCams-1; k++)
00710 {
00711
00712
00713
00714
00715 stereoCalibrate(objectPoints,
00716 tempFrameTester.at(0), tempFrameTester.at(k+1),
00717 cameraMatrix[0], distCoeffs[0],
00718 cameraMatrix[k+1], distCoeffs[k+1],
00719 imSize[0],
00720 R[k+1], T[k+1], E[k+1], F[k+1],
00721 term_crit,
00722 flags);
00723 }
00724
00725
00726
00727 currentSeedScore = calculateExtrinsicERE(nCams, objectPoints.at(0), testCorners, cameraMatrix, distCoeffs, R, T);
00728
00729 if (currentSeedScore < bestSeedScore)
00730 {
00731 bestSeedScore = currentSeedScore;
00732
00733 printf("%s << Best seed score [trial = %d]: %f\n", __FUNCTION__, iii, bestSeedScore);
00734
00735 for (int jjj = 0; jjj < nSeeds; jjj++)
00736 {
00737 bestSeedSet[jjj] = currentSeedSet[jjj];
00738 }
00739
00740 }
00741 else
00742 {
00743
00744 }
00745
00746 }
00747
00748 for (int jjj = 0; jjj < nSeeds; jjj++)
00749 {
00750
00751 for (int k = 0; k < nCams; k++)
00752 {
00753 selectedFrames.at(k).push_back(originalFramesCpy.at(k).at(bestSeedSet[jjj]));
00754 }
00755
00756 unrankedScores[bestSeedSet[jjj]] = 9e50;
00757
00758
00759
00760
00761 addedIndices.push_back(bestSeedSet[jjj]);
00762 }
00763
00764 bestScore = bestSeedScore;
00765
00766
00767 optimumNum = nSeeds-1;
00768
00769
00770 prevBestScore = 9e50;
00771
00772 for (int N = nSeeds; N < num; N++)
00773 {
00774
00775
00776
00777 objectPoints.push_back(row);
00778
00779 for (unsigned int i = 0; i < originalFramesCpy.at(0).size(); i++)
00780 {
00781
00782
00783
00784 for (int k = 0; k < nCams; k++)
00785 {
00786
00787
00788
00789
00790 tempFrameTester.at(k).assign(selectedFrames.at(k).begin(), selectedFrames.at(k).end());
00791
00792 tempFrameTester.at(k).push_back(originalFramesCpy.at(k).at(i));
00793
00794 }
00795
00796
00797
00798 alreadyAdded = false;
00799
00800
00801 for (unsigned int k = 0; k < addedIndices.size(); k++)
00802 {
00803 if (i == int(addedIndices.at(k)))
00804 {
00805
00806 alreadyAdded = true;
00807 }
00808 }
00809
00810
00811
00812
00813
00814
00815 if (alreadyAdded == true)
00816 {
00817 err = -1.0;
00818 }
00819 else
00820 {
00821
00822 randomNum = rand() % 1000 + 1;
00823
00824
00825 if (randomNum > (1.0 - testingProbability)*1000.0)
00826 {
00827
00828
00829
00830
00831
00832 for (int k = 0; k < nCams-1; k++)
00833 {
00834
00835
00836
00837
00838 stereoCalibrate(objectPoints,
00839 tempFrameTester.at(0), tempFrameTester.at(k+1),
00840 cameraMatrix[0], distCoeffs[0],
00841 cameraMatrix[k+1], distCoeffs[k+1],
00842 imSize[0],
00843 R[k+1], T[k+1], E[k+1], F[k+1],
00844 term_crit,
00845 flags);
00846
00847
00848
00849
00850
00851
00852 }
00853
00854
00855 err = calculateExtrinsicERE(nCams, objectPoints.at(0), testCorners, cameraMatrix, distCoeffs, R, T);
00856
00857 }
00858 else
00859 {
00860 err = -1.0;
00861 }
00862
00863 }
00864
00865 unrankedScores[i] = err;
00866
00867
00868
00869 }
00870
00871
00872
00873 bestScore = 9e50;
00874 bestIndex = 0;
00875
00876 for (unsigned int j = 0; j < originalFramesCpy.at(0).size(); j++)
00877 {
00878
00879
00880 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0.0))
00881 {
00882 bestScore = unrankedScores[j];
00883 bestIndex = j;
00884 }
00885 }
00886
00887
00888
00889 unrankedScores[bestIndex] = 9e50;
00890
00891 printf("%s << Best score for %d frameset calibration: %f\n", __FUNCTION__, N+1, bestScore);
00892
00893 for (int k = 0; k < nCams; k++)
00894 {
00895 selectedFrames.at(k).push_back(originalFramesCpy.at(k).at(bestIndex));
00896
00897 }
00898
00899
00900
00901 addedIndices.push_back(bestIndex);
00902
00903 if (bestScore < prevBestScore)
00904 {
00905 prevBestScore = bestScore;
00906 optimumNum = N;
00907 }
00908
00909
00910
00911 }
00912
00913
00914
00915
00916
00917 printf("%s << Optimum number of framesets for calibration = %d\n", __FUNCTION__, optimumNum+1);
00918
00919 for (int k = 0; k < nCams; k++)
00920 {
00921 candidateCorners[k].clear();
00922 candidateCorners[k].assign(selectedFrames.at(k).begin(), selectedFrames.at(k).begin() + optimumNum+1);
00923 }
00924
00925 break;
00926 default:
00927 delete[] unrankedScores;
00928 return;
00929 }
00930
00931
00932 delete[] unrankedScores;
00933
00934 }