1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

modified features2d interface; added algorithmic test for DescriptorMatcher; added sample on matching to many images

This commit is contained in:
Maria Dimashova
2010-10-29 08:44:42 +00:00
parent 0d3809d0b1
commit 69e329c9fd
16 changed files with 1786 additions and 920 deletions
+5 -5
View File
@@ -948,7 +948,7 @@ void VocData::calcClassifierConfMatRow(const string& obj_class, const vector<Obd
/* prepare variables related to calculating recall if using the recall threshold */
int retrieved_hits = 0;
int total_relevant;
int total_relevant = 0;
if (cond == CV_VOC_CCOND_RECALL)
{
vector<char> ground_truth;
@@ -2200,7 +2200,7 @@ bool writeBowImageDescriptor( const string& file, const Mat& bowImageDescriptor
// Load in the bag of words vectors for a set of images, from file if possible
void calculateImageDescriptors( const vector<ObdImage>& images, vector<Mat>& imageDescriptors,
const Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
const string& resPath )
{
CV_Assert( !bowExtractor->getVocabulary().empty() );
@@ -2343,7 +2343,7 @@ void setSVMTrainAutoParams( CvParamGrid& c_grid, CvParamGrid& gamma_grid,
}
void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsExt, const string& objClassName, VocData& vocData,
const Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
const string& resPath )
{
/* first check if a previously trained svm for the current class has been saved to file */
@@ -2418,7 +2418,7 @@ void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsExt, cons
}
void computeConfidences( CvSVM& svm, const string& objClassName, VocData& vocData,
const Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
const string& resPath )
{
cout << "*** CALCULATING CONFIDENCES FOR CLASS " << objClassName << " ***" << endl;
@@ -2437,7 +2437,7 @@ void computeConfidences( CvSVM& svm, const string& objClassName, VocData& vocDat
// Use the bag of words vectors to calculate classifier output for each image in test set
cout << "CALCULATING CONFIDENCE SCORES FOR CLASS " << objClassName << "..." << endl;
vector<float> confidences( images.size() );
float signMul;
float signMul = 1.f;
for( size_t imageIdx = 0; imageIdx < images.size(); imageIdx++ )
{
if( imageIdx == 0 )
+2 -2
View File
@@ -72,7 +72,7 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
{
cout << "< Evaluate descriptor match..." << endl;
vector<Point2f> curve;
Ptr<GenericDescriptorMatch> gdm = new VectorDescriptorMatch( descriptorExtractor, descriptorMatcher );
Ptr<GenericDescriptorMatcher> gdm = new VectorDescriptorMatcher( descriptorExtractor, descriptorMatcher );
evaluateGenericDescriptorMatcher( img1, img2, H12, keypoints1, keypoints2, 0, 0, curve, gdm );
for( float l_p = 0; l_p < 1 - FLT_EPSILON; l_p+=0.1 )
cout << "1-precision = " << l_p << "; recall = " << getRecall( curve, l_p ) << endl;
@@ -81,7 +81,7 @@ void doIteration( const Mat& img1, Mat& img2, bool isWarpPerspective,
vector<int> trainIdxs( matches.size() );
for( size_t i = 0; i < matches.size(); i++ )
trainIdxs[i] = matches[i].indexTrain;
trainIdxs[i] = matches[i].trainIdx;
if( !isWarpPerspective && ransacReprojThreshold >= 0 )
{
+6 -9
View File
@@ -8,7 +8,7 @@
using namespace cv;
IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2,
const vector<KeyPoint>& features2, const vector<int>& desc_idx);
const vector<KeyPoint>& features2, const vector<DMatch>& desc_idx);
int main(int argc, char** argv)
{
@@ -24,7 +24,7 @@ int main(int argc, char** argv)
std::string alg_name = std::string(argv[3]);
std::string params_filename = std::string(argv[4]);
GenericDescriptorMatch *descriptorMatcher = createGenericDescriptorMatcher(alg_name, params_filename);
Ptr<GenericDescriptorMatcher> descriptorMatcher = createGenericDescriptorMatcher(alg_name, params_filename);
if( descriptorMatcher == 0 )
{
printf ("Cannot create descriptor\n");
@@ -50,10 +50,8 @@ int main(int argc, char** argv)
printf("Finding nearest neighbors... \n");
// find NN for each of keypoints2 in keypoints1
descriptorMatcher->add( img1, keypoints1 );
vector<int> matches2to1;
matches2to1.resize(keypoints2.size());
descriptorMatcher->match( img2, keypoints2, matches2to1 );
vector<DMatch> matches2to1;
descriptorMatcher->match( img2, keypoints2, img1, keypoints1, matches2to1 );
printf("Done\n");
IplImage* img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, matches2to1);
@@ -65,11 +63,10 @@ int main(int argc, char** argv)
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&img_corr);
delete descriptorMatcher;
}
IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2,
const vector<KeyPoint>& features2, const vector<int>& desc_idx)
const vector<KeyPoint>& features2, const vector<DMatch>& desc_idx)
{
IplImage* img_corr = cvCreateImage(cvSize(img1->width + img2->width, MAX(img1->height, img2->height)),
IPL_DEPTH_8U, 3);
@@ -88,7 +85,7 @@ IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1,
{
CvPoint pt = cvPoint(cvRound(features2[i].pt.x + img1->width), cvRound(features2[i].pt.y));
cvCircle(img_corr, pt, 3, CV_RGB(255, 0, 0));
cvLine(img_corr, features1[desc_idx[i]].pt, pt, CV_RGB(0, 255, 0));
cvLine(img_corr, features1[desc_idx[i].trainIdx].pt, pt, CV_RGB(0, 255, 0));
}
return img_corr;
+2 -3
View File
@@ -35,9 +35,8 @@ int main(int argc, char** argv)
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<int> matches;
matcher.add(descriptors2);
matcher.match(descriptors1, matches);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
namedWindow("matches", 1);
+134
View File
@@ -0,0 +1,134 @@
#include <highgui.h>
#include "opencv2/features2d/features2d.hpp"
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
const char dlmtr = '/';
void maskMatchesByTrainImgIdx( const vector<DMatch>& matches, int trainImgIdx, vector<char>& mask );
void readTrainFilenames( const string& filename, string& dirName, vector<string>& trainFilenames );
int main(int argc, char** argv)
{
Mat queryImg;
vector<KeyPoint> queryPoints;
Mat queryDescs;
vector<Mat> trainImgCollection;
vector<vector<KeyPoint> > trainPointCollection;
vector<Mat> trainDescCollection;
vector<DMatch> matches;
if( argc != 7 )
{
cout << "Format:" << endl;
cout << argv[0] << "[detectorType] [descriptorType] [matcherType] [queryImage] [fileWithTrainImages] [dirToSaveResImages]" << endl;
return -1;
}
cout << "< 1.) Creating feature detector, descriptor extractor and descriptor matcher ..." << endl;
Ptr<FeatureDetector> detector = createFeatureDetector( argv[1] );
Ptr<DescriptorExtractor> descriptorExtractor = createDescriptorExtractor( argv[2] );
Ptr<DescriptorMatcher> descriptorMatcher = createDescriptorMatcher( argv[3] );
cout << ">" << endl;
if( detector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty() )
{
cout << "Can not create feature detector or descriptor exstractor or descriptor matcher of given types." << endl << ">" << endl;
return -1;
}
cout << "< 2.) Reading the images..." << endl;
queryImg = imread( argv[4], CV_LOAD_IMAGE_GRAYSCALE);
if( queryImg.empty() )
{
cout << "Query image can not be read." << endl << ">" << endl;
return -1;
}
string trainDirName;
vector<string> trainFilenames;
vector<int> usedTrainImgIdxs;
readTrainFilenames( argv[5], trainDirName, trainFilenames );
if( trainFilenames.empty() )
{
cout << "Train image filenames can not be read." << endl << ">" << endl;
return -1;
}
for( size_t i = 0; i < trainFilenames.size(); i++ )
{
Mat img = imread( trainDirName + trainFilenames[i], CV_LOAD_IMAGE_GRAYSCALE );
if( img.empty() ) cout << "Train image " << trainDirName + trainFilenames[i] << " can not be read." << endl;
trainImgCollection.push_back( img );
usedTrainImgIdxs.push_back( i );
}
if( trainImgCollection.empty() )
{
cout << "All train images can not be read." << endl << ">" << endl;
return -1;
}
else
cout << trainImgCollection.size() << " train images were read." << endl;
cout << ">" << endl;
cout << endl << "< 3.) Extracting keypoints from images..." << endl;
detector->detect( queryImg, queryPoints );
detector->detect( trainImgCollection, trainPointCollection );
cout << ">" << endl;
cout << "< 4.) Computing descriptors for keypoints..." << endl;
descriptorExtractor->compute( queryImg, queryPoints, queryDescs );
descriptorExtractor->compute( trainImgCollection, trainPointCollection, trainDescCollection );
cout << ">" << endl;
cout << "< 5.) Set train descriptors collection in the matcher and match query descriptors to them..." << endl;
descriptorMatcher->add( trainDescCollection );
descriptorMatcher->match( queryDescs, matches );
CV_Assert( queryPoints.size() == matches.size() );
cout << ">" << endl;
Mat drawImg;
vector<char> mask;
for( size_t i = 0; i < trainImgCollection.size(); i++ )
{
maskMatchesByTrainImgIdx( matches, i, mask );
drawMatches( queryImg, queryPoints, trainImgCollection[i], trainPointCollection[i],
matches, drawImg, Scalar::all(-1), Scalar::all(-1), mask );
imwrite( string(argv[6]) + "/res_" + trainFilenames[usedTrainImgIdxs[i]] + ".png", drawImg );
}
return 0;
}
void maskMatchesByTrainImgIdx( const vector<DMatch>& matches, int trainImgIdx, vector<char>& mask )
{
mask.resize( matches.size() );
fill( mask.begin(), mask.end(), 0 );
for( size_t i = 0; i < matches.size(); i++ )
{
if( matches[i].imgIdx == trainImgIdx )
mask[i] = 1;
}
}
void readTrainFilenames( const string& filename, string& dirName, vector<string>& trainFilenames )
{
trainFilenames.clear();
ifstream file( filename.c_str() );
if ( !file.is_open() )
return;
size_t pos = filename.rfind(dlmtr);
dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr;
while( !file.eof() )
{
string str; getline( file, str );
if( str.empty() ) break;
trainFilenames.push_back(str);
}
file.close();
}