Commit 673b4404 authored by Ilya Lysenkov's avatar Ilya Lysenkov

Fixed plot data generation for descriptors comparison

parent 400eb371
...@@ -1516,7 +1516,8 @@ struct CV_EXPORTS L2 ...@@ -1516,7 +1516,8 @@ struct CV_EXPORTS L2
*/ */
struct DMatch struct DMatch
{ {
int index; int indexTrain;
int indexQuery;
float distance; float distance;
//less is better //less is better
...@@ -1712,7 +1713,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat ...@@ -1712,7 +1713,7 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
matches.resize( matchings.size() ); matches.resize( matchings.size() );
for( size_t i=0;i<matchings.size();i++) for( size_t i=0;i<matchings.size();i++)
{ {
matches[i] = matchings[i].index; matches[i] = matchings[i].indexTrain;
} }
} }
...@@ -1754,10 +1755,11 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat ...@@ -1754,10 +1755,11 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
if( matchIndex != -1 ) if( matchIndex != -1 )
{ {
DMatch matching; DMatch match;
matching.index = matchIndex; match.indexTrain = matchIndex;
matching.distance = matchDistance; match.indexQuery = i;
matches[i] = matching; match.distance = matchDistance;
matches[i] = match;
} }
} }
} }
...@@ -1830,8 +1832,8 @@ public: ...@@ -1830,8 +1832,8 @@ public:
// Matches test keypoints to the training set // Matches test keypoints to the training set
// image The source image // image The source image
// points Test keypoints from the source image // points Test keypoints from the source image
// matchings A vector to be filled with keypoint matchings // matches A vector to be filled with keypoint matches
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matchings ) {}; virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches ) {};
// Clears keypoints storing in collection // Clears keypoints storing in collection
virtual void clear(); virtual void clear();
...@@ -1907,7 +1909,7 @@ public: ...@@ -1907,7 +1909,7 @@ public:
// loaded with DescriptorOneWay::Initialize, kd tree is used for finding minimum distances. // loaded with DescriptorOneWay::Initialize, kd tree is used for finding minimum distances.
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<int>& indices ); virtual void match( const Mat& image, vector<KeyPoint>& points, vector<int>& indices );
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matchings ); virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches );
// 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 );
...@@ -2037,7 +2039,7 @@ public: ...@@ -2037,7 +2039,7 @@ public:
virtual void match( const Mat& image, vector<KeyPoint>& keypoints, vector<int>& indices ); virtual void match( const Mat& image, vector<KeyPoint>& keypoints, vector<int>& indices );
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matchings ); virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches );
virtual void classify( const Mat& image, vector<KeyPoint>& keypoints ); virtual void classify( const Mat& image, vector<KeyPoint>& keypoints );
...@@ -2095,12 +2097,12 @@ public: ...@@ -2095,12 +2097,12 @@ public:
matcher.match( descriptors, keypointIndices ); matcher.match( descriptors, keypointIndices );
}; };
virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matchings ) virtual void match( const Mat& image, vector<KeyPoint>& points, vector<DMatch>& matches )
{ {
Mat descriptors; Mat descriptors;
extractor.compute( image, points, descriptors ); extractor.compute( image, points, descriptors );
matcher.match( descriptors, matchings ); matcher.match( descriptors, matches );
} }
virtual void clear() virtual void clear()
......
...@@ -372,6 +372,8 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const ...@@ -372,6 +372,8 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const
if( !size || overlaps.nzcount() == 0 ) if( !size || overlaps.nzcount() == 0 )
return; return;
if( ifEvaluateDetectors )
{
// threshold the overlaps // threshold the overlaps
for( int y = 0; y < size[0]; y++ ) for( int y = 0; y < size[0]; y++ )
{ {
...@@ -381,8 +383,7 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const ...@@ -381,8 +383,7 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const
overlaps.erase(y,x); overlaps.erase(y,x);
} }
} }
if( ifEvaluateDetectors )
{
// regions one-to-one matching // regions one-to-one matching
correspondencesCount = 0; correspondencesCount = 0;
while( overlaps.nzcount() > 0 ) while( overlaps.nzcount() > 0 )
...@@ -400,7 +401,16 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const ...@@ -400,7 +401,16 @@ void calculateRepeatability( const vector<EllipticKeyPoint>& _keypoints1, const
} }
else else
{ {
overlaps.copyTo(*thresholdedOverlapMask); thresholdedOverlapMask->create( 2, size );
for( int y = 0; y < size[0]; y++ )
{
for( int x = 0; x < size[1]; x++ )
{
float val = overlaps(y,x);
if ( val >= overlapThreshold )
thresholdedOverlapMask->ref(y,x) = val;
}
}
} }
} }
...@@ -424,10 +434,23 @@ inline float precision( int correctMatchCount, int falseMatchCount ) ...@@ -424,10 +434,23 @@ inline float precision( int correctMatchCount, int falseMatchCount )
return correctMatchCount + falseMatchCount ? (float)correctMatchCount / (float)(correctMatchCount + falseMatchCount) : -1; return correctMatchCount + falseMatchCount ? (float)correctMatchCount / (float)(correctMatchCount + falseMatchCount) : -1;
} }
struct DMatchForEvaluation
{
DMatch match;
int isCorrect;
bool operator<( const DMatchForEvaluation &m) const
{
return match < m.match;
}
};
void evaluateDescriptors( const vector<EllipticKeyPoint>& keypoints1, const vector<EllipticKeyPoint>& keypoints2, void evaluateDescriptors( const vector<EllipticKeyPoint>& keypoints1, const vector<EllipticKeyPoint>& keypoints2,
vector< pair<DMatch, int> >& matches1to2, vector<DMatchForEvaluation>& matches1to2,
const Mat& img1, const Mat& img2, const Mat& H1to2, const Mat& img1, const Mat& img2, const Mat& H1to2,
int &correctMatchCount, int &falseMatchCount, vector<int> &matchStatuses, int& correspondenceCount ) int &correctMatchCount, int &falseMatchCount, int& correspondenceCount )
{ {
assert( !keypoints1.empty() && !keypoints2.empty() && !matches1to2.empty() ); assert( !keypoints1.empty() && !keypoints2.empty() && !matches1to2.empty() );
assert( keypoints1.size() == matches1to2.size() ); assert( keypoints1.size() == matches1to2.size() );
...@@ -441,26 +464,23 @@ void evaluateDescriptors( const vector<EllipticKeyPoint>& keypoints1, const vect ...@@ -441,26 +464,23 @@ void evaluateDescriptors( const vector<EllipticKeyPoint>& keypoints1, const vect
&thresholdedOverlapMask ); &thresholdedOverlapMask );
correspondenceCount = thresholdedOverlapMask.nzcount(); correspondenceCount = thresholdedOverlapMask.nzcount();
matchStatuses.resize( matches1to2.size() );
correctMatchCount = 0; correctMatchCount = 0;
falseMatchCount = 0; falseMatchCount = 0;
//the nearest descriptors should be examined first for( size_t i = 0; i < matches1to2.size(); i++ )
std::sort( matches1to2.begin(), matches1to2.end() );
for( size_t i1 = 0; i1 < matches1to2.size(); i1++ )
{ {
int i2 = matches1to2[i1].first.index; if( matches1to2[i].match.indexTrain > 0 )
if( i2 > 0 )
{ {
matchStatuses[i2] = thresholdedOverlapMask(matches1to2[i1].second, i2); matches1to2[i].isCorrect = thresholdedOverlapMask( matches1to2[i].match.indexQuery, matches1to2[i].match.indexTrain);
if( matchStatuses[i2] ) if( matches1to2[i].isCorrect )
correctMatchCount++; correctMatchCount++;
else else
falseMatchCount++; falseMatchCount++;
} }
else else
matchStatuses[i2] = -1; {
matches1to2[i].isCorrect = -1;
}
} }
} }
...@@ -1408,9 +1428,8 @@ void DescriptorQualityTest::runDatasetTest (const vector<Mat> &imgs, const vecto ...@@ -1408,9 +1428,8 @@ void DescriptorQualityTest::runDatasetTest (const vector<Mat> &imgs, const vecto
transformToEllipticKeyPoints( keypoints1, ekeypoints1 ); transformToEllipticKeyPoints( keypoints1, ekeypoints1 );
int progressCount = DATASETS_COUNT*TEST_CASE_COUNT; int progressCount = DATASETS_COUNT*TEST_CASE_COUNT;
vector< pair<DMatch, int> > allMatchings; vector<DMatchForEvaluation> allMatches;
vector<int> allMatchStatuses;
size_t matchingIndex = 0;
int allCorrespCount = 0; int allCorrespCount = 0;
for( int ci = 0; ci < TEST_CASE_COUNT; ci++ ) for( int ci = 0; ci < TEST_CASE_COUNT; ci++ )
{ {
...@@ -1428,43 +1447,38 @@ void DescriptorQualityTest::runDatasetTest (const vector<Mat> &imgs, const vecto ...@@ -1428,43 +1447,38 @@ void DescriptorQualityTest::runDatasetTest (const vector<Mat> &imgs, const vecto
readKeypoints( keypontsFS, keypoints2, ci+1 ); readKeypoints( keypontsFS, keypoints2, ci+1 );
transformToEllipticKeyPoints( keypoints2, ekeypoints2 ); transformToEllipticKeyPoints( keypoints2, ekeypoints2 );
descMatch->add( imgs[ci+1], keypoints2 ); descMatch->add( imgs[ci+1], keypoints2 );
vector<DMatch> matchings1to2; vector<DMatch> matches1to2;
descMatch->match( imgs[0], keypoints1, matchings1to2 ); descMatch->match( imgs[0], keypoints1, matches1to2 );
vector< pair<DMatch, int> > matchings (matchings1to2.size()); vector<DMatchForEvaluation> matches ( matches1to2.size() );
for( size_t i=0;i<matchings1to2.size();i++ ) for( size_t i=0;i<matches1to2.size();i++)
matchings[i] = pair<DMatch, int>( matchings1to2[i], i); {
matches[i].match = matches1to2[i];
}
// TODO if( commRunParams[di].matchFilter ) // TODO if( commRunParams[di].matchFilter )
int correspCount; int correspCount;
int correctMatchCount = 0, falseMatchCount = 0; int correctMatchCount = 0, falseMatchCount = 0;
vector<int> matchStatuses; evaluateDescriptors( ekeypoints1, ekeypoints2, matches, imgs[0], imgs[ci+1], Hs[ci],
evaluateDescriptors( ekeypoints1, ekeypoints2, matchings, imgs[0], imgs[ci+1], Hs[ci], correctMatchCount, falseMatchCount, correspCount );
correctMatchCount, falseMatchCount, matchStatuses, correspCount );
for( size_t i=0;i<matchings.size();i++ )
matchings[i].second += matchingIndex;
matchingIndex += matchings.size();
allCorrespCount += correspCount; allCorrespCount += correspCount;
std::copy( matches.begin(), matches.end(), std::back_inserter( allMatches ) );
//TODO: use merge //TODO: remove after testing
std::copy( matchings.begin(), matchings.end(), std::back_inserter( allMatchings ) ); //printf ("%d %d %d \n", correctMatchCount, falseMatchCount, correspCount );
std::copy( matchStatuses.begin(), matchStatuses.end(), std::back_inserter( allMatchStatuses ) );
printf ("%d %d %d \n", 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 (); descMatch->clear ();
} }
std::sort( allMatchings.begin(), allMatchings.end() ); std::sort( allMatches.begin(), allMatches.end() );
calcDatasetQuality[di].resize( allMatchings.size() ); calcDatasetQuality[di].resize( allMatches.size() );
int correctMatchCount = 0, falseMatchCount = 0; int correctMatchCount = 0, falseMatchCount = 0;
for( size_t i=0;i<allMatchings.size();i++) for( size_t i=0;i<allMatches.size();i++)
{ {
if( allMatchStatuses[ allMatchings[i].second ] ) if( allMatches[i].isCorrect )
correctMatchCount++; correctMatchCount++;
else else
falseMatchCount++; falseMatchCount++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment