OPENCV (Unsupported format or combination formats) SURF - opencv

anyone familiar with this error? I tested a surf descriptor in real-time. I want to use it for recognition of different species of fish using of this features. Sometimes the program is okay but sometimes it gets an error. The compilation is Build successfully. After the compilation this error show.
#include <opencv2\imgproc\imgproc_c.h>
#include <stdio.h>
#include <math.h>
#include <opencv\highgui.h>
#include <opencv\cv.h>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/legacy/legacy.hpp>
using namespace cv;
#define nimg 3
int main()
{
Mat object = imread( "D:/galunggong.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat object1 = imread( "D:/sapsap.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat object2 = imread( "D:/bisugo.jpg",CV_LOAD_IMAGE_GRAYSCALE );
// Mat object3 = imread( "4.jpg", CV_LOAD_IMAGE_GRAYSCALE );
//Mat object4 = imread( "5.jpg", CV_LOAD_IMAGE_GRAYSCALE );
if( !object.data )
{
std::cout<< "Error reading object " << std::endl;
return -1;
}
if( !object1.data )
{
std::cout<< "Error reading object " << std::endl;
return -1;
}
if( !object2.data )
{
std::cout<< "Error reading object " << std::endl;
return -1;
}
//Detect the keypoints using SURF Detector
int minHessian = 1000;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> kp_object;
std::vector<KeyPoint> kp_object1;
std::vector<KeyPoint> kp_object2;
std::vector<KeyPoint> kp_object3;
std::vector<KeyPoint> kp_object4;
detector.detect( object, kp_object );
detector.detect( object1, kp_object1 );
detector.detect( object2, kp_object2 );
//Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat des_object;
Mat des_object1;
Mat des_object2;
extractor.compute( object, kp_object, des_object );
extractor.compute( object1, kp_object1, des_object1 );
extractor.compute( object2, kp_object2, des_object2 );
FlannBasedMatcher matcher;
CvCapture* cap = cvCreateCameraCapture(0);
cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, 320);
cvSetCaptureProperty( cap, CV_CAP_PROP_FRAME_HEIGHT, 240 );
namedWindow("Good Matches");
std::vector<Point2f> obj_corners(4);
//Get the corners from the object
obj_corners[0] = cvPoint(0,0);
obj_corners[1] = cvPoint( object.cols, 0 );
obj_corners[2] = cvPoint( object.cols, object.rows );
obj_corners[3] = cvPoint( 0, object.rows );
char key = 'a';
int framecount = 0;
Mat frame;
Mat des_image, img_matches;
char vect[nimg];
char contor;
char ok, ko;
while (1)
{
frame = cvQueryFrame(cap);
if (framecount < 5)
{
framecount++;
continue;
}
std::vector<KeyPoint> kp_image;
std::vector<vector<DMatch > > matches;
std::vector<vector<DMatch > > matches1;
std::vector<vector<DMatch > > matches2;
std::vector<DMatch > good_matches;
std::vector<DMatch > good_matches1;
std::vector<DMatch > good_matches2;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
std::vector<Point2f> scene_corners(4);
Mat H;
Mat image;
cvtColor(frame, image, CV_RGB2GRAY);
detector.detect( image, kp_image );
extractor.compute( image, kp_image, des_image );
matcher.knnMatch(des_object, des_image, matches, 2);
// printf("d \n");
//////////////////////////////////////////////////////
contor=0;
for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int)
matches[i].size()<=2 && (int) matches[i].size()>0))
{
good_matches.push_back(matches[i][0]);
}
}
vect[contor]=good_matches.size();
/////////////////////////////////////////////////////
contor=1;
matcher.knnMatch(des_object1, des_image, matches1, 2);
for(int i = 0; i < min(des_image.rows-1,(int) matches1.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if((matches1[i][0].distance < 0.6*(matches1[i][1].distance)) && ((int)
matches1[i].size()<=2 && (int) matches1[i].size()>0))
{
good_matches1.push_back(matches1[i][0]);
}
}
vect[contor]=good_matches1.size();
/////////////////////////////////////////////////////
contor=2;
matcher.knnMatch(des_object2, des_image, matches2, 2);
for(int i = 0; i < min(des_image.rows-1,(int) matches2.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if((matches2[i][0].distance < 0.6*(matches2[i][1].distance)) && ((int)
matches2[i].size()<=2 && (int) matches2[i].size()>0))
{
good_matches2.push_back(matches2[i][0]);
}
}
vect[contor]=good_matches2.size();
////////////////////////////////////////////////////
/*
contor =3;
matcher.knnMatch(des_object, des_image, matches3, 2);
for(int i = 0; i < min(des_image.rows-1,(int) matches3.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if((matches3[i][0].distance < 0.6*(matches3[i][1].distance)) && ((int)
matches3[i].size()<=2 && (int) matches3[i].size()>0))
{
good_matches3.push_back(matches[i][0]);
}
}
vect[contor]=good_matches3.size();
//////////////////////////////////////////////////
contor=4;
matcher.knnMatch(des_object, des_image, matches4, 2);
for(int i = 0; i < min(des_image.rows-1,(int) matches4.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if((matches4[i][0].distance < 0.6*(matches4[i][1].distance)) && ((int)
matches4[i].size()<=2 && (int) matches4[i].size()>0))
{
good_matches4.push_back(matches[i][0]);
}
}
vect[contor]=good_matches4.size();
*/
printf("%d %d %d \n ",vect[0],vect[1],vect[2]);
ok=0;
for (contor=1;contor<nimg;contor++)
if (vect[contor]>vect[contor-1])
ok=contor;
for (ko=10;ko>3;ko++)
{
if (ok==0 && vect[ok]>ko)
{printf("Forward \n");
ko=2;}
else if (ok==1 && vect[ok]>ko)
{printf("Turn Left \n");
ko=2;}
else if (ok==2 && vect[ok]>ko)
{printf("Turn Right \n");
ko=2;}
}
//Show detected matches
imshow( "Good Matches",frame /*img_matches*/ );
key = waitKey(1);
}
}

