I wrote a program which gets matches between 2 pictures.
And this is the code. but if I use BruteForceMatcher> (not flann) it works.
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
void help()
{
printf("\nThis program demonstrates using features2d detector, descriptor extractor and simple matcher\n"
"Using the SURF desriptor:\n"
"\n"
"Usage:\n matcher_simple <image1> <image2>\n");
}
int main()
{
Mat img1 = imread("C:\\Users\\Hayk\\Desktop\\source1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread("C:\\Users\\Hayk\\Desktop\\source2.bmp", CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
// detecting keypoints
SurfFeatureDetector detector(6000);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
// matching descriptors
FlannBasedMatcher matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
return 0;
}
And this error I am getting after running the program
OpenCV Error: Assertion failed (dataset.type() == CvType<T>::type()) in unknown
function, file c:\Users\vp\work\ocv\opencv\modules\features2d\..\flann\include\o
pencv2/flann/flann.hpp, line 105
Can anyone say to me what I am doing wrong?
Your code works just fine on Linux with OpenCV 2.3.1a.
I've had several problems with the C++ OpenCV's interface for Windows. When I have to use Windows, I use the C interface.
You said it is works with the BruteForceMatcher but not Flann. I created a minimal example. Could you please run this and tell me, whether you get the same error that you got in your question?
Just trying to pin down the problem.
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main()
{
// Five descriptors with random values between 0 and 0.2
Mat descriptors(5, 64, CV_32FC1);
RNG rng;
rng.fill(descriptors, cv::RNG::UNIFORM, 0.0, 0.2);
// the query descriptor should yield a match in row 3 of the train descriptors
Mat query_descriptors;
query_descriptors.push_back(descriptors.row(3));
// Match using Brute Force. On your machine this should work.
BruteForceMatcher< L2<float> > brute_matcher;
vector<DMatch> matches;
brute_matcher.match(query_descriptors, descriptors, matches);
std::cout << "Brute Force Matcher: " << std::endl;
for(int i=0; i<matches.size(); ++i)
{
std::cout << matches[i].queryIdx << " <--> " << matches[i].trainIdx << std::endl;
}
// The code should fail here because we are now going to use the FlannBasedMatcher
std::cout << "Flann Based Matcher: " << std::endl;
FlannBasedMatcher matcher;
matcher.match(query_descriptors, descriptors, matches);
for(int i=0; i<matches.size(); ++i)
{
std::cout << matches[i].queryIdx << " <--> " << matches[i].trainIdx << std::endl;
}
return 0;
}
Related
The highlighted code demonstrate openCV framework is loaded in my C code and it render Police watching. Which is just to demonstrate it works very smooth and very clean code to write.
Target: My webCAM is connected in to the USB port. I would like to capture the live webcam image and match from a local file (/tmp/myface.png), if live webcam match with local file myface.png, it will show the text "Police watching"
How can i now, capture my webCAM on this following code? 2) When the webCAM is captured, how can i load the file and find if it match, on match it shows that text only.
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
#include "opencv/cv.h"
void detectAndDisplay(Mat frame);
//*************
// Set Region of Interest
cv::Rect roi_b;
cv::Rect roi_c;
size_t ic = 0; // ic is index of current element
int ac = 0; // ac is area of current element
size_t ib = 0; // ib is index of biggest element
int ab = 0; // ab is area of biggest element
stringstream ssfn;
//*************
CascadeClassifier face_cascade;
string window_name = "Capture - Face detection";
int filenumber; // Number of file to be saved
string filename;
Mat frameread = imread("test.jpg");
int main(int argc, const char *argv[]){
if (argc != 4) {
cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.ext> </path/to/device id>" << endl;
cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
cout << "\t </path/to/csv.ext> -- Path to the CSV file with the face database." << endl;
cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
// exit(1);
}
CascadeClassifier face_cascade;
CascadeClassifier face_cascade1;
String fn="C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
String fn1="C:\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml";
face_cascade.load(fn);
face_cascade1.load(fn1);
VideoCapture input(0);
if(!input.isOpened()){return -1;}
namedWindow("Mezo",1);
Mat f2;
Mat frame;
std::vector<Rect> faces,faces1;
CvCapture* capture1;
IplImage* f1;
Mat crop;
cv::Rect r;
// detectAndDisplay(frameread);
while(1)
{
ic=0;
ib=0;
ab=0;
ac=0;
input >> frame;
waitKey(10);
//cvtColor(frame, frame, CV_BGR2GRAY);
//cv::equalizeHist(frame,frame);
face_cascade.detectMultiScale(frame, faces, 1.1, 10, CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0), cvSize(300,300));
for(int i=0; i < faces.size();i++)
{
Point pt1(faces[i].x+faces[i].width, faces[i].y+faces[i].height);
Point pt2(faces[i].x,faces[i].y);
Mat faceROI = frame(faces[i]);
face_cascade1.detectMultiScale(faceROI, faces1, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30,30));
for(size_t j=0; j< faces1.size(); j++)
{
Point center(faces[i].x+faces1[j].x+faces1[j].width*0.5, faces[i].y+faces1[j].y+faces1[j].height*0.5);
int radius = cvRound((faces1[j].width+faces1[j].height)*0.25);
circle(frame, center, radius, Scalar(255,0,0), 2, 8, 0);
}
rectangle(frame, pt1, pt2, cvScalar(0,255,0), 2, 8, 0);
}
imshow("Result", frame);
waitKey(3);
char c = waitKey(3);
if(c == 27)
break;
}
return 0;
}
What you are asking about is probably the Face recognition. You should be more clear in your question.
Opencv has a class for doing recognition perfectly, not as you think to do.
Many approaches are available for this technology, Opencv has three algorithms. As well you need to prepare your database of images (labelled faces)
All this steps are described in opencv docs with some examples : http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html
Just you need to read and apply.
Here you can also find a good tutorial for beginners.
My program is getting an input from the webcam and outputting the Gaussian Pyramid in real time. The program runs fine, but when I exit (by pressing a key to trigger the waitKey()), I get an error:
Debug Assertion Failed!
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse))
Line 52: dbgdel.cpp
I suspect this is related to the buildPyramid() function I am using to create the Gaussian Pyramid. The output requires an Array of Mat. The number of mats that are output depends on the number of levels, so the output needs to be a pointer. I don't know if the problem is with initializing the variable or if it doesn't get deleted at the end. I could also just be completely off about the cause.
I am making the Array of Arrays with this:
std::vector<cv::Mat> GPyr;
and I am making the Gaussian Pyramid with this:
buildPyramid(imgMatNew, GPyr, levels, BORDER_DEFAULT);
Any ideas for what is causing the error?
Full Source:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2\objdetect\objdetect.hpp"
using namespace cv;
using namespace std;
int main()
{
CvCapture* capture = 0;
// imgMatNew, imgMatOut were used to grab the current frame
Mat frame, frameCopy, image, imgMatNew, imgMatOut;
std::vector<cv::Mat> GPyr;
int levels = 4;
capture = cvCaptureFromCAM(CV_CAP_ANY); //0=default, -1=any camera, 1..99=your camera
if (!capture)
{
cout << "No camera detected" << endl;
}
//cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
namedWindow("GPyrOut", WINDOW_AUTOSIZE);
namedWindow("imageNew", WINDOW_AUTOSIZE);
if (capture)
{
cout << "In capture ..." << endl;
for (;;)
{
// capture frame from video camera
IplImage* iplImg = cvQueryFrame(capture);
frame = iplImg;
// convert ilpImg into Mat format for easy processing
imgMatNew = cvarrToMat(iplImg, 1);
// Start Image Processing Here
buildPyramid(imgMatNew, GPyr, levels, BORDER_DEFAULT);
// Show Window
imshow("GPyrOut", GPyr[levels]); //show G Pyr, at a certain level, mex index = levels
imshow("imageNew", imgMatNew); //show window
if (waitKey(10) >= 0)
break;
}
// waitKey(0);
}
cvReleaseCapture(&capture);
return 0;
}
so, there's 2 things wrong here.
a) you must not use opencv's outdated c-api, mixing c and c++ calls is the straight road to hell.
b) c++ starts indexing at 0, and the last valid index is size-1, so for 4 levels, levels[4] is out of bounds. please run a debug build to get proper exceptions in this case !
here's the corrected code:
Mat frame, frameCopy, image, imgMatNew, imgMatOut;
std::vector<cv::Mat> GPyr;
int levels = 4;
VideoCapture capture(0);
if (!capture.isOpened())
{
cout << "No camera detected" << endl;
return -1;
}
//cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
namedWindow("GPyrOut", WINDOW_AUTOSIZE);
namedWindow("imageNew", WINDOW_AUTOSIZE);
cout << "In capture ..." << endl;
for (;;)
{
// capture frame from video camera
capture.read(frame);
// Start Image Processing Here
buildPyramid(frame, GPyr, levels, BORDER_DEFAULT);
// Show Window
imshow("GPyrOut", GPyr[levels-1]); //show last level
imshow("imageNew", frame); //show window
if (waitKey(10) >= 0)
break;
}
when training my classifier, i get this error:
Image step is wrong (The matrix is not continuous, thus its number of rows can not be changed) in reshape, file /home/denn/Downloads/opencv-2.4.6.1/modules/core/src/matrix.cpp, line 802
terminate called after throwing an instance of 'cv::Exception'
what(): /home/denn/Downloads/opencv-2.4.6.1/modules/core/src/matrix.cpp:802: error: (-13) The matrix is not continuous, thus its number of rows can not be changed in function reshape
Aborted (core dumped)
I'm working on an Automatic Number Plate Recognition project in C++. all that is left now is train the my SVM.
I resized all my images to a 450 by 450 after researching this but the error persists.
I have studied and looked around but none of the solutions works for me.
any help accorded will be highly appreciated.
// Main entry code OpenCV
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main ( int argc, char** argv )
{
cout << "OpenCV Training SVM Automatic Number Plate Recognition\n";
cout << "\n";
char* path_Plates;
char* path_NoPlates;
int numPlates;
int numNoPlates;
int imageWidth=450; //144
int imageHeight=450; //33
//Check if user specify image to process
if(argc >= 5 )
{
numPlates= atoi(argv[1]);
numNoPlates= atoi(argv[2]);
path_Plates= argv[3];
path_NoPlates= argv[4];
}else{
cout << "Usage:\n" << argv[0] << " <num Plate Files> <num Non Plate Files> <path to plate folder files> <path to non plate files> \n";
return 0;
}
Mat classes;//(numPlates+numNoPlates, 1, CV_32FC1);
Mat trainingData;//(numPlates+numNoPlates, imageWidth*imageHeight, CV_32FC1 );
Mat trainingImages;
vector<int> trainingLabels;
for(int i=0; i< numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_Plates << i << ".jpg";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(1);
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates << i << ".jpg";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);
}
Mat(trainingImages).copyTo(trainingData);
//trainingData = trainingData.reshape(1,trainingData.rows);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);
FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
return 0;
}
I edited the code and made it like this:
// Main entry code OpenCV
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
#include <iostream>
using namespace std;
using namespace cv;
int main ( int argc, char** argv )
{
cout << "OpenCV Training SVM Automatic Number Plate Recognition\n";
cout << "\n";
char* path_Plates;
char* path_NoPlates;
int numPlates;
int numNoPlates;
int imageWidth=450; //144
int imageHeight=450; //33
//Check if user specify image to process
if(argc >= 5 )
{
numPlates= atoi(argv[1]);
numNoPlates= atoi(argv[2]);
path_Plates= argv[3];
path_NoPlates= argv[4];
}else{
cout << "Usage:\n" << argv[0] << " <num Plate Files> <num Non Plate Files> <path to plate folder files> <path to non plate files> \n";
return 0;
}
Mat classes;//(numPlates+numNoPlates, 1, CV_32FC1);
Mat trainingData;//(numPlates+numNoPlates, imageWidth*imageHeight, CV_32FC1 );
Mat trainingImages;
vector<int> trainingLabels;
Mat classes = new Mat();
Mat trainingData = new Mat();
Mat trainingImages = new Mat();
Mat trainingLabels = new Mat();
for(int i=0; i< numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_Plates << i << ".png";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(1);//trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32FC1));//trainingLabels.push_back(1);
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates << i << ".png";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1); //img= img.clone().reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);//trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32FC1));//trainingLabels.push_back(0);
}
trainingImages.copyTo(trainingData);
//trainingData = trainingData.reshape(1,trainingData.rows);
trainingData.convertTo(trainingData, CV_32FC1);
trainingLabels.copyTo(classes);
FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
return 0;
}
but I get this error on compilation:
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:52:27: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:52:27: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:53:32: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:55:34: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:56:34: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
make[2]: *** [CMakeFiles/trainSVM.dir/trainSVM.cpp.o] Error 1
make[1]: *** [CMakeFiles/trainSVM.dir/all] Error 2
make: *** [all] Error 2
I any advice?
As berak pointed out in the comments above, your cv::Mat can become discontinuous in the following instances:
if you extract a part of the matrix using Mat::col(), Mat::diag() , and so on, or construct a matrix header for externally allocated data, such matrices may no longer have [the iscontinuous()] property.
As they point out in the above reference, create your matrices using Mat::create and you won't have this issue.
Update:
So, the function Mat::clone, as our friend berak pointed out in the comments above, will do the trick for you. It calls the function Mat::create. I just tried out the following code, and it worked like a charm.
Mat trainingImages;
vector<int> trainingLabels;
for(int i=0; i< numPlates; i++)
{
stringstream ss;
ss << path_Plates << "grumpy" << i << ".jpg";
std::cout << ss.str() << std::endl;
Mat img =imread(ss.str(), CV_LOAD_IMAGE_GRAYSCALE);
if(! img.data ) {
cout << "Could not open or find the image" << std::endl ;
return -1;
}
else {
img = img.clone().reshape(0,1);
trainingImages.push_back(img);
trainingLabels.push_back(i);
}
}
However, a few notes, it looks like you might not have the right header file names. I used the following with OpenCV 2.4.8 on Ubuntu 12.04:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
Also, make sure to compile it with the OpenCV libraries (i.e. opencv_core and opencv_ml). Hope that helps you in your quest for plate recognition.
i have tried out this file to compile with
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/legacy/legacy.hpp>
using namespace cv;
static void help( char** argv )
{
std::cout << "\nUsage: " << argv[0] << " [path/to/image1] [path/to/image2] \n"
<< "This is an example on how to use the keypoint descriptor presented in the following paper: \n"
<< "A. Alahi, R. Ortiz, and P. Vandergheynst. FREAK: Fast Retina Keypoint. \n"
<< "In IEEE Conference on Computer Vision and Pattern Recognition, 2012. CVPR 2012 Open Source Award winner \n"
<< std::endl;
}
int main( int argc, char** argv ) {
// check http://docs.opencv.org/doc/tutorials/features2d/table_of_content_features2d/table_of_content_features2d.html
// for OpenCV general detection/matching framework details
if( argc != 3 ) {
help(argv);
return -1;
}
// Load images
Mat imgA = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE );
if( !imgA.data ) {
std::cout<< " --(!) Error reading image " << argv[1] << std::endl;
return -1;
}
Mat imgB = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE );
if( !imgB.data ) {
std::cout << " --(!) Error reading image " << argv[2] << std::endl;
return -1;
}
std::vector<KeyPoint> keypointsA, keypointsB;
Mat descriptorsA, descriptorsB;
std::vector<DMatch> matches;
// DETECTION
// Any openCV detector such as
SurfFeatureDetector detector(2000,4);
// DESCRIPTOR
// Our proposed FREAK descriptor
// (roation invariance, scale invariance, pattern radius corresponding to SMALLEST_KP_SIZE,
// number of octaves, optional vector containing the selected pairs)
// FREAK extractor(true, true, 22, 4, std::vector<int>());
FREAK extractor;
// MATCHER
// The standard Hamming distance can be used such as
// BruteForceMatcher<Hamming> matcher;
// or the proposed cascade of hamming distance using SSSE3
BruteForceMatcher<Hamming> matcher;
// detect
double t = (double)getTickCount();
detector.detect( imgA, keypointsA );
detector.detect( imgB, keypointsB );
t = ((double)getTickCount() - t)/getTickFrequency();
std::cout << "detection time [s]: " << t/1.0 << std::endl;
// extract
t = (double)getTickCount();
extractor.compute( imgA, keypointsA, descriptorsA );
extractor.compute( imgB, keypointsB, descriptorsB );
t = ((double)getTickCount() - t)/getTickFrequency();
std::cout << "extraction time [s]: " << t << std::endl;
// match
t = (double)getTickCount();
matcher.match(descriptorsA, descriptorsB, matches);
t = ((double)getTickCount() - t)/getTickFrequency();
std::cout << "matching time [s]: " << t << std::endl;
// Draw matches
Mat imgMatch;
drawMatches(imgA, keypointsA, imgB, keypointsB, matches, imgMatch);
namedWindow("matches", CV_WINDOW_KEEPRATIO);
imshow("matches", imgMatch);
waitKey(0);
}
with this command
gcc freak_demo.cpp `pkg-config opencv --cflags --libs`
and received this error message
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: /tmp/ccwSmrle.o: undefined reference to symbol '_ZNSsD1Ev##GLIBCXX_3.4'
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: note: '_ZNSsD1Ev##GLIBCXX_3.4' is defined in DSO /usr/lib64/libstdc++.so.6 so try adding it to the linker command line
/usr/lib64/libstdc++.so.6: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
I don't know what GLIBCXX is. Which package (OpenSuse 13.1, gcc 4.8) do I have to install? I don't know how to interpret the error message, any help is appreciated.
As Daniel Frey said in his comment, use g++ instead of gcc. This solved the exact same problem for me, but for the compilation of a totally different program.
I am trying to understand how to get the descriptor for a given KeyPoint in OpenCV. So far my code looks like follows:
#include <iostream>
#include "opencv2/opencv.hpp"
typedef cv::Mat Image;
int main(int argc, const char * argv[])
{
Image imgA = cv::imread("images/buddhamulticam_total100.png",
CV_LOAD_IMAGE_GRAYSCALE);
Image imgB = cv::imread("images/buddhamulticam_total101.png",
CV_LOAD_IMAGE_GRAYSCALE);
cv::Ptr<cv::FeatureDetector> detector =
cv::FeatureDetector::create("ORB");
cv::Ptr<cv::DescriptorExtractor> descriptor =
cv::DescriptorExtractor::create("ORB");
std::vector<cv::KeyPoint> keyPointsA, keyPointsB;
keyPointsA.push_back(cv::KeyPoint(0,0,5));
keyPointsB.push_back(cv::KeyPoint(10,10,5));
cv::Mat descriptorA, descriptorB;
descriptor->compute(imgA, keyPointsA, descriptorA);
descriptor->compute(imgB, keyPointsB, descriptorB);
std::cout << "DescriptorA (" << descriptorA.rows << "," <<
descriptorA.cols << ")" << std::endl;
std::cout << "DescriptorB (" << descriptorB.rows << ","
<< descriptorB.cols << ")" << std::endl;
return 0;
}
The problem is that I am getting no data in the descriptor. What am I missing?
Could you explain in more detail what are the params passed to the KeyPoint object? I am new to computer vision + OpenCV, so probably a better explanation (than OpenCV's documentation) could help.
You're trying to computer ORB on the points (0,0) and (10,10), but they are too close to the image border, so ORB can't compute descriptors in those locations. ORB (as well as the other binary descriptors) filters them out.
EDIT: since you asked about usage, I'm editing the answer. You should pass the whole image. I use it as:
Ptr<FeatureDetector> detector = FeatureDetector::create(detector_name);
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create(descriptor_name);
detector->detect(imgK, kp);
descriptor->compute(imgK, kp, desc);