图像分辨率大于 1080 * 1080 的 OpenCV 图像拼接
Posted
技术标签:
【中文标题】图像分辨率大于 1080 * 1080 的 OpenCV 图像拼接【英文标题】:OpenCV Image Stitching with Image Resolutions greater than 1080 * 1080 【发布时间】:2016-10-25 08:32:44 【问题描述】:我一直在使用 OpenCV 在 Raspberry Pi 和基于 Windows 操作系统的 PC 上将两个图像拼接在一起。
#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main (int argc, char** argv)
Mat image_1 = imread (argv[1]);
Mat image_2 = imread (argv[2]);
Mat gray_image_1;
Mat gray_image_2;
cvtColor (image_1, gray_image_1, CV_RGB2GRAY);
cvtColor (image_2, gray_image_2, CV_RGB2GRAY);
// Check if image files can be read
if (!gray_image_1.data)
std::cout << "Error Reading Image 1" << std::endl;
return 0;
if (!gray_image_2.data)
std::cout << "Error Reading Image 2" << std::endl;
return 0;
// Detect the keypoints using SURF Detector
// Based from Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
int minHessian = 50;
SurfFeatureDetector detector (minHessian);
std::vector <KeyPoint> keypoints_object, keypoints_scene;
detector.detect (gray_image_2, keypoints_object);
detector.detect (gray_image_1, keypoints_scene);
// Calculate Feature Vectors (descriptors)
// Based from Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
SurfDescriptorExtractor extractor;
Mat descriptors_object, descriptors_scene;
extractor.compute (gray_image_2, keypoints_object, descriptors_object);
extractor.compute (gray_image_1, keypoints_scene, descriptors_scene);
// Matching descriptor vectors using FLANN matcher
// Based from Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
FlannBasedMatcher matcher;
std::vector <DMatch> matches;
matcher.match (descriptors_object, descriptors_scene, matches);
double max_dist = 0;
double min_dist = 100;
// Quick calculation of max and min distances between keypoints
// Based from Anna Huaman's 'Features2D + Homography to find a known object' Tutorial
for (int i = 0; i < descriptors_object.rows; i++)
double dist = matches[i].distance;
if (dist < min_dist)
min_dist = dist;
// Use matches that have a distance that is less than 3 * min_dist
std::vector <DMatch> good_matches;
for (int i = 0; i < descriptors_object.rows; i++)
if (matches[i].distance < 3 * min_dist)
good_matches.push_back (matches[i]);
std::vector <Point2f> obj;
std::vector <Point2f> scene;
for (int i = 0; i < good_matches.size(); i++)
// Get the keypoints from the good matches
obj.push_back (keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back (keypoints_scene[good_matches[i].trainIdx].pt);
// Find the Homography Matrix
Mat H = findHomography (obj, scene, CV_RANSAC);
// Use the Homography Matrix to warp the images
cv::Mat result;
warpPerspective (image_2, result, H, cv::Size (image_2.cols + image_1.cols, image_2.rows));
cv::Mat half (result, cv::Rect (0, 0, image_1.cols, image_1.rows));
image_1.copyTo (half);
// Write image
imwrite("Update.jpg", result);
waitKey (0);
return 0;
我用作输入的两个图像导致成功。但是,只有当这两个图像的分辨率为
对于 1440 * 1440 和 1944 * 1944 分辨率,我发现 findHomography 无法运行,因为我不再获得超过 3 个好的匹配。 findHomography 需要至少 4 个好的匹配项。
我试过了……
cv::resize(输入图像) - 导致没有分辨率大小的图像为 findHomography 产生足够好的匹配。
min Hessian 增加或减少 - 无变化
最小距离增加或减少 - 没有变化
注意:两个图像重叠并且具有相同的尺寸。
有没有人能解决这个问题?我花了几个小时研究这个问题,只是得出了 OpenCV 图像拼接无法处理高分辨率图像的结论。
下面我将附上两张高分辨率图片,供任何希望提供帮助的人参考。
colour_1_1440
colour_2_1440
我使用的是 OpenCV 2.4.13,而不是新的 OpenCV 3.1.0。
【问题讨论】:
您确定没有在距离过滤器部分丢弃好的匹配项吗?if (matches[i].distance < 3 * min_dist)
你也试过其他的描述符,ORB,SIFT?
我没有尝试过ORB或SIFT等其他描述符。现在我将调查 min_dist 声明,因为我还没有看过那个。
用 3 * min_dist 调整后我发现这是我的问题。谢谢马丁·马蒂拉。让别人检查你的工作总是好的:P
不客气 :) 发现问题后尝试回答您的问题,以便其他用户轻松找到答案
【参考方案1】:
来自 Martin Matilla 的评论:
“你确定你没有在距离过滤器部分丢弃好的匹配吗?if (matches[i].distance
解决方案确实位于 3 * min_dist。我将值“3”更改为“4”以允许处理高分辨率图像。
注意:最初我将“3”更改为“30”,发现第二张输入图像按预期失真。
【讨论】:
以上是关于图像分辨率大于 1080 * 1080 的 OpenCV 图像拼接的主要内容,如果未能解决你的问题,请参考以下文章