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