// ImageMosaic.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// source code : https://blog.csdn.net/dcrmg/article/details/52629856
// explanation : https://blog.csdn.net/u012384044/article/details/73162675#commentBox
//
#include "pch.h"
#include <iostream>
#include <string.h>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/legacy/legacy.hpp"
using namespace cv;
using namespace std;
//计算原始图像点位在经过矩阵变换后在目标图像上对应位置
Point2f getTransformPoint(const Point2f originalPoint, const Mat &transformMaxtri);
int main(int argc, char *argv[])
{
string filename1 = "100-0038_img.jpg";
string filename2 = "100-0039_img.jpg";
Mat image01 = imread(filename1);
Mat image02 = imread(filename2);
imshow("拼接图像1", image01);
imshow("拼接图像2", image02);
//灰度图转换
Mat image1, image2;
cvtColor(image01, image1, CV_RGB2GRAY);
cvtColor(image02, image2, CV_RGB2GRAY);
//提取特征点
SurfFeatureDetector detector(800); // surf. hessianThreshold
//SiftFeatureDetector detector(800); // sift. nfeatures
vector<KeyPoint> keyPoint1, keyPoint2;
detector.detect(image1, keyPoint1);
detector.detect(image2, keyPoint2);
// 显示特征点
Mat image1KeyPoint, image2KeyPoint;
drawKeypoints(image01, keyPoint1, image1KeyPoint,
Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(image02, keyPoint2, image2KeyPoint,
Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("image1Keypoint", image1KeyPoint);
imshow("image2Keypoint", image2KeyPoint);
//waitKey(0);
//特征点描述,为下边的特征点匹配做准备
SurfDescriptorExtractor descriptor; //surf
//SiftDescriptorExtractor descriptor; //sift
Mat imageDesc1, imageDesc2;
descriptor.compute(image1, keyPoint1, imageDesc1);
descriptor.compute(image2, keyPoint2, imageDesc2);
//获得匹配特征点,并提取最优配对
FlannBasedMatcher matcher;
vector<DMatch> matchePoints;
matcher.match(imageDesc1, imageDesc2, matchePoints, Mat());
// 粗匹配图像
Mat outImg;
drawMatches(image01, keyPoint1, image02, keyPoint2, matchePoints, outImg,
Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("粗匹配结果", outImg);
//waitKey(0);
sort(matchePoints.begin(), matchePoints.end()); //特征点排序
//获取排在前N个的最优匹配特征点
vector<Point2f> imagePoints1, imagePoints2;
for (int i = 0; i < 10; i++)
{
imagePoints1.push_back(keyPoint1[matchePoints[i].queryIdx].pt);
imagePoints2.push_back(keyPoint2[matchePoints[i].trainIdx].pt);
}
//获取图像1到图像2的投影映射矩阵,尺寸为3*3
vector<uchar> inliersMask(imagePoints1.size());
Mat homo = findHomography(imagePoints1, imagePoints2, CV_RANSAC, 3.0, inliersMask);
vector<DMatch>matches_ransac;
// 手动的保留RANSAC过滤后的匹配点对
// 这一步做的没必要,因为最后确定匹配区域的时候只用到了第一个点。
for (int i = 0; i < inliersMask.size(); i++)
{
cout << int(inliersMask[i]) << endl;
if (inliersMask[i])
{
matches_ransac.push_back(matchePoints[i]);
}
}
drawMatches(image01, keyPoint1, image02, keyPoint2, matches_ransac, outImg,
Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("精匹配:", outImg);
cout << "homo:\n" << homo << endl;
Mat adjustMat = (Mat_<double>(3, 3) << 1.0, 0, image01.cols, 0, 1.0, 0, 0, 0, 1.0);
cout << "adjustMat:\n" << adjustMat << endl;
Mat adjustHomo = adjustMat * homo;
cout << "adjustHomo:\n" << adjustHomo << endl;
//获取最强配对点(第一个点)在原始图像和矩阵变换后图像上的对应位置,用于图像拼接点的定位
Point2f originalLinkPoint, targetLinkPoint, basedImagePoint;
originalLinkPoint = keyPoint1[matchePoints[0].queryIdx].pt;
//image01在image02上最强匹配点(第一个点)的对应位置
//perspectiveTransform();
targetLinkPoint = getTransformPoint(originalLinkPoint, adjustHomo);
basedImagePoint = keyPoint2[matchePoints[0].trainIdx].pt;
//图像配准
Mat imageTransform1;
//透视变化
warpPerspective(image01, imageTransform1, adjustMat*homo, Size(image02.cols + image01.cols, image02.rows));
//imshow("imageTransform1", imageTransform1);
// 因为image01已经经过变换(�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
利用OpenCV-2.4.13和vs2017实现SURF/SIFT + RANSAC + 线性加权融合来实现图像的左右拼接,上下也可以拼接,改一下adjustMat就可以(代码中是x偏移量,你换成y的偏移量,把值换成rows就好,同时在计算透视变换的时候Size参数改为(image02.cols, image02.rows + image01.rows)),代码均有注释,同时将每一步结构都显示出来了,附有示例图片,直接就可以运行。
资源推荐
资源详情
资源评论
收起资源包目录
ImageMosaic.zip (19个子文件)
ImageMosaic
ImageMosaic
ImageMosaic
ImageMosaic.vcxproj 9KB
ImageMosaic.vcxproj.user 165B
100-0040_img.jpg 59KB
ImageMosaic.cpp 13KB
100-0023_img.jpg 107KB
拼接结果.jpg 211KB
100-0039_img.jpg 85KB
ImageMosaic.vcxproj.filters 1KB
100-0038_img.jpg 60KB
pch.cpp 188B
100-0024_img.jpg 116KB
100-0025_img.jpg 130KB
pch.h 614B
101-0104_img.jpg 124KB
.vs
ImageMosaic
v15
ipch
AutoPCH
e7d55abe53aad59d.ipch 320KB
beec6b604aac47a8.ipch 320KB
.suo 51KB
Browse.VC.db 18.77MB
ImageMosaic.sln 1KB
共 19 条
- 1
资源评论
- L3583525232019-07-28可参考学习,但有鬼影~
- cxbs2019-05-16还不错,能运行,要事先配置好路径!
MR_Radish666
- 粉丝: 353
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功