Sometimes SURF cannot find any feature points so it may return an empty descriptor.
You should check the descriptors for data:
if(des_object.empty()||des_object1.empty()||des_object2.empty())
{
std::cout<<"Empty descriptor(s)."<<std::endl;
return -1;
}

Related

Implementing Lucas Kanade Method

I have a problem with the execution of my code.
I am trying to make this work:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
int main( )
{
Mat src1,src2;
namedWindow( "corner", CV_WINDOW_AUTOSIZE );
namedWindow( "result", CV_WINDOW_AUTOSIZE );
src1 = imread("RGB_32.png", CV_LOAD_IMAGE_COLOR);
src2 = imread("RGB_33.png", CV_LOAD_IMAGE_COLOR);
//*********************************************************************************
Mat im1,im2;
cvtColor(src1, im1, CV_RGB2GRAY);
cvtColor(src2, im2, CV_RGB2GRAY);
//******************ReduceImageSizeAndDetectCorner**********************************
Mat im2c,
tmp = im2;
pyrDown(tmp,im2c,Size( tmp.cols/2, tmp.rows/2));
Mat dst = Mat::zeros( im2c.size(), CV_32FC1 );
int blockSize = 3;
int apertureSize = 3;
double c = 0.09;
cornerHarris(im2c,dst,blockSize, apertureSize, c, BORDER_DEFAULT);
Mat dst_norm, dst_norm_scaled;
normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
convertScaleAbs( dst_norm, dst_norm_scaled );
int w=23,nb_pt=0,l=0, alpha=143;
/// Drawing a circle around corners
for( int j = 0+w; j < dst_norm.rows-w ; j++ ){
for( int i = 0+w; i < dst_norm.cols-w; i++ ){
if( (int) dst_norm.at<float>(j,i) > alpha )
{
circle( im2c, Point( i, j ), 0.5, Scalar(0,0,255), 4, 8, 0 );
nb_pt ++ ;
}
}
}
Mat C= Mat:: zeros(nb_pt,2,CV_32FC1) ;
for( int j = 0+w; j < dst_norm.rows-w ; j++ ){
for( int i = 0+w; i < dst_norm.cols-w; i++ ){
if( (int) dst_norm.at<float>(j,i) > alpha ){
C.at <float> (l,0)=j;
C.at <float> (l,1)=i;
l++;
}
}
}
C=2*C;
//******************ImplementLucas&KanadeMethod**************************************
Mat1f Cx,Cy;
Mat Ix_m,Iy_m,It_m,It1,It2;
Cx = (Mat_<float>(2,2) << -1,1,-1,1);
Cy= (Mat_<float>(2,2) << -1,-1,1,1);
Mat Ct1 = (Mat_<float>(2,2) << -1,-1,-1,-1);
Mat Ct2 = Mat::ones( 2, 2, CV_8U );
filter2D(im1,Ix_m,-1,Cx,Point(-1,-1),0,BORDER_DEFAULT);
filter2D(im1,Iy_m,-1,Cy,Point(-1,-1),0,BORDER_DEFAULT);
filter2D(im1,It1,-1,Ct1,Point(-1,-1),0,BORDER_DEFAULT);
filter2D(im1,It2,-1,Ct2,Point(-1,-1),0,BORDER_DEFAULT);
add(It1,It2,It_m);
//initialiser le flot
//Mat u = Mat::zeros( 1, nb_pt, CV_32FC1 );
//Mat v = Mat::zeros( 1, nb_pt, CV_32FC1 );
Mat Ix,Ixd,Iy,Iyd,It,Itd,b,nu,A;
int u,v ;
cv::Scalar color(0,0,255);
int size = 10 ;
int thickness = 10 ;
for (int k=0 ; k < nb_pt ; ++k) {
int j= C.at <float> (k,0);
int i= C.at <float> (k,1);
Ix= Ix_m(Range(j-w,j+w),Range(i-w,i+w));
Iy= Iy_m(Range(j-w,j+w),Range(i-w,i+w));
It= It_m(Range(j-w,j+w),Range(i-w,i+w));
redim(Ix,Ixd);
redim(Iy,Iyd);
redim(It,Itd);
multi(Itd,b);
funct(Ixd,Iyd,A);
Mat inv = A.inv(DECOMP_SVD);
nu = inv * b ;
u= nu.at<float> (0,0);
v= nu.at<float> (0,1);
//cout << "u = "<< u << endl ;
//cout << "v = "<< v << endl ;
cvQuiver(src2,i,j,u,v,color, size, thickness);
}
imshow( "result", src2 );*/
waitKey();
}
I have a problem with the for loop. When k = 2, I get the error "core dumped". But, when I run the code case by case, that is to say I take the case k=0 then k=1,2,..., it works.
Any help please? when k=2

Accurate subpixel edge location in C (OPENCV)

I want to find subpixel and I resarched this topic However I think that subpixels must be such as 152.6 , 49.3 ...
I find this document in opencv http://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=cornersubpix#cornersubpix
And I try this code
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src, src_gray;
int maxCorners = 10;
int maxTrackbar = 50;
RNG rng(11111);
char* source_window = "Image";
void goodFeaturesToTrack_Demo( int, void* );
int main( int argc, char** argv )
{
src = imread( "a.png", 1 );
cvtColor( src, src_gray, CV_BGR2GRAY );
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo);
imshow( source_window, src );
goodFeaturesToTrack_Demo( 0, 0 );
waitKey(0);
return(0);
}
void goodFeaturesToTrack_Demo( int, void* )
{
if( maxCorners < 1 )
{ maxCorners = 1; }
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
bool useHarrisDetector = false;
double k = 0.04;
Mat copy;
copy = src.clone();
goodFeaturesToTrack( src_gray,corners,maxCorners,qualityLevel,minDistance,Mat(),blockSize,useHarrisDetector,k );
cout<<"** Number of corners detected: "<<corners.size()<<endl;
int r = 4;
for( int i = 0; i < corners.size(); i++ )
{ circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255),rng.uniform(0,255)), -1, 8, 0 ); }
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, copy );
Size winSize = Size( 10, 10 );
Size zeroZone = Size( -1, -1 );
TermCriteria criteria = TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001 );
cornerSubPix( src_gray, corners, winSize, zeroZone, criteria );
for( int i = 0; i < corners.size(); i++ )
{ cout<<" -- Refined Corner ["<<i<<"] ("<<corners[i].x<<","<<corners[i].y<<")"<<endl; }
}
But I have this result:
this code ofind only corner's subpixel I want to find edge's subpixel

Panoramic image Stitching Algorithm

