Speeded up descriptors evaluations using clear ()

This commit is contained in:
Ilya Lysenkov 2010-06-02 06:55:03 +00:00
parent 8e526dc58a
commit bb235220e7
4 changed files with 73 additions and 32 deletions

View File

@ -1024,13 +1024,14 @@ public:
const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1, const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
int pca_dim_high = 100, int pca_dim_low = 100); int pca_dim_high = 100, int pca_dim_low = 100);
OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, const string &train_path = string(), const string &images_list = string(), OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, const string &train_path = string(), const string &images_list = string(),
int pyr_levels = 1, float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1,
int pca_dim_high = 100, int pca_dim_low = 100); int pca_dim_high = 100, int pca_dim_low = 100);
virtual ~OneWayDescriptorBase(); virtual ~OneWayDescriptorBase();
void clear ();
// Allocate: allocates memory for a given number of descriptors // Allocate: allocates memory for a given number of descriptors
void Allocate(int train_feature_count); void Allocate(int train_feature_count);
@ -1124,7 +1125,7 @@ public:
// GeneratePCA: calculate and save PCA components and descriptors // GeneratePCA: calculate and save PCA components and descriptors
// - img_path: path to training PCA images directory // - img_path: path to training PCA images directory
// - images_list: filename with filenames of training PCA images // - images_list: filename with filenames of training PCA images
void GeneratePCA(const char* img_path, const char* images_list); void GeneratePCA(const char* img_path, const char* images_list, int pose_count=500);
// SetPCAHigh: sets the high resolution pca matrices (copied to internal structures) // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
void SetPCAHigh(CvMat* avg, CvMat* eigenvectors); void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
@ -1168,6 +1169,9 @@ protected:
int m_pca_dim_low; int m_pca_dim_low;
int m_pyr_levels; int m_pyr_levels;
const float scale_min;
const float scale_max;
const float scale_step;
}; };
class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
@ -1184,9 +1188,9 @@ public:
OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config, OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1); const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename, OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
const string &train_path = string (), const string &images_list = string (), int pyr_levels = 1); const string &train_path = string (), const string &images_list = string (),
float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1);
virtual ~OneWayDescriptorObject(); virtual ~OneWayDescriptorObject();
@ -1705,9 +1709,9 @@ public:
static const int POSE_COUNT = 500; static const int POSE_COUNT = 500;
static const int PATCH_WIDTH = 24; static const int PATCH_WIDTH = 24;
static const int PATCH_HEIGHT = 24; static const int PATCH_HEIGHT = 24;
static float GET_MIN_SCALE() { return 1.f; } static float GET_MIN_SCALE() { return 0.7f; }
static float GET_MAX_SCALE() { return 3.f; } static float GET_MAX_SCALE() { return 1.5f; }
static float GET_STEP_SCALE() { return 1.15f; } static float GET_STEP_SCALE() { return 1.2f; }
Params( int _poseCount = POSE_COUNT, Params( int _poseCount = POSE_COUNT,
Size _patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT), Size _patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
@ -1755,6 +1759,8 @@ public:
// Classify a set of keypoints. The same as match, but returns point classes rather than indices // Classify a set of keypoints. The same as match, but returns point classes rather than indices
virtual void classify( const Mat& image, vector<KeyPoint>& points ); virtual void classify( const Mat& image, vector<KeyPoint>& points );
virtual void clear ();
protected: protected:
Ptr<OneWayDescriptorBase> base; Ptr<OneWayDescriptorBase> base;
Params params; Params params;

View File

@ -204,7 +204,7 @@ void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
{ {
if( base.empty() ) if( base.empty() )
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename, base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
params.trainPath, params.trainImagesList); params.trainPath, params.trainImagesList, params.minScale, params.maxScale, params.stepScale);
size_t trainFeatureCount = keypoints.size(); size_t trainFeatureCount = keypoints.size();
@ -225,7 +225,7 @@ void OneWayDescriptorMatch::add( KeyPointCollection& keypoints )
{ {
if( base.empty() ) if( base.empty() )
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename, base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
params.trainPath, params.trainImagesList); params.trainPath, params.trainImagesList, params.minScale, params.maxScale, params.stepScale);
size_t trainFeatureCount = keypoints.calcKeypointCount(); size_t trainFeatureCount = keypoints.calcKeypointCount();
@ -275,6 +275,12 @@ void OneWayDescriptorMatch::classify( const Mat& image, vector<KeyPoint>& points
} }
} }
void OneWayDescriptorMatch::clear ()
{
GenericDescriptorMatch::clear();
base->clear ();
}
/****************************************************************************************\ /****************************************************************************************\
* CalonderDescriptorMatch * * CalonderDescriptorMatch *
\****************************************************************************************/ \****************************************************************************************/

