$search
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 double errValues[]) 00013 { 00014 00015 double *errors_in_x, *errors_in_y; 00016 00017 bool tmpErrorValuesOnly = false; 00018 00019 00020 if (!errValues) 00021 { 00022 tmpErrorValuesOnly = true; 00023 errValues = new double[corners.size() * corners.at(0).size()]; 00024 } 00025 00026 00027 Mat fsRvec, fsTvec; 00028 cv::vector<Point2f> cornerSet; 00029 cornerSet.resize(physicalPoints.size()); 00030 00031 double err = 0.0, xSum = 0, ySum = 0, tSum = 0, xMean = 0, yMean = 0, tMean = 0, xDev = 0, yDev = 0, tDev = 0; 00032 00033 Point2f imLoc, imageDec, predictedDec; 00034 00035 for (unsigned int i = 0; i < corners.size(); i++) 00036 { 00037 // Estimate pose of board 00038 solvePnP(Mat(physicalPoints), Mat(corners.at(i)), cameraMatrix, distCoeffs, fsRvec, fsTvec, false); 00039 00040 // Reproject the object points using estimated rvec/tvec 00041 projectPoints(Mat(physicalPoints), fsRvec, fsTvec, cameraMatrix, distCoeffs, cornerSet); 00042 // do we want distortion vector or not? (noDistVector) it would make undistorted comparison better.. 00043 00044 //image.copyTo(debugImage); 00045 00046 // Find the mean and standard deviations for differences between results (conventional) 00047 for (unsigned int j = 0; j < cornerSet.size(); j++) 00048 { 00049 00050 imageDec = Point2f(corners.at(i).at(j).x, corners.at(i).at(j).y); 00051 predictedDec = Point2f(cornerSet.at(j).x, cornerSet.at(j).y); 00052 00053 if (errValues) 00054 { 00055 errValues[i*cornerSet.size()+j] = pow(pow(imageDec.x-predictedDec.x, 2)+pow(imageDec.y-predictedDec.y, 2), 0.5); 00056 //printf("%s << errValues[%d] = %f\n", __FUNCTION__, i*cornerSet.size()+j, errValues[i*cornerSet.size()+j]); 00057 } 00058 00059 00060 // Expand the vector between the actual and predicted points 00061 predictedDec = imageDec + 3*(predictedDec - imageDec); 00062 } 00063 00064 00065 } 00066 00067 // Calculate means 00068 for (unsigned int i = 0; i < corners.size(); i++) 00069 { 00070 for (unsigned int j = 0; j < cornerSet.size(); j++) 00071 { 00072 //xSum += errors_in_x[i*cornerSet.size()+j]; 00073 //ySum += errors_in_y[i*cornerSet.size()+j]; 00074 if (errValues) 00075 { 00076 tSum += errValues[i*cornerSet.size()+j]; 00077 } 00078 00079 } 00080 } 00081 00082 //xMean = xSum / (fullSetCorners.size()*cornerSet.size()); 00083 //yMean = ySum / (fullSetCorners.size()*cornerSet.size()); 00084 err = tSum / (corners.size()*cornerSet.size()); 00085 00086 /* 00087 errTotal = pow(pow(xMean, 2)+pow(yMean, 2), 0.5); 00088 00089 xDev = pow(xMean/cornerSet.size(), 0.5); // /= (fullSetCorners.size()*cornerSet.size()); 00090 yDev = pow(yMean/cornerSet.size(), 0.5); // /= (fullSetCorners.size()*cornerSet.size()); 00091 tDev = pow(tMean/cornerSet.size(), 0.5); 00092 */ 00093 00094 // Blur and normalize fovMat for display: 00095 00096 //Mat fovMat2; 00097 00098 // calculate std dev and window size based on no. of points 00099 //Size winSize; 00100 //double areaPerPt = double(imSize.width) * double(imSize.height) / double(cornerSet.size()); 00101 00102 //double stdDev = pow(areaPerPt, 0.5); 00103 00104 // Initially use PURE fovMat to calculate fov score..? Then imagify it... 00105 00106 00107 //winSize = Size(int(stdDev*3), int(stdDev*3)); 00108 00109 //GaussianBlur(fovMat, fovMat2, winSize, stdDev); 00110 //normalize_64(fovMat, fovMat2); // dst, src 00111 00112 //imshow("errMat", errMat); 00113 //waitKey(0); 00114 00115 00116 if (tmpErrorValuesOnly) 00117 { 00118 //printf("%s << deleting temporary errValues array...\n", __FUNCTION__); 00119 delete[] errValues; 00120 } 00121 00122 return err; 00123 } 00124 00125 void optimizeCalibrationSet(Size imSize, 00126 cv::vector< cv::vector<Point2f> >& candidatePatterns, 00127 cv::vector< cv::vector<Point2f> >& testPatterns, 00128 cv::vector<Point3f> row, 00129 vector<int>& selectedTags, 00130 int selection, 00131 int num, 00132 bool debugMode) 00133 { 00134 00135 //printf("%s << ENTERED.\n", __FUNCTION__); 00136 00137 selectedTags.clear(); 00138 00139 Mat distributionMap; 00140 00141 // If no optimization is desired 00142 if (selection == 0) { 00143 return; 00144 } 00145 00146 // Initialize Random Number Generator 00147 srand ( (unsigned int)(time(NULL)) ); 00148 00149 // Calibration Variables 00150 cv::vector< cv::vector<Point3f> > objectPoints; 00151 Mat cameraMatrix = Mat::eye(3, 3, CV_64F); 00152 Mat distCoeffs = Mat(1, 8, CV_64F); 00153 cv::vector<Mat> rvecs, tvecs; 00154 00155 // Pointset Variables 00156 cv::vector< cv::vector<Point2f> > candidatePatternsCpy; 00157 candidatePatternsCpy.assign(candidatePatterns.begin(), candidatePatterns.end()); // So all corners are preserved for ERE calculation/s 00158 cv::vector< cv::vector<Point2f> > fullSetCorners; 00159 fullSetCorners.assign(testPatterns.begin(), testPatterns.end()); // So all corners are preserved for ERE calculation/s 00160 cv::vector< cv::vector<Point2f> > selectedFrames; 00161 cv::vector< cv::vector<Point2f> > tempFrameTester; 00162 cv::vector< cv::vector<Point2f> > newCorners; 00163 00164 // Error Measurement Variables 00165 double err; 00166 Mat optimalResults(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_64FC1); // Raw results 00167 Mat rankedScores(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_64FC1); // Reordered results 00168 Mat rankedIndices(10, ABSOLUTE_MAX_FRAMES_TO_STORE, CV_8UC1); // Indices in order - to correspond with 'rankedScores' 00169 00170 // Display and Debugging Variables 00171 Mat distributionDisplay(distributionMap.size(), CV_8UC1); 00172 00173 // Optimization Variables 00174 Mat binMap(30, 40, CV_32SC1); 00175 Mat binTemp(binMap.size(), CV_8UC1); 00176 binMap.setTo(0); 00177 00178 // Scoring Variables 00179 double score, maxScore = 0.0; 00180 int maxIndex = 0; 00181 int rankedFrames[ABSOLUTE_MAX_FRAMES_TO_STORE]; 00182 double rankedScoreVector[ABSOLUTE_MAX_FRAMES_TO_STORE]; 00183 double *unrankedScores; // [MAX_FRAMES_TO_LOAD]; 00184 //int addedIndices[MAX_FRAMES_TO_LOAD]; 00185 vector<int> addedIndices; 00186 double bestScore = 0.0, topScore = 0.0; 00187 int bestIndex; 00188 00189 vector<unsigned int> currentIndices, topIndices, bestIndices; 00190 00191 // For optimum number of frames 00192 double prevBestScore = 9e99; 00193 int optimumNum = 0; 00194 unsigned long int possibleCombos; 00195 00196 // Gaussian Variables 00197 Mat gaussianMat(binMap.size().height, binMap.size().width, CV_64FC1); 00198 createGaussianMatrix(gaussianMat, 0.3); 00199 00200 // Other Variables 00201 int randomNum = 0; 00202 double testingProbability = 1.00; 00203 00204 double bestErr = 9e99; 00205 00206 // Random trials code 00207 int nTrials = 20; 00208 00209 double median, p90, p99; 00210 00211 double *values; 00212 00213 //printf("%s << ENTERED. (%d)\n", __FUNCTION__, 0); 00214 00215 values = new double[num*nTrials]; 00216 00217 /* 00218 for (int i = 0; i < num; i++) { 00219 values[i] = new double[nTrials]; 00220 } 00221 */ 00222 00223 num = min((int)num, (int)candidatePatterns.size()); 00224 00225 // SEED VARIABLES 00226 int nSeeds = 5; 00227 int nSeedTrials = 500; 00228 00229 int *bestSeedSet, *currentSeedSet; 00230 00231 double bestSeedScore = 9e50, currentSeedScore; 00232 00233 bool alreadyUsed; 00234 00235 int newRandomNum; 00236 00237 double radialDistribution[RADIAL_LENGTH]; 00238 00239 vector<int> tagNames; 00240 00241 for (unsigned int iii = 0; iii < candidatePatterns.size(); iii++) { 00242 tagNames.push_back(iii); 00243 } 00244 00245 // Clear radial distribution array 00246 for (int i = 0; i < RADIAL_LENGTH; i++) 00247 { 00248 radialDistribution[i] = 0.0; 00249 } 00250 00251 //printf("%s << ENTERED. (%d)\n", __FUNCTION__, 1); 00252 00253 switch (selection) 00254 { 00255 // ================================================== 00256 case SCORE_BASED_OPTIMIZATION_CODE: // SCORE-BASED OPTIMAL FRAME SELECTION 00257 // ================================================== 00258 // Until you've sufficiently filled the newCorners vector 00259 while (newCorners.size() < (unsigned int)(num)) 00260 { 00261 maxScore = 0.0; 00262 maxIndex = 0; 00263 00264 // For each corner remaining 00265 for (unsigned int i = 0; i < candidatePatterns.size(); i++) 00266 { 00267 score = obtainSetScore(distributionMap, binMap, gaussianMat, candidatePatterns.at(i), radialDistribution); 00268 //printf("%s << Frame [%d] scores %f\n", __FUNCTION__, i, score); 00269 if (score > maxScore) 00270 { 00271 maxScore = score; 00272 maxIndex = i; 00273 } 00274 else if (score < 0) 00275 { 00276 printf("%s << ERROR. Negative score. Returning.\n", __FUNCTION__); 00277 return; 00278 } 00279 } 00280 00281 //printf("%s << Top scoring frame #%d gets %f\n", __FUNCTION__, maxIndex, maxScore); 00282 //cin.get(); 00283 00284 newCorners.push_back(candidatePatterns.at(maxIndex)); // Push highest scorer onto new vector 00285 00286 addToDistributionMap(distributionMap, newCorners.at(newCorners.size()-1)); // update distribution 00287 addToRadialDistribution(radialDistribution, newCorners.at(newCorners.size()-1), distributionMap.size()); 00288 00289 prepForDisplay(distributionMap, distributionDisplay); 00290 imshow("distributionMap", distributionDisplay); 00291 00292 addToBinMap(binMap, newCorners.at(newCorners.size()-1), distributionMap.size()); // update binned mat 00293 convertScaleAbs(binMap, binTemp); 00294 simpleResize(binTemp, distributionDisplay, Size(480, 640)); 00295 equalizeHist(distributionDisplay, distributionDisplay); 00296 //imshow("binMap", distributionDisplay); 00297 00298 waitKey( 0 ); 00299 00300 candidatePatterns.erase(candidatePatterns.begin()+maxIndex); // Erase it from original vector 00301 } 00302 00303 candidatePatterns.clear(); 00304 newCorners.swap(candidatePatterns); 00305 break; 00306 // ================================================== 00307 case RANDOM_SET_OPTIMIZATION_CODE: // RANDOM FRAME SELECTION 00308 // ================================================== 00309 for (int i = 0; i < num; i++) 00310 { 00311 randomNum = rand() % int(candidatePatterns.size()); 00312 newCorners.push_back(candidatePatterns.at(randomNum)); 00313 candidatePatterns.erase(candidatePatterns.begin()+randomNum); 00314 selectedTags.push_back(tagNames.at(randomNum)); 00315 00316 addToDistributionMap(distributionMap, newCorners.at(i)); 00317 prepForDisplay(distributionMap, distributionDisplay); 00318 imshow("distributionMap", distributionDisplay); 00319 waitKey(40); 00320 } 00321 00322 candidatePatterns.clear(); 00323 newCorners.swap(candidatePatterns); 00324 break; 00325 // ================================================== 00326 case FIRST_N_PATTERNS_OPTIMIZATION_CODE: // FIRST N FRAMES SELECTION 00327 // ================================================== 00328 while (candidatePatterns.size() > (unsigned int)(num)) 00329 { 00330 candidatePatterns.pop_back(); 00331 } 00332 00333 for (int i = 0; i < num; i++) 00334 { 00335 addToDistributionMap(distributionMap, candidatePatterns.at(i)); 00336 selectedTags.push_back(tagNames.at(i)); 00337 prepForDisplay(distributionMap, distributionDisplay); 00338 imshow("distributionMap", distributionDisplay); 00339 waitKey(40); 00340 } 00341 00342 delete[] values; 00343 00344 return; 00345 // ================================================== 00346 case ENHANCED_MCM_OPTIMIZATION_CODE: // MULTIPLE-TRIAL OPTIMAL FRAME SELECTION 00347 // ================================================== 00348 00349 //printf("%s << ENTERED. (%d)\n", __FUNCTION__, 2); 00350 selectedFrames.clear(); 00351 00352 unrankedScores = new double[candidatePatternsCpy.size()]; 00353 00354 prevBestScore = 9e50; 00355 00356 //printf("%s << num = %d\n", __FUNCTION__, num); 00357 00358 for (int N = 0; N < num; N++) 00359 { 00360 00361 objectPoints.push_back(row); 00362 00363 //printf("%s << candidatePatternsCpy.size() = %d\n", __FUNCTION__, candidatePatternsCpy.size()); 00364 00365 for (unsigned int i = 0; i < candidatePatternsCpy.size(); i++) 00366 { 00367 00368 tempFrameTester.clear(); 00369 tempFrameTester.assign(selectedFrames.begin(), selectedFrames.end()); 00370 tempFrameTester.push_back(candidatePatternsCpy.at(i)); 00371 00372 bool alreadyAdded = false; 00373 00374 for (int k = 0; k < addedIndices.size(); k++) 00375 { 00376 if (i == addedIndices.at(k)) // this was addedIndices[N] before - but that doesn't make sense... 00377 { 00378 alreadyAdded = true; 00379 //printf("%s << WTF?\n", __FUNCTION__); 00380 } 00381 } 00382 00383 if (alreadyAdded == true) 00384 { 00385 err = -1.0; 00386 } 00387 else 00388 { 00389 00390 randomNum = rand() % 1000 + 1; // random number between 1 and 1000 (inclusive) 00391 00392 Mat fovMat, errMat; 00393 double fovScore, errScore; 00394 00395 if (randomNum > (1 - testingProbability)*1000.0) 00396 { 00397 //printf("%s << Calibrating pattern #%d\n", __FUNCTION__, i); 00398 00399 //printf("%s << objectPoints.size() = %d; tempFrameTester.size() = %d\n", __FUNCTION__, objectPoints.size(), tempFrameTester.size()); 00400 00401 //printf("%s << imSize = (%d, %d); objectPoints.at(0).size() = %d; tempFrameTester.at(0).size() = %d\n", __FUNCTION__, imSize.height, imSize.width, objectPoints.at(0).size(), tempFrameTester.at(0).size()); 00402 00403 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, INTRINSICS_FLAGS); 00404 00405 //printf("%s << objectPoints.at(0).size() = %d; fullSetCorners.size() = %d\n", __FUNCTION__, objectPoints.at(0).size(), fullSetCorners.size()); 00406 00407 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs); 00408 //printf("%s << err = %f\n", __FUNCTION__, err); 00409 } 00410 else 00411 { 00412 // If the frame is not to be tested (more likely with lower testingProbability) 00413 err = -1.0; 00414 } 00415 00416 } 00417 00418 unrankedScores[i] = err; 00419 //printf("%s << score = %f\n", __FUNCTION__, err); 00420 00421 00422 00423 } 00424 00425 bestScore = 9e50; 00426 bestIndex = 0; 00427 00428 for (unsigned int j = 0; j < candidatePatternsCpy.size(); j++) 00429 { 00430 00431 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0)) 00432 { 00433 bestScore = unrankedScores[j]; 00434 bestIndex = j; 00435 } 00436 } 00437 00438 unrankedScores[bestIndex] = 9e50; 00439 00440 //printf("%s << Best score for %d frame calibration: %f\n", __FUNCTION__, N+1, bestScore); 00441 00442 selectedFrames.push_back(candidatePatternsCpy.at(bestIndex)); 00443 00444 // Corrupt best frame in 'originalFramesCpy' 00445 for (unsigned int i = 0; i < candidatePatternsCpy.at(bestIndex).size(); i++) 00446 { 00447 candidatePatternsCpy.at(bestIndex).at(i) = Point2f(0.0,0.0); 00448 } 00449 00450 addedIndices.push_back(bestIndex); 00451 00452 if (bestScore < prevBestScore) 00453 { 00454 prevBestScore = bestScore; 00455 optimumNum = N; 00456 } 00457 00458 if (debugMode) { 00459 printf("%s << (%d) frames considered; best generalized error = (%f)\n", __FUNCTION__, N, prevBestScore); 00460 } 00461 00462 } 00463 00464 delete[] unrankedScores; 00465 00466 //printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, optimumNum+1); 00467 00468 candidatePatterns.clear(); 00469 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.begin() + optimumNum+1); 00470 00471 for (int i = 0; i < optimumNum+1; i++) 00472 { 00473 selectedTags.push_back(tagNames.at(addedIndices.at(i))); 00474 } 00475 00476 //printf("%s << ENTERED. (%d)\n", __FUNCTION__, 3); 00477 00478 break; 00479 // ================================================== 00480 case RANDOM_SEED_OPTIMIZATION_CODE: // Random N-seed accumulative search 00481 // ================================================== 00482 00483 selectedFrames.clear(); 00484 00485 unrankedScores = new double[candidatePatternsCpy.size()]; 00486 00487 prevBestScore = 9e50; 00488 00489 //printf("%s << num = %d\n", __FUNCTION__, num); 00490 00491 00492 00493 bestSeedSet = new int[nSeeds]; 00494 currentSeedSet = new int[nSeeds]; 00495 00496 00497 00498 for (int iii = 0; iii < nSeedTrials; iii++) 00499 { 00500 00501 objectPoints.clear(); 00502 tempFrameTester.clear(); 00503 00504 randomNum = rand() % candidatePatternsCpy.size(); 00505 00506 currentSeedSet[0] = randomNum; 00507 objectPoints.push_back(row); 00508 00509 00510 tempFrameTester.push_back(candidatePatternsCpy.at(currentSeedSet[0])); 00511 00512 for (int jjj = 1; jjj < nSeeds; jjj++) 00513 { 00514 do 00515 { 00516 alreadyUsed = false; 00517 00518 randomNum = rand() % candidatePatternsCpy.size(); 00519 00520 for (int kkk = 0; kkk < jjj; kkk++) 00521 { 00522 if (randomNum == currentSeedSet[kkk]) 00523 { 00524 alreadyUsed = true; 00525 } 00526 } 00527 } 00528 while (alreadyUsed); 00529 00530 currentSeedSet[jjj] = randomNum; 00531 00532 objectPoints.push_back(row); 00533 tempFrameTester.push_back(candidatePatternsCpy.at(currentSeedSet[jjj])); 00534 } 00535 00536 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, INTRINSICS_FLAGS); 00537 00538 currentSeedScore = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs); 00539 00540 if (currentSeedScore < bestSeedScore) 00541 { 00542 bestSeedScore = currentSeedScore; 00543 00544 printf("%s << Best seed score [trial = %d]: %f\n", __FUNCTION__, iii, bestSeedScore); 00545 00546 for (int jjj = 0; jjj < nSeeds; jjj++) 00547 { 00548 bestSeedSet[jjj] = currentSeedSet[jjj]; 00549 } 00550 00551 } 00552 00553 } 00554 00555 for (int jjj = 0; jjj < nSeeds; jjj++) 00556 { 00557 selectedFrames.push_back(candidatePatternsCpy.at(bestSeedSet[jjj])); 00558 unrankedScores[bestSeedSet[jjj]] = 9e50; 00559 00560 // Corrupt seed frames 00561 for (unsigned int kkk = 0; kkk < candidatePatternsCpy.at(bestSeedSet[jjj]).size(); kkk++) 00562 { 00563 candidatePatternsCpy.at(bestSeedSet[jjj]).at(kkk) = Point2f(0.0,0.0); 00564 } 00565 00566 addedIndices.push_back(bestSeedSet[jjj]); 00567 } 00568 00569 bestScore = bestSeedScore; 00570 00571 // Subtract 1 because later code is dodgy... :P 00572 optimumNum = nSeeds-1; 00573 00574 for (int N = nSeeds; N < num; N++) 00575 { 00576 00577 objectPoints.push_back(row); 00578 00579 //printf("%s << candidatePatternsCpy.size() = %d\n", __FUNCTION__, candidatePatternsCpy.size()); 00580 00581 for (unsigned int i = 0; i < candidatePatternsCpy.size(); i++) 00582 { 00583 00584 tempFrameTester.clear(); 00585 tempFrameTester.assign(selectedFrames.begin(), selectedFrames.end()); 00586 tempFrameTester.push_back(candidatePatternsCpy.at(i)); 00587 00588 bool alreadyAdded = false; 00589 00590 for (int k = 0; k < addedIndices.size(); k++) 00591 { 00592 if (i == addedIndices.at(k)) // this was addedIndices[N] before - but that doesn't make sense... 00593 { 00594 alreadyAdded = true; 00595 //printf("%s << WTF?\n", __FUNCTION__); 00596 } 00597 } 00598 00599 if (alreadyAdded == true) 00600 { 00601 err = -1.0; 00602 } 00603 else 00604 { 00605 00606 randomNum = rand() % 1000 + 1; // random number between 1 and 1000 (inclusive) 00607 00608 Mat fovMat, errMat; 00609 double fovScore, errScore; 00610 00611 if (randomNum > (1 - testingProbability)*1000.0) 00612 { 00613 //printf("%s << Calibrating pattern #%d\n", __FUNCTION__, i); 00614 00615 //printf("%s << objectPoints.size() = %d; tempFrameTester.size() = %d\n", __FUNCTION__, objectPoints.size(), tempFrameTester.size()); 00616 00617 calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, INTRINSICS_FLAGS); 00618 00619 //printf("%s << objectPoints.at(0).size() = %d; fullSetCorners.size() = %d\n", __FUNCTION__, objectPoints.at(0).size(), fullSetCorners.size()); 00620 00621 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs); 00622 //printf("%s << err = %f\n", __FUNCTION__, err); 00623 } 00624 else 00625 { 00626 // If the frame is not to be tested (more likely with lower testingProbability) 00627 err = -1.0; 00628 } 00629 00630 } 00631 00632 unrankedScores[i] = err; 00633 00634 } 00635 00636 bestScore = 9e50; 00637 bestIndex = 0; 00638 00639 for (unsigned int j = 0; j < candidatePatternsCpy.size(); j++) 00640 { 00641 00642 if ((unrankedScores[j] < bestScore) && (unrankedScores[j] > 0)) 00643 { 00644 bestScore = unrankedScores[j]; 00645 bestIndex = j; 00646 } 00647 } 00648 00649 unrankedScores[bestIndex] = 9e50; 00650 00651 printf("%s << Best score for %d frame calibration: %f\n", __FUNCTION__, N+1, bestScore); 00652 00653 selectedFrames.push_back(candidatePatternsCpy.at(bestIndex)); 00654 00655 // Corrupt best frame in 'originalFramesCpy' 00656 for (unsigned int i = 0; i < candidatePatternsCpy.at(bestIndex).size(); i++) 00657 { 00658 candidatePatternsCpy.at(bestIndex).at(i) = Point2f(0.0,0.0); 00659 } 00660 00661 addedIndices.push_back(bestIndex); 00662 00663 if (bestScore < prevBestScore) 00664 { 00665 prevBestScore = bestScore; 00666 optimumNum = N; 00667 } 00668 00669 } 00670 00671 delete[] unrankedScores; 00672 00673 printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, optimumNum+1); 00674 00675 candidatePatterns.clear(); 00676 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.begin() + optimumNum+1); 00677 00678 for (int i = 0; i < optimumNum+1; i++) 00679 { 00680 selectedTags.push_back(tagNames.at(addedIndices.at(i))); 00681 } 00682 00683 break; 00684 // ================================================== 00685 case EXHAUSTIVE_SEARCH_OPTIMIZATION_CODE: // EXHAUSTIVE TRUE-OPTIMAL SELECTION 00686 // ================================================== 00687 00688 if (candidatePatternsCpy.size() > 20) 00689 { 00690 printf("%s << Too many frames for exhaustive approach.\n", __FUNCTION__); 00691 break; 00692 } 00693 else 00694 { 00695 printf("%s << Searching for absolute optimum.\n", __FUNCTION__); 00696 } 00697 00698 bestScore = 9e99; 00699 00700 // For each different value of N 00701 for (int N = 0; N < num; N++) 00702 { 00703 00704 topScore = 9e99; 00705 00706 printf("%s << N(+1) = %d\n", __FUNCTION__, N+1); 00707 00708 objectPoints.push_back(row); 00709 00710 possibleCombos = 1; 00711 00712 possibleCombos = factorial(candidatePatternsCpy.size()) / (factorial(N+1) * factorial(candidatePatternsCpy.size() - N - 1)); 00713 00714 printf("%s << possibleCombos = %d\n", __FUNCTION__, possibleCombos); 00715 00716 currentIndices.clear(); 00717 00718 // For each possible combo 00719 for (unsigned int i = 0; i < possibleCombos; i++) 00720 { 00721 00722 tempFrameTester.clear(); 00723 getNextCombo(currentIndices, N+1, candidatePatternsCpy.size()); 00724 00725 for (int j = 0; j < currentIndices.size(); j++) 00726 { 00727 //printf("%s << currentIndices.at(%d) = %d\n", __FUNCTION__, j, currentIndices.at(j)); 00728 tempFrameTester.push_back(candidatePatternsCpy.at(currentIndices.at(j))); 00729 } 00730 00731 err = calibrateCamera(objectPoints, tempFrameTester, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, INTRINSICS_FLAGS); 00732 00733 Mat fovMat, errMat; 00734 double fovScore, errScore; 00735 00736 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs); 00737 00738 if (err < topScore) 00739 { 00740 topScore = err; 00741 topIndices.clear(); 00742 topIndices.assign(currentIndices.begin(), currentIndices.end()); 00743 } 00744 00745 if (err < bestScore) 00746 { 00747 bestScore = err; 00748 bestIndices.clear(); 00749 bestIndices.assign(currentIndices.begin(), currentIndices.end()); 00750 } 00751 00752 } 00753 00754 printf("%s << topScore [(N+1) = %d] = %f\n", __FUNCTION__, N+1, topScore); 00755 00756 for (int j = 0; j < topIndices.size(); j++) 00757 { 00758 printf("%s << topIndices.at(%d) = %d\n", __FUNCTION__, j, topIndices.at(j)); 00759 } 00760 00761 } 00762 00763 candidatePatterns.clear(); 00764 00765 printf("%s << Optimum number of frames for calibration = %d\n", __FUNCTION__, bestIndices.size()); 00766 printf("%s << bestScore = %f\n", __FUNCTION__, bestScore); 00767 00768 for (unsigned int i = 0; i < bestIndices.size(); i++) 00769 { 00770 printf("%s << bestIndices.at(%d) = %d\n", __FUNCTION__, i, bestIndices.at(i)); 00771 candidatePatterns.push_back(candidatePatternsCpy.at(bestIndices.at(i))); 00772 } 00773 00774 break; 00775 // ================================================== 00776 case BEST_OF_RANDOM_PATTERNS_OPTIMIZATION_CODE: // MANY RANDOM TRIALS FRAME SELECTION 00777 // ================================================== 00778 00779 bestErr = 9e99; 00780 00781 printf("%s << Random trial selection\n", __FUNCTION__); 00782 00783 for (unsigned int k = 0; k < nTrials; k++) 00784 { 00785 00786 //printf("%s << Trial #%d.\n", __FUNCTION__, k); 00787 00788 objectPoints.clear(); 00789 candidatePatterns.clear(); 00790 currentIndices.clear(); 00791 newCorners.clear(); 00792 00793 candidatePatterns.assign(candidatePatternsCpy.begin(), candidatePatternsCpy.end()); 00794 00795 for (int N = 0; N < num; N++) 00796 { 00797 00798 objectPoints.push_back(row); 00799 randomNum = rand() % int(candidatePatterns.size()); 00800 currentIndices.push_back(randomNum); 00801 newCorners.push_back(candidatePatterns.at(randomNum)); 00802 candidatePatterns.erase(candidatePatterns.begin()+randomNum); 00803 //printf("%s << oP.size() = %d; nC.size() = %d\n", __FUNCTION__, objectPoints.size(), newCorners.size()); 00804 00805 err = calibrateCamera(objectPoints, newCorners, imSize, cameraMatrix, distCoeffs, rvecs, tvecs, INTRINSICS_FLAGS); 00806 00807 Mat fovMat, errMat; 00808 double fovScore, errScore; 00809 err = calculateERE(imSize, objectPoints.at(0), fullSetCorners, cameraMatrix, distCoeffs); 00810 00811 values[N*nTrials+k] = err; 00812 00813 //printf("%s << trial #%d, N = %d, score = %f\n", __FUNCTION__, k, N, err); 00814 00815 if (err < bestErr) 00816 { 00817 bestErr = err; 00818 bestIndices.clear(); 00819 00820 selectedFrames.clear(); 00821 00822 bestIndices.assign(currentIndices.begin(), currentIndices.end()); 00823 00824 selectedFrames.assign(newCorners.begin(), newCorners.end()); 00825 00826 //printf("%s << new bestErr[N = %d] = %f\n", __FUNCTION__, N, bestErr); 00827 } 00828 } 00829 } 00830 00831 candidatePatterns.clear(); 00832 00833 for (int N = 0; N < num; N++) 00834 { 00835 median = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.5); 00836 p90 = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.9); 00837 p99 = findEquivalentProbabilityScore(&values[N*nTrials], nTrials, 0.99); 00838 00839 //printf("%s << Random results for %d frames: median = %f; p90 = %f; p99 = %f\n", __FUNCTION__, N, median, p90, p99); 00840 } 00841 00842 candidatePatterns.assign(selectedFrames.begin(), selectedFrames.end()); 00843 00844 break; 00845 default: 00846 00847 delete[] values; 00848 00849 return; 00850 } 00851 00852 00853 delete[] values; 00854 00855 }