Maybe the problem is, that I'm not good at English.
I am new to openCV. I want know area which stitcher merge. like this↓
to
If you know the order in which your image is taken then you may follow this code for stitching your images together. If the order is not known then the solution becomes more complex. Also, this code is designed for images of same size, if your camera is shifted it may result in some erroneous result.Implement some checks for proper understanding. You may refer to this article "http://ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/"for much proper understanding of the stitching function that has been called twice in main.
#include <stdio.h>
#include <iostream>
#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;
void stitching( cv::Mat&,cv::Mat& ,cv::Mat& );
int main()
{
Mat image1= imread("image1.jpg");
Mat image2= imread("image2.jpg");
Mat image3= imread("image3.jpg");
Mat gray_image1;
Mat gray_image2;
Mat gray_image3;
Mat result1,result2;
// Convert to Grayscale
cvtColor( image1, gray_image1, CV_RGB2GRAY );
cvtColor( image2, gray_image2, CV_RGB2GRAY );
cvtColor( image3, gray_image3, CV_RGB2GRAY );
stitching(gray_image1,gray_image2,result1);
stitching(result1,gray_image3,result2);
cv::imshow("stitched image"result2);
cv::WaitKey(0);
}
void stitching( cv::Mat& im1,cv::Mat& im2,cv::Mat& stitch_im)
{
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
std::vector< KeyPoint > keypoints_object, keypoints_scene;
detector.detect(im1, keypoints_object );
detector.detect(im2, keypoints_scene );
SurfDescriptorExtractor extractor;
Mat descriptors_object, descriptors_scene;
extractor.compute( im1, keypoints_object, descriptors_object );
extractor.compute( im2, keypoints_scene, descriptors_scene );
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_object, descriptors_scene, matches );
double max_dist = 0; double min_dist = 100;
for( int i = 0; i < descriptors_object.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = 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++ )
{
obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}
Mat H = findHomography( obj, scene, CV_RANSAC );
cv::Mat result;
warpPerspective(im1,stitch_im,H,cv::Size(im1.cols+im2.cols,im1.rows));
}

Opencv Surf Bug error

Anyone familiar with this error? I tested a surf descriptor in real-time and it worked well but after few seconds it crashes and I got this error.
It was related when no points were detected. I run my code again and have the detected object stays for more than 2 mins and still no error. but when I removed the object and there were no points, it crashes again after 40 secs.
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/legacy/legacy.hpp"
using namespace cv;
using namespace std;
char key = 'a';
int framecount = 0;
SurfFeatureDetector detector(1000);
SurfDescriptorExtractor extractor;
FlannBasedMatcher matcher;
Mat frame, des_object, image;
Mat des_image, img_matches, H;
std::vector<KeyPoint> kp_object;
std::vector<Point2f> obj_corners(4);
std::vector<KeyPoint> kp_image;
std::vector<vector<DMatch > > matches;
std::vector<DMatch > good_matches;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
std::vector<Point2f> scene_corners(4);
int main()
{
//reference image
Mat object = imread("D:/milo.jpg", CV_LOAD_IMAGE_GRAYSCALE );
if( !object.data )
{
std::cout<< "Error reading object " << std::endl;
return -1;
}
//compute detectors and descriptors of reference image
detector.detect( object, kp_object );
extractor.compute( object, kp_object, des_object );
//create video capture object
CvCapture* capture = cvCaptureFromCAM(0);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 270);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 190);
//Get the corners from the object
obj_corners[0] = cvPoint(0,0);
obj_corners[1] = cvPoint( object.cols, 0 );
obj_corners[2] = cvPoint( object.cols, object.rows );
obj_corners[3] = cvPoint( 0, object.rows );
//wile loop for real time detection
while (key != 27)
{
Mat frame;
frame = cvQueryFrame(capture);
if (framecount < 5)
{
framecount++;
continue;
}
Mat des_image, img_matches;
std::vector<KeyPoint> kp_image;
std::vector<vector<DMatch > > matches;
std::vector<DMatch > good_matches;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
std::vector<Point2f> scene_corners(4);
Mat H;
Mat image;
cvtColor(frame, image, CV_RGB2GRAY);
detector.detect( image, kp_image );
extractor.compute( image, kp_image, des_image );
matcher.knnMatch(des_object, des_image, matches, 2);
int goodMatchesCounter =0;
for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS
SENSITIVE TO SEGFAULTS
{
if(((int)matches[i].size()<=2 && (int)matches[i].size()>0) && (matches[i}
[0].distance<0.6*(matches[i][1].distance)))
{
// good_matches.push_back(matches[i][0]);
obj.push_back( kp_object[ matches[i][0].queryIdx ].pt );
scene.push_back( kp_image[ matches[i][0].trainIdx ].pt );
goodMatchesCounter++;
}
}
//Draw only "good" matches
// drawMatches( object, kp_object, image, kp_image, good_matches, img_matches,
Scalar::all(-1), Scalar::all(-1), vector<char>(),
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
if (goodMatchesCounter >= 4)
{
H = findHomography( obj, scene, CV_RANSAC );
perspectiveTransform( obj_corners, scene_corners, H);
//Draw lines between the corners (the mapped object in the scene image )
line( image, scene_corners[0], scene_corners[1], Scalar( 0, 0, 0), 4 );
line( image, scene_corners[1], scene_corners[2], Scalar( 0, 0, 0),
4 );
line( image, scene_corners[2], scene_corners[3], Scalar( 0, 0, 0),
4 );
line( image, scene_corners[3], scene_corners[0], Scalar( 0, 0, 0),
4 );
}
//Show detected matches
imshow( "Good Matches", image );
key = waitKey(1);
}
return 0;
}

