How to make an array of ROI from a list of keypoints [closed]
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.
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( !img_1.data || !img_2.data )
{ 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);
waitKey(0);
return 0;
}
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.
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
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.