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

前端 未结 3 1974
不思量自难忘°
不思量自难忘° 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条回答
  • 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<FeatureDetector>  detector = new SurfFeatureDetector(2000);  // Detector for features
    
    vector<KeyPoint> srcFeatures;   // Detected key points on first image
    vector<KeyPoint> 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<L2<float>> matcher;       // Use FlannBasedMatcher matcher. It is better
    vector<DMatch> matches;
    matcher.match(srcDescriptors, dstDescriptors, matches);     
    
    // Extract pairs of points
    vector<int> 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<Point2f> sPoints; KeyPoint::convert(srcFeatures, sPoints,pairOfsrcKP);
    vector<Point2f> 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<uchar> 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<const vector<char>&> (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);
    
    0 讨论(0)
  • 2020-12-29 15:09

    Are the images taken standing from the same position but you're just rotated a bit so that they're not aligned correctly? If so then the images are related by a homography - i.e. a projective transformation. Given a set of correspondences between the images (you need at least 4 pairs), the standard way to find the homography is to use the DLT algorithm.

    0 讨论(0)
  • 2020-12-29 15:12

    Avoid linker errors using the below code:

    #include "cv.h"
    #include "highgui.h"
    using namespace cv;
    
    // Directives to linker to include openCV lib files.
    #pragma comment(lib, "opencv_core220.lib") 
    #pragma comment(lib, "opencv_highgui220.lib") 
    #pragma comment(lib, "opencv_contrib220.lib") 
    #pragma comment(lib, "opencv_imgproc220.lib") 
    #pragma comment(lib, "opencv_gpu220.lib") 
    #pragma comment(lib, "opencv_video220.lib") 
    #pragma comment(lib, "opencv_legacy220.lib") 
    
    #pragma comment(lib, "opencv_ml220.lib") 
    #pragma comment(lib, "opencv_objdetect220.lib") 
    #pragma comment(lib, "opencv_ffmpeg220.lib") 
    
    #pragma comment(lib, "opencv_flann220.lib") 
    #pragma comment(lib, "opencv_features2d220.lib") 
    #pragma comment(lib, "opencv_calib3d220.lib") 
    
    // Your code here...
    int main(void){
        Mat B = Mat:eye(3,3,CV_8U);
        return -1;
    }
    
    0 讨论(0)
提交回复
热议问题