Strange result of SURF_GPU and BruteForceMatcher_GPU with knnMatch

OpenCV 2.4.5, CUDA 5.0
I tried to transfer my SURF matcher from the CPU to the GPU and got such a strange result. I use knnMatch and findHomography + perspectiveTransform together with my function, which checks the corners of the bounding box for the result to more precision.
GPU part:
const int baseImagesSize = baseImages.size();
SURF_GPU surf(1500);
surf.extended = false;
GpuMat keypoints_test_GPU, descriptors_test_GPU;
surf(frame, GpuMat(), keypoints_test_GPU, descriptors_test_GPU);
vector<float> descriptors_test_CPU;
surf.downloadDescriptors(descriptors_test_GPU, descriptors_test_CPU);
Mat descriptors_test_CPU_Mat(descriptors_test_CPU);
vector<Point2f> objs_corners(4);
BruteForceMatcher_GPU< L2<float> > matcher;
vector<KeyPoint> keypoints_test_CPU;
surf.downloadKeypoints(keypoints_test_GPU, keypoints_test_CPU);
for (int i = 0; i < baseImagesSize; ++i)
{
//Get the corners from the object
objs_corners[0] = cvPoint(0,0);
objs_corners[1] = cvPoint( baseImages[i].cols, 0 );
objs_corners[2] = cvPoint( baseImages[i].cols, baseImages[i].rows );
objs_corners[3] = cvPoint( 0, baseImages[i].rows );
//cout<<endl<<objs_corners[0]<<" "<<objs_corners[1]<<" "<<objs_corners[2]<<" "<<objs_corners[3]<<endl;
GpuMat keypoints_tmp_GPU, descriptors_tmp_GPU;
surf(baseImages[i], GpuMat(), keypoints_tmp_GPU, descriptors_tmp_GPU);
GpuMat trainIdx, distance;
vector< vector<DMatch> > matches;
matcher.knnMatch(descriptors_test_GPU, descriptors_tmp_GPU, matches, 2);
vector<KeyPoint> keypoints_tmp_CPU;
surf.downloadKeypoints(keypoints_tmp_GPU, keypoints_tmp_CPU);
std::vector<DMatch > good_matches;
for(int k = 0; k < min(descriptors_test_CPU_Mat.rows-1,(int) matches.size()); k++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
{
if((matches[k][0].distance < 0.6*(matches[k][1].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0))
{
good_matches.push_back(matches[k][0]);
}
}
vector<Point2f> obj;
vector<Point2f> scene;
vector<Point2f> scene_corners(4);
Mat H;
Mat img (baseImages[i]), img_matches, frame_cpu (frame);
std::ostringstream o_stream;
o_stream<<"Logo_save/"<<baseImagesNames[i];
try
{
drawMatches( img, keypoints_tmp_CPU, frame_cpu, keypoints_test_CPU, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
imwrite(o_stream.str(),img_matches);
}
catch(...)
{
cout<<"Error in drawMatches name: "<< baseImagesNames[i]<<endl;
}
if (good_matches.size() >= 4)
{
for( int k = 0; k < good_matches.size(); k++ )
{
//Get the keypoints from the good matches
obj.push_back( (keypoints_tmp_CPU)[ good_matches[k].queryIdx ].pt );
scene.push_back( keypoints_test_CPU[ good_matches[k].trainIdx ].pt );
}
cout<<good_matches.size()<<" "<<baseImagesNames[i]<<endl;
H = findHomography( obj, scene, CV_RANSAC);
perspectiveTransform( objs_corners, scene_corners, H);
bool falseDetect = isSmallAngle(scene_corners);
//cout<< falseDetect<< endl;
if(!falseDetect)
{
cout<<"DETECT "<<baseImagesNames[i]<<endl;
}
}
matcher.clear();
}
Bad result on GPU (MIN_HESSIAN==1500):
Bad result on GPU (MIN_HESSIAN==400):
CPU part:
SurfFeatureDetector detector( MIN_HESSIAN );//MIN_HESSIAN==400
const int baseImagesSize = baseImages.size();
vector< vector<KeyPoint> > kp_objects(baseImagesSize);
//Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
vector<Mat> des_objects(baseImagesSize);
FlannBasedMatcher matcher;
//namedWindow("SURF feature detector");
vector< vector<Point2f> > objs_corners(baseImagesSize,vector<Point2f>(4));
for (int i = 0; i < baseImagesSize; ++i)
{
detector.detect(baseImages[i], kp_objects[i]);
extractor.compute(baseImages[i], kp_objects[i], des_objects[i]);
//Get the corners from the object
(objs_corners[i])[0] = cvPoint(0,0);
(objs_corners[i])[1] = cvPoint( baseImages[i].cols, 0 );
(objs_corners[i])[2] = cvPoint( baseImages[i].cols, baseImages[i].rows );
(objs_corners[i])[3] = cvPoint( 0, baseImages[i].rows );
}
Mat des_image;
std::vector<KeyPoint> kp_image;
Mat image;
cvtColor(frame, image, CV_RGB2GRAY);
detector.detect( image, kp_image );
extractor.compute( image, kp_image, des_image );
for (int i = 0; i < baseImagesSize; ++i)
{
Mat img_matches;
std::vector<vector<DMatch > > matches;
std::vector<DMatch > good_matches;
std::vector<Point2f> obj;
std::vector<Point2f> scene;
std::vector<Point2f> scene_corners(4);
Mat H;
matcher.knnMatch(des_objects[i], des_image, matches, 2);
for(int k = 0; k < min(des_image.rows-1,(int) matches.size()); k++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
{
if((matches[k][0].distance < 0.6*(matches[k][4].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0))
{
good_matches.push_back(matches[k][0]);
}
}
//Draw only "good" matches
std::ostringstream o_stream;
o_stream<<"Logo_save/"<<baseImagesNames[i];
try
{
drawMatches( baseImages[i], kp_objects[i], image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
imwrite(o_stream.str(),img_matches);
}
catch(...)
{
cout<<"Error in drawMatches name: "<< baseImagesNames[i]<<endl;
}
if (good_matches.size() >= 4)
{
for( int k = 0; k < good_matches.size(); k++ )
{
//Get the keypoints from the good matches
obj.push_back( (kp_objects[i])[ good_matches[k].queryIdx ].pt );
scene.push_back( kp_image[ good_matches[k].trainIdx ].pt );
}
H = findHomography( obj, scene, CV_RANSAC);
perspectiveTransform( objs_corners[i], scene_corners, H);
bool falseDetect = isSmallAngle(scene_corners);
if(!falseDetect)
{
cout<<"DETECT "<<baseImagesNames[i]<<endl;
}
}
}
Good result on CPU (MIN_HESSIAN==400):
Problem solved here topic
Swap parameters in drawMatches call:
drawMatches(frame_cpu, keypoints_test_CPU, img, keypoints_tmp_CPU, ...);
Swap keypoints_tmp_CPU and keypoints_test_CPU:
obj.push_back( keypoints_test_CPU[ good_matches[k].trainIdx ].pt );
scene.push_back( (keypoints_tmp_CPU)[ good_matches[k].queryIdx ].pt );

Resources