Calculate offset/skew/rotation of similar images in C++

前端 未结 3 1984
不思量自难忘°
不思量自难忘° 2020-12-29 14:33

I have multiple images taken simultaneously pointing at the same direction from the same starting location. However, there is still a slight offset because these cameras wer

3条回答
  •  -上瘾入骨i
    2020-12-29 14:55

    Here is a short code that does what you want (I use openCV 2.2):

    1. Suppose you have 2 images: srcImage,dstImage, and you want to align them
    2. The code is very simple. Use it as basis for your algorithm.

    Code:

    // Detect special points on each image that can be corresponded    
    Ptr  detector = new SurfFeatureDetector(2000);  // Detector for features
    
    vector srcFeatures;   // Detected key points on first image
    vector dstFeatures;
    detector->detect(srcImage,srcFeatures);
    detector->detect(dstImage,dstFeatures); 
    
    // Extract descriptors of the features
    SurfDescriptorExtractor extractor;  
    Mat projDescriptors, camDescriptors;
    extractor.compute(srcImage,  srcFeatures, srcDescriptors);
    extractor.compute(dstImage , dstFeatures, dstDescriptors );
    
    // Match descriptors of 2 images (find pairs of corresponding points)
    BruteForceMatcher> matcher;       // Use FlannBasedMatcher matcher. It is better
    vector matches;
    matcher.match(srcDescriptors, dstDescriptors, matches);     
    
    // Extract pairs of points
    vector pairOfsrcKP(matches.size()), pairOfdstKP(matches.size());
    for( size_t i = 0; i < matches.size(); i++ ){
        pairOfsrcKP[i] = matches[i].queryIdx;
        pairOfdstKP[i] = matches[i].trainIdx;
    }
    
    vector sPoints; KeyPoint::convert(srcFeatures, sPoints,pairOfsrcKP);
    vector dPoints; KeyPoint::convert(dstFeatures, dPoints,pairOfdstKP);
    
    // Matched pairs of 2D points. Those pairs will be used to calculate homography
    Mat src2Dfeatures;
    Mat dst2Dfeatures;
    Mat(sPoints).copyTo(src2Dfeatures);
    Mat(dPoints).copyTo(dst2Dfeatures);
    
    // Calculate homography
    vector outlierMask;
    Mat H;
    H = findHomography( src2Dfeatures, dst2Dfeatures, outlierMask, RANSAC, 3);
    
    // Show the result (only for debug)
    if (debug){
       Mat outimg;
       drawMatches(srcImage, srcFeatures,dstImage, dstFeatures, matches, outimg, Scalar::all(-1), Scalar::all(-1),
                   reinterpret_cast&> (outlierMask));
       imshow("Matches: Src image (left) to dst (right)", outimg);
       cvWaitKey(0);
    }
    
    // Now you have the resulting homography. I mean that:  H(srcImage) is alligned to dstImage. Apply H using the below code
    Mat AlignedSrcImage;
    warpPerspective(srcImage,AlignedSrcImage,H,dstImage.Size(),INTER_LINEAR,BORDER_CONSTANT);
    Mat AlignedDstImageToSrc;
    warpPerspective(dstImage,AlignedDstImageToSrc,H.inv(),srcImage.Size(),INTER_LINEAR,BORDER_CONSTANT);
    

提交回复
热议问题