Starwolf-001
Starwolf-001

Reputation: 202

OpenCV Image Stitching with Image Resolutions greater than 1080 * 1080

I've been working with OpenCV to stitch two images together on a Raspberry Pi and on a Windows OS based 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;
}

The two images I use as inputs result in success. But, only when those two images have resolutions of <= 1080 * 1080 pixels.

For 1440 * 1440 and 1944 * 1944 resolutions I found that the findHomography couldn't function because I was no longer getting more than 3 good matches. findHomography needs at least 4 good matches.

I have tried...

cv::resize(the input images) - results in no resolution size images producing enough good matches for the findHomography.

min Hessian increased or decreased - no change

minimum distance increased or decreased - no change

Note: Both images overlap and have the same dimensions.


Does anyone have a solution to this problem? I have spent a few hours researching this issue and only being lead to the conclusion that OpenCV Image Stitching cannot process high resolution images.

Below I'll include two high resolution images for anyone wishing to help.

colour_1_1440

colour_2_1440

I was using OpenCV 2.4.13 and not the new OpenCV 3.1.0.

Upvotes: 2

Views: 1058

Answers (1)

Starwolf-001
Starwolf-001

Reputation: 202

Based from Martin Matilla's comment:

"are you sure you are not discarding good matches in the distance filter section? if (matches[i].distance < 3 * min_dist)" – Martin Matilla 53 mins ago

The solution did lie at 3 * min_dist. I changed the value '3' to '4' to allow for high resolution images to be processed.

Note: Originally I changed '3' to '30' and found that the 2nd input image was distorted as expected. <- Just to let anyone know :)

Upvotes: 3

Related Questions