Opencv拼接多个图像

时间:2015-04-28 07:55:58

标签: c++ opencv image-stitching

我一直致力于在opencv中拼接多个图像以创建马赛克 我在opencv上关注了这个链接: Stitch multiple images using OpenCV (Python)
这是我到目前为止的代码:

// imgstch.cpp :
// imgstch.cpp :
//#include "stdafx.h"
#include<opencv/cv.h>
#include<opencv/highgui.h>
#include<iostream>
#include<stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
using namespace cv;
int main()
{
//-- Input the two images
cv::Mat img1;
std::vector<cv::KeyPoint> img1_keypoints;
cv::Mat img1_descriptors;
cv::Mat img2;
std::vector<cv::KeyPoint> img2_keypoints;
cv::Mat img2_descriptors;
img1 = cv::imread("/home/ishita/Downloads/ishita/Downloads/Mosaic/b2.JPG");
img2 = cv::imread("/home/ishita/Downloads/ishita/Downloads/Mosaic/b1.JPG");
//-- ORB feature detector, extractor and descriptor
int minHessian = 1800;
OrbFeatureDetector detector( minHessian );
OrbDescriptorExtractor extractor;
detector.detect(img1, img1_keypoints);
detector.detect(img2, img2_keypoints);
extractor.compute(img1, img1_keypoints, img1_descriptors);
extractor.compute(img2, img2_keypoints, img2_descriptors);
//-- Matching descriptor vectors with a brute force matcher
BFMatcher matcher(NORM_HAMMING);
std::vector< DMatch > matches;
matcher.match( img1_descriptors, img2_descriptors, matches );
imshow("image1", img1);
imshow("image2",img2);
//-- Draw matches
Mat img_matches;
drawMatches( img1, img1_keypoints, img2, img2_keypoints, matches, img_matches );
//-- Show detected matches
imshow("Matches", img_matches );imwrite("/home/ishita/img_stitch/img_matches.jpg",img_matches);
double max_dist = 0; double min_dist = 10;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < matches.size(); i++ )
{
double dist = matches[i].distance;
if( dist < min_dist && dist >3)
{
min_dist = dist;
}
if( dist > max_dist) max_dist = dist;
}
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
std::vector< DMatch > good_matches;
for( int i = 0; i < matches.size(); i++ )
{
//cout<<matches[i].distance<<endl;
if( matches[i].distance < 3*min_dist && matches[i].distance > 3)
{
good_matches.push_back( matches[i]); }
}
//calculate the Homography
vector<Point2f> p1, p2;
for (unsigned int i = 0; i < matches.size(); i++) {
p1.push_back(img1_keypoints[matches[i].queryIdx].pt);
p2.push_back(img2_keypoints[matches[i].trainIdx].pt);
}
// Homografía
vector<unsigned char> match_mask;
Mat H = findHomography(p1,p2,CV_RANSAC);
cout << "H = "<< endl << " " << H << endl << endl;
// Use the Homography Matrix to warp the images

cv::Mat result;
result=img1.clone();
warpPerspective(img1,result,H,cv::Size(img1.cols+img2.cols,img1.rows));
cv::Mat half(result,cv::Rect(0,0,img2.cols,img2.rows));
img2.copyTo(half);
imwrite("/home/ishita/img_stitch/result.jpg",result);
imshow( "Result", result );



//for images 2 and 3


cv::Mat img3;
std::vector<cv::KeyPoint> img3_keypoints;
cv::Mat img3_descriptors;

img3 = cv::imread("/home/ishita/Downloads/ishita/Downloads/Mosaic/b3.JPG");

//detector.detect(img2, img2_keypoints);
detector.detect(img3, img3_keypoints);
//extractor.compute(img2, img2_keypoints, img2_descriptors);
extractor.compute(img3, img3_keypoints, img3_descriptors);

matcher.match( img1_descriptors, img3_descriptors, matches );
//imshow("image2", img1);
imshow("image3",img3);
//-- Draw matches
Mat img_matches2;
drawMatches( img1, img1_keypoints, img3, img3_keypoints, matches, img_matches2 );
//-- Show detected matches
imshow("Matches2", img_matches2 );imwrite("/home/ishita/img_stitch/img_matches.jpg",img_matches2);
max_dist = 0; min_dist = 10;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < matches.size(); i++ )
{
double dist = matches[i].distance;
if( dist < min_dist && dist >3)
{
min_dist = dist;
}
if( dist > max_dist) max_dist = dist;
}
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
std::vector< DMatch > good_matches2;
for( int i = 0; i < matches.size(); i++ )
{
//cout<<matches[i].distance<<endl;
if( matches[i].distance < 3*min_dist && matches[i].distance > 3)
{
good_matches2.push_back( matches[i]); }
}
//calculate the Homography
vector<Point2f> p3, p4;
for (unsigned int i = 0; i < matches.size(); i++) {
p3.push_back(img1_keypoints[matches[i].queryIdx].pt);
p4.push_back(img3_keypoints[matches[i].trainIdx].pt);
}
// Homografía
vector<unsigned char> match_mask2;
Mat H2 = findHomography(p3,p4,CV_RANSAC);
Mat H3 = H * H2;
cout << "H2= "<< endl << " " << H2 << endl << endl;
// Use the Homography Matrix to warp the images
cv::Mat result2;
result2 = result.clone();
warpPerspective(result,result2,H3,cv::Size(img3.cols+result.cols,result.rows));
 cv::Mat half2(result,cv::Rect(0,0,img3.cols,img3.rows));
 img3.copyTo(half2);
 imwrite("/home/ishita/img_stitch/result.jpg",result2);
 imshow( "Result2", result2 );




waitKey(0);
return 0;
}

拼接前两张图像的结果符合要求,但拼接第三张图像的结果不合适。

这背后的逻辑或方法的实现可能有什么问题?

图片和结果可以在这里找到: https://drive.google.com/folderview?id=0BxXVoeIUgVW7fnFMbExhTzN4QnRueXZpQmpILTZCWFZoTlZEckxfWV83VjkxMmFNSXdLVWM&usp=sharing

1 个答案:

答案 0 :(得分:0)

这个答案为时已晚,但可能对其他人有所帮助。

在某些算法中,要拼接的图像尺寸必须相同。 (如果问题是这个测试在解决方案下面)

1- you could run program once for (img1 , img2)=>result1. 

2- then for (img2 , img3)=>result2.

3- (result1 , result2) => final

这是另一个同时获取所有图像的示例:

https://www.geeksforgeeks.org/stitching-input-images-panorama-using-opencv-c/