View File

@ -1213,7 +1213,8 @@ namespace cv{
OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path, OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path,
const char* pca_config, const char* pca_hr_config, const char* pca_config, const char* pca_hr_config,
const char* pca_desc_config, int pyr_levels, const char* pca_desc_config, int pyr_levels,
int pca_dim_high, int pca_dim_low) : m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low) int pca_dim_high, int pca_dim_low)
: m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low), scale_min (0.7f), scale_max(1.5f), scale_step (1.2f)
{ {
// m_pca_descriptors_matrix = 0; // m_pca_descriptors_matrix = 0;
m_patch_size = patch_size; m_patch_size = patch_size;
@ -1270,8 +1271,10 @@ namespace cv{
} }
OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename,
const string &train_path, const string &images_list, int pyr_levels, const string &train_path, const string &images_list, float _scale_min, float _scale_max,
int pca_dim_high, int pca_dim_low) : m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low) float _scale_step, int pyr_levels,
int pca_dim_high, int pca_dim_low)
: m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low), scale_min(_scale_min), scale_max(_scale_max), scale_step(_scale_step)
{ {
// m_pca_descriptors_matrix = 0; // m_pca_descriptors_matrix = 0;
m_patch_size = patch_size; m_patch_size = patch_size;
@ -1341,6 +1344,20 @@ namespace cv{
#endif #endif
} }
void OneWayDescriptorBase::clear(){
delete []m_descriptors;
m_descriptors = 0;
#if defined(_KDTREE)
// if (m_pca_descriptors_matrix)
// delete m_pca_descriptors_matrix;
cvReleaseMat(&m_pca_descriptors_matrix);
m_pca_descriptors_matrix = 0;
delete m_pca_descriptors_tree;
m_pca_descriptors_tree = 0;
#endif
}
void OneWayDescriptorBase::InitializePoses() void OneWayDescriptorBase::InitializePoses()
{ {
m_poses = new CvAffinePose[m_pose_count]; m_poses = new CvAffinePose[m_pose_count];
@ -1423,25 +1440,25 @@ namespace cv{
#if 0 #if 0
::FindOneWayDescriptor(m_train_feature_count, m_descriptors, patch, desc_idx, pose_idx, distance, m_pca_avg, m_pca_eigenvectors); ::FindOneWayDescriptor(m_train_feature_count, m_descriptors, patch, desc_idx, pose_idx, distance, m_pca_avg, m_pca_eigenvectors);
#else #else
float scale_min = 0.7f; float min = scale_min;
float scale_max = 2.0f; float max = scale_max;
float scale_step = 1.2f; float step = scale_step;
if (scale_ranges) if (scale_ranges)
{ {
scale_min = scale_ranges[0]; min = scale_ranges[0];
scale_max = scale_ranges[1]; max = scale_ranges[1];
} }
float scale = 1.0f; float scale = 1.0f;
#if !defined(_KDTREE) #if !defined(_KDTREE)
cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch, cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch,
scale_min, scale_max, scale_step, desc_idx, pose_idx, distance, scale, min, max, step, desc_idx, pose_idx, distance, scale,
m_pca_avg, m_pca_eigenvectors); m_pca_avg, m_pca_eigenvectors);
#else #else
cv::FindOneWayDescriptorEx(m_pca_descriptors_tree, m_descriptors[0].GetPatchSize(), m_descriptors[0].GetPCADimLow(), m_pose_count, patch, cv::FindOneWayDescriptorEx(m_pca_descriptors_tree, m_descriptors[0].GetPatchSize(), m_descriptors[0].GetPCADimLow(), m_pose_count, patch,
scale_min, scale_max, scale_step, desc_idx, pose_idx, distance, scale, min, max, step, desc_idx, pose_idx, distance, scale,
m_pca_avg, m_pca_eigenvectors); m_pca_avg, m_pca_eigenvectors);
#endif #endif
@ -1454,14 +1471,14 @@ namespace cv{
void OneWayDescriptorBase::FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs, void OneWayDescriptorBase::FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges) const std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges) const
{ {
float scale_min = 0.7f; float min = scale_min;
float scale_max = 2.5f; float max = scale_max;
float scale_step = 1.2f; float step = scale_step;
if (scale_ranges) if (scale_ranges)
{ {
scale_min = scale_ranges[0]; min = scale_ranges[0];
scale_max = scale_ranges[1]; max = scale_ranges[1];
} }
distances.resize(n); distances.resize(n);
@ -1471,7 +1488,7 @@ namespace cv{
/*float scales = 1.0f;*/ /*float scales = 1.0f;*/
cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch, cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch,
scale_min, scale_max, scale_step ,n, desc_idxs, pose_idxs, distances, _scales, min, max, step ,n, desc_idxs, pose_idxs, distances, _scales,
m_pca_avg, m_pca_eigenvectors); m_pca_avg, m_pca_eigenvectors);
} }
@ -1719,7 +1736,7 @@ namespace cv{
calcPCAFeatures(patches, fs, postfix, avg, eigenvectors); calcPCAFeatures(patches, fs, postfix, avg, eigenvectors);
} }
void OneWayDescriptorBase::GeneratePCA(const char* img_path, const char* images_list) void OneWayDescriptorBase::GeneratePCA(const char* img_path, const char* images_list, int pose_count)
{ {
char pca_filename[1024]; char pca_filename[1024];
sprintf(pca_filename, "%s/%s", img_path, GetPCAFilename().c_str()); sprintf(pca_filename, "%s/%s", img_path, GetPCAFilename().c_str());
@ -1729,7 +1746,6 @@ namespace cv{
generatePCAFeatures(img_path, images_list, fs, "lr", cvSize(m_patch_size.width / 2, m_patch_size.height / 2), generatePCAFeatures(img_path, images_list, fs, "lr", cvSize(m_patch_size.width / 2, m_patch_size.height / 2),
&m_pca_avg, &m_pca_eigenvectors); &m_pca_avg, &m_pca_eigenvectors);
const int pose_count = 500;
OneWayDescriptorBase descriptors(m_patch_size, pose_count); OneWayDescriptorBase descriptors(m_patch_size, pose_count);
descriptors.SetPCAHigh(m_pca_hr_avg, m_pca_hr_eigenvectors); descriptors.SetPCAHigh(m_pca_hr_avg, m_pca_hr_eigenvectors);
descriptors.SetPCALow(m_pca_avg, m_pca_eigenvectors); descriptors.SetPCALow(m_pca_avg, m_pca_eigenvectors);
@ -1926,13 +1942,12 @@ namespace cv{
} }
OneWayDescriptorObject::OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename, OneWayDescriptorObject::OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
const string &train_path, const string &images_list, int pyr_levels) : const string &train_path, const string &images_list, float _scale_min, float _scale_max, float _scale_step, int pyr_levels) :
OneWayDescriptorBase(patch_size, pose_count, pca_filename, train_path, images_list, pyr_levels) OneWayDescriptorBase(patch_size, pose_count, pca_filename, train_path, images_list, _scale_min, _scale_max, _scale_step, pyr_levels)
{ {
m_part_id = 0; m_part_id = 0;
} }
OneWayDescriptorObject::~OneWayDescriptorObject() OneWayDescriptorObject::~OneWayDescriptorObject()
{ {
delete []m_part_id; delete []m_part_id;

View File

@ -1461,6 +1461,7 @@ const string PRECISION = "precision";
const string KEYPOINTS_FILENAME = "keypointsFilename"; const string KEYPOINTS_FILENAME = "keypointsFilename";
const string PROJECT_KEYPOINTS_FROM_1IMAGE = "projectKeypointsFrom1Image"; const string PROJECT_KEYPOINTS_FROM_1IMAGE = "projectKeypointsFrom1Image";
const string MATCH_FILTER = "matchFilter"; const string MATCH_FILTER = "matchFilter";
const string RUN_PARAMS_IS_IDENTICAL = "runParamsIsIdentical";
const string ONE_WAY_TRAIN_DIR = "detectors_descriptors_evaluation/one_way_train_images/"; const string ONE_WAY_TRAIN_DIR = "detectors_descriptors_evaluation/one_way_train_images/";
const string ONE_WAY_IMAGES_LIST = "one_way_train_images.txt"; const string ONE_WAY_IMAGES_LIST = "one_way_train_images.txt";
@ -1514,6 +1515,7 @@ protected:
string keypontsFilename; string keypontsFilename;
bool projectKeypointsFrom1Image; bool projectKeypointsFrom1Image;
int matchFilter; // not used now int matchFilter; // not used now
bool runParamsIsIdentical;
}; };
vector<CommonRunParams> commRunParams; vector<CommonRunParams> commRunParams;
}; };
@ -1565,6 +1567,7 @@ void DescriptorQualityTest::readDatasetRunParams( FileNode& fn, int datasetIdx )
commRunParams[datasetIdx].keypontsFilename = (string)fn[KEYPOINTS_FILENAME]; commRunParams[datasetIdx].keypontsFilename = (string)fn[KEYPOINTS_FILENAME];
commRunParams[datasetIdx].projectKeypointsFrom1Image = (int)fn[PROJECT_KEYPOINTS_FROM_1IMAGE] != 0; commRunParams[datasetIdx].projectKeypointsFrom1Image = (int)fn[PROJECT_KEYPOINTS_FROM_1IMAGE] != 0;
commRunParams[datasetIdx].matchFilter = (int)fn[MATCH_FILTER]; commRunParams[datasetIdx].matchFilter = (int)fn[MATCH_FILTER];
commRunParams[datasetIdx].runParamsIsIdentical = (int)fn[RUN_PARAMS_IS_IDENTICAL];
} }
void DescriptorQualityTest::writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const void DescriptorQualityTest::writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const
@ -1572,6 +1575,7 @@ void DescriptorQualityTest::writeDatasetRunParams( FileStorage& fs, int datasetI
fs << KEYPOINTS_FILENAME << commRunParams[datasetIdx].keypontsFilename; fs << KEYPOINTS_FILENAME << commRunParams[datasetIdx].keypontsFilename;
fs << PROJECT_KEYPOINTS_FROM_1IMAGE << commRunParams[datasetIdx].projectKeypointsFrom1Image; fs << PROJECT_KEYPOINTS_FROM_1IMAGE << commRunParams[datasetIdx].projectKeypointsFrom1Image;
fs << MATCH_FILTER << commRunParams[datasetIdx].matchFilter; fs << MATCH_FILTER << commRunParams[datasetIdx].matchFilter;
fs << RUN_PARAMS_IS_IDENTICAL << commRunParams[datasetIdx].runParamsIsIdentical;
} }
void DescriptorQualityTest::setDefaultDatasetRunParams( int datasetIdx ) void DescriptorQualityTest::setDefaultDatasetRunParams( int datasetIdx )
@ -1579,6 +1583,7 @@ void DescriptorQualityTest::setDefaultDatasetRunParams( int datasetIdx )
commRunParams[datasetIdx].keypontsFilename = "surf_" + DATASET_NAMES[datasetIdx] + ".xml.gz"; commRunParams[datasetIdx].keypontsFilename = "surf_" + DATASET_NAMES[datasetIdx] + ".xml.gz";
commRunParams[datasetIdx].projectKeypointsFrom1Image = true; commRunParams[datasetIdx].projectKeypointsFrom1Image = true;
commRunParams[datasetIdx].matchFilter = NO_MATCH_FILTER; commRunParams[datasetIdx].matchFilter = NO_MATCH_FILTER;
commRunParams[datasetIdx].runParamsIsIdentical = true;
} }
void DescriptorQualityTest::run( int ) void DescriptorQualityTest::run( int )
@ -1586,6 +1591,8 @@ void DescriptorQualityTest::run( int )
readAllDatasetsRunParams(); readAllDatasetsRunParams();
readResults(); readResults();
Ptr<GenericDescriptorMatch> descMatch;
int notReadDatasets = 0; int notReadDatasets = 0;
int progress = 0, progressCount = DATASETS_COUNT*TEST_CASE_COUNT; int progress = 0, progressCount = DATASETS_COUNT*TEST_CASE_COUNT;
for(int di = 0; di < DATASETS_COUNT; di++ ) for(int di = 0; di < DATASETS_COUNT; di++ )
@ -1608,6 +1615,12 @@ void DescriptorQualityTest::run( int )
vector<KeyPoint> keypoints1; vector<EllipticKeyPoint> ekeypoints1; vector<KeyPoint> keypoints1; vector<EllipticKeyPoint> ekeypoints1;
readKeypoints( keypontsFS, keypoints1, 0); readKeypoints( keypontsFS, keypoints1, 0);
transformToEllipticKeyPoints( keypoints1, ekeypoints1 ); transformToEllipticKeyPoints( keypoints1, ekeypoints1 );
if (!commRunParams[di].runParamsIsIdentical)
{
descMatch = createDescriptorMatch (di);
}
for( int ci = 0; ci < TEST_CASE_COUNT; ci++ ) for( int ci = 0; ci < TEST_CASE_COUNT; ci++ )
{ {
progress = update_progress( progress, di*TEST_CASE_COUNT + ci, progressCount, 0 ); progress = update_progress( progress, di*TEST_CASE_COUNT + ci, progressCount, 0 );
@ -1624,7 +1637,6 @@ void DescriptorQualityTest::run( int )
readKeypoints( keypontsFS, keypoints2, ci+1 ); readKeypoints( keypontsFS, keypoints2, ci+1 );
transformToEllipticKeyPoints( keypoints2, ekeypoints2 ); transformToEllipticKeyPoints( keypoints2, ekeypoints2 );
Ptr<GenericDescriptorMatch> descMatch = createDescriptorMatch(di);
descMatch->add( imgs[ci+1], keypoints2 ); descMatch->add( imgs[ci+1], keypoints2 );
vector<int> matches1to2; vector<int> matches1to2;
descMatch->match( imgs[0], keypoints1, matches1to2 ); descMatch->match( imgs[0], keypoints1, matches1to2 );
@ -1635,6 +1647,8 @@ void DescriptorQualityTest::run( int )
correctMatchCount, falseMatchCount, correspCount ); correctMatchCount, falseMatchCount, correspCount );
calcQuality[di][ci].recall = recall( correctMatchCount, correspCount ); calcQuality[di][ci].recall = recall( correctMatchCount, correspCount );
calcQuality[di][ci].precision = precision( correctMatchCount, falseMatchCount ); calcQuality[di][ci].precision = precision( correctMatchCount, falseMatchCount );
descMatch->clear ();
} }
} }
} }