int AlignPair(int argc, const char *argv[]) { // Align two images using feature matching if (argc < 7) { printf("usage: %s input1.f input2.f matchfile nRANSAC RANSACthresh [sift]\n", argv[1]); return -1; } const char *infile1 = argv[2]; const char *infile2 = argv[3]; const char *matchfile = argv[4]; int nRANSAC = atoi(argv[5]); double RANSACthresh = atof(argv[6]); FeatureSet f1, f2; // Read in the feature sets if ((argc >= 8) && (strcmp(argv[7], "sift") == 0)) { f1.load_sift(infile1); f2.load_sift(infile2); } else { f1.load(infile1); f2.load(infile2); } CTransform3x3 M; // Read in the feature matches vector<FeatureMatch> matches; bool success = ReadFeatureMatches(matchfile, matches); if (!success) { printf("Error opening match file %s for reading\n", matchfile); return -1; } // Perform the alignment. if (strcmp(argv[1], "alignPairHomography") == 0) { alignPair(f1, f2, matches, eHomography, nRANSAC, RANSACthresh, M); } else { alignPair(f1, f2, matches, eTranslate, nRANSAC, RANSACthresh, M); } // Print out the result CTransform3x3 Mi = M.Inverse(); /*printf("% 10.3e %10.3e %10.3e\n %10.3e %10.3e %10.3e\n %10.3e %10.3e %10.3e\n", Mi[0][0], Mi[0][1], Mi[0][2], Mi[1][0], Mi[1][1], Mi[1][2], Mi[2][0], Mi[2][1], Mi[2][2]);*/ printf("%0.8e %0.8e %0.8e %0.8e %0.8e %0.8e %0.8e %0.8e %0.8e", Mi[0][0], Mi[0][1], Mi[0][2], Mi[1][0], Mi[1][1], Mi[1][2], Mi[2][0], Mi[2][1], Mi[2][2]); return 0; }
// Initialize global alignment of all images. int initGlobalAlign(const vector<FeatureSet> &fs, int minMatches, MotionModel m, float f, const vector< pair<int,int> >& WH, int nRANSAC, double RANSACthresh, AlignMatrix &am, vector<CTransform3x3> &ms) { int n = fs.size(); // create the n-by-n alignment matrix am.resize(n); for (int i=0; i<n; i++) am[i].resize(n); vector<FeatureMatch> matches; CTransform3x3 transMat; for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { if (i != j) { printf("matching image %d with image %d, ", i, j); // BEGIN TODO // write code to fill in the information for am[i][j] // // you'll need to call your feature matching routine, // then your pair alignment routine matches.clear(); int count = MatchFeaturesByDistRatio(fs[i], fs[j],matches); if(count < minMatches) { am[i][j].matches = matches; am[i][j].inliers.clear(); am[i][j].r = transMat; } else { am[i][j].matches = matches; if(ApproximateRotation) am[i][j].inliers = alignPair(fs[i],fs[j],matches,eRotate3D,f,WH[i],WH[j],nRANSAC,RANSACthresh,transMat); else am[i][j].inliers = MyalignPair(fs[i],fs[j],matches,eRotate3D,f,WH[i],WH[j],nRANSAC,RANSACthresh,transMat); am[i][j].r = transMat; } // END TODO printf("%d inliers\n", am[i][j].inliers.size()); if ((int) am[i][j].inliers.size() < minMatches) am[i][j].inliers.clear(); } } } vector<AlignmentImage> nodes(n); for (int i=1; i<n; i++) { nodes[i].added = false; nodes[i].nBest = 0; nodes[i].imageID = i; nodes[i].parentID = -1; } // create the image heap ImageHeap heap(nodes); // add the first image and update the match quality of // its neighbors nodes[0].added = true; for (int j=1; j<n; j++) { int nMatches = am[0][j].inliers.size(); if (nodes[j].nBest < nMatches) { heap.increaseKey(nodes[j].heapIndex, nMatches); nodes[j].parentID = 0; } } AlignmentImage *nextImage; // add the rest of the images for (int i=0; i<n-1; i++) { nextImage = heap.extractMax(); if (nextImage->nBest == 0) { // image set seems to be disconnected return -1; } nextImage->added = true; int id = nextImage->imageID; int pid = nextImage->parentID; // compute the global alignment of the extracted image nextImage->r = am[pid][id].r * nodes[pid].r; // update the match quality for its neighbor images for (int j=0; j<n; j++) { if ((id != j) && (!nodes[j].added)) { int nMatches = am[id][j].inliers.size(); if (nodes[j].nBest < nMatches) { heap.increaseKey(nodes[j].heapIndex, nMatches); nodes[j].parentID = id; } } } } ms.clear(); // put the global transformations into the output array for (int i=0; i<n; i++) { ms.push_back(nodes[i].r); } return 0; }
int AlignPair(int argc, const char *argv[]) { // Align two images using feature matching if (argc < 7) { printf("usage: %s input1.f input2.f matchfile nRANSAC RANSACthresh [sift]\n", argv[1]); return -1; } const char *infile1 = argv[2]; const char *infile2 = argv[3]; const char *matchfile = argv[4]; int nRANSAC = atoi(argv[5]); double RANSACthresh = atof(argv[6]); FeatureSet f1, f2; // Read in the feature sets if ((argc >= 8) && (strcmp(argv[7], "sift") == 0)) { f1.load_sift(infile1); f2.load_sift(infile2); } else { f1.load(infile1); f2.load(infile2); } CTransform3x3 M; // Read in the feature matches vector<FeatureMatch> matches; bool success = ReadFeatureMatches(matchfile, matches); if (!success) { printf("Error opening match file %s for reading\n", matchfile); return -1; } #if 0 // Align two images using feature matching if (argc < 6) { printf("usage: %s input1.f input2.f nRANSAC RANSACthresh [sift]\n", argv[1]); return -1; } const char *infile1 = argv[2]; const char *infile2 = argv[3]; int nRANSAC = atoi(argv[4]); double RANSACthresh = atof(argv[5]); FeatureSet f1, f2; //printf("Reading features\n"); // Read in the feature sets if ((argc >= 7) && (strcmp(argv[6], "sift") == 0)) { f1.load_sift(infile1); f2.load_sift(infile2); } else { f1.load(infile1); f2.load(infile2); } vector<FeatureMatch> matches; CTransform3x3 M; // call your feature matching routine and store the result // in matches // printf("Finding matches\n"); fastMatchFeatures(f1, f2, matches); #endif // Performs the alignment. // printf("Aligning pair\n"); // alignPair(f1, f2, matches, eTranslate, 0.0f, nRANSAC, RANSACthresh, M); alignPair(f1, f2, matches, eTranslate, 0.0f, nRANSAC, RANSACthresh, M); // Print out the result if ((argc >= 7) && (strcmp(argv[6], "sift") == 0)) { printf("%.2f %.2f\n", M[0][2], -M[1][2]); } else { printf("%.2f %.2f\n", M[0][2], M[1][2]); // printf("%0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f\n", // M[0][0], M[0][1], M[0][2], // M[1][0], M[1][1], M[1][2], // M[2][0], M[2][1], M[2][2]); } return 0; }