c++ - 图像分辨率大于1080 * 1080的OpenCV图像拼接

标签 c++ opencv image-stitching opencv-stitching

我一直在使用 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;
}

我用作输入的两个图像取得了成功。但是,仅当这两个图像的分辨率 <= 1080 * 1080 像素时。

对于 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。

最佳答案

基于 Martin Matilla 的评论:

“您确定没有丢弃距离过滤器部分中的良好匹配吗?if (matches[i].distance < 3 * min_dist)” – Martin Matilla 53 分钟前

解决方案确实位于 3 * min_dist。我将值“3”更改为“4”以允许处理高分辨率图像。

注意:最初我将“3”更改为“30”,发现第二个输入图像按预期扭曲。 <- 只是为了让任何人知道:)

关于c++ - 图像分辨率大于1080 * 1080的OpenCV图像拼接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40235117/

相关文章:

python - 加入两个图像

c++ - 关于函数参数和默认初始化的规则

c++ - 为什么不调用私有(private)成员的默认构造函数?

c++ - 使用 OpenCV 设置 QuickCam Pro 3000 的帧大小?

python - 查找 RGB 颜色 channel 的变化-Python

opencv - 透视图像拼接

c++ - 使用 libsodium、randombytes 错误为 iOS 构建 zeromq

C++:通过引用抛出派生类在捕获基类时不起作用

opencv - CMake搜索OpenCV库

c++ - OpenCV 将 float 据送入图像拼​​接过程