基于opencv的图像配准

思路就是先对两幅图像进行特征点匹配,然后由匹配的特征点计算出变换矩阵,再使用变换矩阵进行仿射变换即可,原理有点像摄像机模型。

#include<iostream>
#include <opencv2/opencv.hpp>

int main(){
    cv::VideoCapture video;
    video.open("/home/dx/桌面/运动检测/motion_detect/TGIR-WN.avi");

    cv::Mat img1,img2;
     cv::Mat image_1280_1024;
    std::vector<cv::KeyPoint> RAN_KP_Src, RAN_KP_Dst;
    std::vector<cv::Point2f> pSrc, pDst;

     video>>img1;
     for(int i=0;i<60;i++){
        video>>img2;
     }

     double angle = 10;
    cv::Point2f center((img1.cols - 1) / 2.0, (img1.rows - 1) / 2.0);
    cv::Mat rotation_matix = cv::getRotationMatrix2D(center, angle, 1.0);
    cv::warpAffine(img1, img2, rotation_matix, img1.size());


     cv::imshow("img1",img1);
     cv::imshow("img2",img2);

    cv::Ptr<cv::FastFeatureDetector> _detector;
    cv::Ptr<cv::SiftDescriptorExtractor> _extrator;
    _detector = cv::FastFeatureDetector::create(16);
    _extrator = cv::SiftFeatureDetector::create(2048);

    std::vector<cv::KeyPoint> _keyPoints[2];
    cv::Mat _descriptor[2];

     _detector->detect(img1, _keyPoints[0]);
    _extrator->compute(img1, _keyPoints[0],_descriptor[0]);

     _detector->detect(img2, _keyPoints[1]);
    _extrator->compute(img2, _keyPoints[1],_descriptor[1]);

     cv::BFMatcher bfMatcher;
    std::vector<cv::DMatch> dMatches;
    std::vector<cv::DMatch> mMatches;

    bfMatcher.match(_descriptor[0], _descriptor[1],dMatches);
    std::cout << "The number of match:" << dMatches.size() << std::endl;

     cv::Mat homo;

    double min_dist = dMatches[0].distance, max_dist =
                                                dMatches[0].distance;
    for (int32_t m = 0; m < dMatches.size(); m++)
    {
        if (dMatches[m].distance < min_dist)
        {
            min_dist = dMatches[m].distance;
        }
        if (dMatches[m].distance > max_dist)
        {
            max_dist = dMatches[m].distance;
        }
    }
    

    std::vector<cv::DMatch> goodMatches;
    for (int32_t m = 0; m < dMatches.size(); m++)
    {
        if (dMatches[m].distance < 0.4 * max_dist)
        {
            goodMatches.push_back(dMatches[m]);
        }
    }

    mMatches = goodMatches;
    std::cout << "mMatches:" << mMatches.size() << std::endl;
    // queryidx是匹配点对在查询图上的索引
    //trainidx是匹配点对在训练图上的索引
    // std::cout<<_keyPoints[0]<<std::endl;
    for (size_t i = 0; i < mMatches.size(); i++)
    {
        RAN_KP_Src.push_back(_keyPoints[0][goodMatches[i].queryIdx]); 
        RAN_KP_Dst.push_back(_keyPoints[1][goodMatches[i].trainIdx]);
    }
    //pt: coordinates of the keypoint
    for (size_t i = 0; i < mMatches.size(); i++)
    {
        pSrc.push_back(RAN_KP_Src[i].pt);
        pDst.push_back(RAN_KP_Dst[i].pt);
    }

     homo = cv::estimateRigidTransform(pSrc, pDst, true);
     std::cout<<homo;

     cv::Mat result;
     cv::warpAffine(img1, result, homo, img1.size());


     cv::imshow("img3",result);
     cv::waitKey(0);


    return 0;


}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值