How to make an array of ROI from a list of keypoints [closed]

asked 2015-12-26 01:04:21 -0500

Hi there..Im new to this opencv and really need the explanation how to solve the problem. I try to get a multiple of ROI (array) from a known coordinate but keep on getting this error. image description

Anyone can figure it out what the problem is and how to solve it?? This is my code:

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/features2d.hpp"

using namespace cv;

int main( )

  Mat img_1 = imread( "Colour2.bmp", CV_LOAD_IMAGE_GRAYSCALE );
  Mat img_2 = imread( "Greyscale.bmp", CV_LOAD_IMAGE_GRAYSCALE );
  int i;

  if( ! || ! )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;

  SurfFeatureDetector detector( minHessian );

  std::vector<KeyPoint> keypoints_1;
  std::vector<KeyPoint> keypoints_2;

  detector.detect( img_1, keypoints_1 );
  detector.detect( img_2, keypoints_2 );

  //-- Draw keypoints
  Mat img_keypoints_1,img_keypoints_2;

  drawKeypoints( img_1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT );

  //-- Show detected (drawn) keypoints
  imshow("Input", img_keypoints_1 );
  imshow("Input2", img_keypoints_2 );

  //-- Step 2: Calculate descriptors (feature vectors)
  SurfDescriptorExtractor extractor;

  Mat descriptors_object, descriptors_scene;

  extractor.compute( img_1, keypoints_1, descriptors_object );
  extractor.compute( img_2, keypoints_2, descriptors_scene );

  //-- Step 3: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;  
  //BFMatcher matcher(NORM_L1);
  std::vector< DMatch > matches;
  matcher.match( descriptors_object, descriptors_scene, matches );

  double max_dist = 0; double min_dist = 150; double dist;

  //Quick calculation of min and max distances between keypoints
  for(int i=0; i<descriptors_object.rows; i++)
    dist = matches[i].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;

  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] );

  Point c1, c2;
  std::vector<cv::Mat> ROI;
  Mat img_3 = cv::Mat::zeros(img_2.rows, img_2.cols, CV_8UC1);

  for( unsigned int i = 0; i < good_matches.size(); i++ )
    //-- Get the keypoints from the good matches
        c1.x =  keypoints_1[ good_matches[i].queryIdx ].pt.x;
        c1.y =  keypoints_1[ good_matches[i].queryIdx ].pt.y;

        c2.x=  keypoints_2[ good_matches[i].trainIdx ].pt.x;
        c2.y=  keypoints_2[ good_matches[i].trainIdx ].pt.y;

        //Check the coordinate of good matches
        printf( "-- Good Match [%d] Keypoint 1.x: %d  -- Keypoint 1.y: %d  \n", i, c1.x, c1.y ); 

        /* This is where the problems begin
        //Get@Crop ROI for each good matches on keypoints_1 with area 20x20
        ROI[i] = img_1( cv::Rect(c1.x, c1.y, 20, 20)); 

        //Paste the previous ROI on another image with the same coordinate in img_2
        ROI[i].copyTo(img_3( cv::Rect(c2.x, c2.y, 20, 20)));
  //show final image
  imshow("Final ",img_3);


  return 0;
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by sturkmen
close date 2020-09-27 11:53:55.782057


Problem 1 (maybe?): The ROI you are choosing is not centered on the keypoint, the keypoint is the top left corner. I suspect you intended to have the ROI centered on the keypoint.

Problem 2: You don't check to make sure the keypoint is at least 20 (I suspect you intended 10) pixels from the nearest border. I don't believe SURF has any boundary at the edge of the image that it doesn't put points in, like ORB does.

Tetragramm gravatar imageTetragramm ( 2015-12-26 04:33:12 -0500 )edit

Thanks for your comments. For Problem 1: From my point of view it's doesn't matter if the ROI is centred or not, but the thing is the array must have the value of ROI. Problem 2: I just need an array of ROI values at the coordinate of the keypoints. I don't think it's still relate to the SURF stuff. Please enlighten me if i'm wrong

exolala gravatar imageexolala ( 2015-12-26 06:30:01 -0500 )edit

Ok, it doesn't need to be centered, but you do still have to worry about problem 2. The ROI you are extracting can include areas that are not in the image, which causes the exception. You need to either exclude keypoints too close to the edge, or alter your ROI so that it is fully contained in the image.

Changing your ROI to cv::Rect(MIN(img_cols-1-width), MIN(img_rows-1-height), width, height) should do it. Double check to make sure I don't have an off by one error, but I think that's right.

Tetragramm gravatar imageTetragramm ( 2015-12-27 05:20:38 -0500 )edit