Commit cd81db88 authored by Maria Dimashova's avatar Maria Dimashova

updated sift wrapper (recalculation angles mode)

parent ccbe4053
...@@ -224,25 +224,26 @@ public: ...@@ -224,25 +224,26 @@ public:
static const int DEFAULT_NOCTAVES = 4; static const int DEFAULT_NOCTAVES = 4;
static const int DEFAULT_NOCTAVE_LAYERS = 3; static const int DEFAULT_NOCTAVE_LAYERS = 3;
static const int DEFAULT_FIRST_OCTAVE = -1; static const int DEFAULT_FIRST_OCTAVE = -1;
enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
CommonParams() : nOctaves(DEFAULT_NOCTAVES), nOctaveLayers(DEFAULT_NOCTAVE_LAYERS), CommonParams() : nOctaves(DEFAULT_NOCTAVES), nOctaveLayers(DEFAULT_NOCTAVE_LAYERS),
firstOctave(DEFAULT_FIRST_OCTAVE) {} firstOctave(DEFAULT_FIRST_OCTAVE), angleMode(FIRST_ANGLE) {}
CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave ) : CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave, int _angleMode ) :
nOctaves(_nOctaves), nOctaveLayers(_nOctaveLayers), nOctaves(_nOctaves), nOctaveLayers(_nOctaveLayers),
firstOctave(_firstOctave) {} firstOctave(_firstOctave), angleMode(_angleMode) {}
int nOctaves, nOctaveLayers, firstOctave; int nOctaves, nOctaveLayers, firstOctave;
int angleMode;
}; };
struct DetectorParams struct DetectorParams
{ {
static double GET_DEFAULT_THRESHOLD() { return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; } static double GET_DEFAULT_THRESHOLD() { return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; } static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
DetectorParams() : threshold(GET_DEFAULT_THRESHOLD()), edgeThreshold(GET_DEFAULT_EDGE_THRESHOLD()), DetectorParams() : threshold(GET_DEFAULT_THRESHOLD()), edgeThreshold(GET_DEFAULT_EDGE_THRESHOLD()) {}
angleMode(FIRST_ANGLE) {} DetectorParams( double _threshold, double _edgeThreshold ) :
DetectorParams( double _threshold, double _edgeThreshold, int _angleMode ) : threshold(_threshold), edgeThreshold(_edgeThreshold) {}
threshold(_threshold), edgeThreshold(_edgeThreshold), angleMode(_angleMode) {}
double threshold, edgeThreshold; double threshold, edgeThreshold;
int angleMode;
}; };
struct DescriptorParams struct DescriptorParams
...@@ -250,24 +251,30 @@ public: ...@@ -250,24 +251,30 @@ public:
static double GET_DEFAULT_MAGNIFICATION() { return 3.0; } static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
static const bool DEFAULT_IS_NORMALIZE = true; static const bool DEFAULT_IS_NORMALIZE = true;
static const int DESCRIPTOR_SIZE = 128; static const int DESCRIPTOR_SIZE = 128;
DescriptorParams() : magnification(GET_DEFAULT_MAGNIFICATION()), isNormalize(DEFAULT_IS_NORMALIZE) {} DescriptorParams() : magnification(GET_DEFAULT_MAGNIFICATION()), isNormalize(DEFAULT_IS_NORMALIZE),
DescriptorParams( double _magnification, bool _isNormalize ) : recalculateAngles(true) {}
magnification(_magnification), isNormalize(_isNormalize) {} DescriptorParams( double _magnification, bool _isNormalize, bool _recalculateAngles ) :
magnification(_magnification), isNormalize(_isNormalize),
recalculateAngles(_recalculateAngles) {}
double magnification; double magnification;
bool isNormalize; bool isNormalize;
bool recalculateAngles;
}; };
SIFT(); SIFT();
// sift-detector constructor // sift-detector constructor
SIFT( double _threshold, double _edgeThreshold, int _angleMode=DetectorParams::FIRST_ANGLE, SIFT( double _threshold, double _edgeThreshold,
int _nOctaves=CommonParams::DEFAULT_NOCTAVES, int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS, int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE ); int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
int _angleMode=CommonParams::FIRST_ANGLE );
// sift-descriptor constructor // sift-descriptor constructor
SIFT( double _magnification, bool _isNormalize=true, SIFT( double _magnification, bool _isNormalize=true,
bool _recalculateAngles = true,
int _nOctaves=CommonParams::DEFAULT_NOCTAVES, int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS, int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE ); int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
int _angleMode=CommonParams::FIRST_ANGLE );
SIFT( const CommonParams& _commParams, SIFT( const CommonParams& _commParams,
const DetectorParams& _detectorParams = DetectorParams(), const DetectorParams& _detectorParams = DetectorParams(),
const DescriptorParams& _descriptorParams = DescriptorParams() ); const DescriptorParams& _descriptorParams = DescriptorParams() );
...@@ -1231,10 +1238,10 @@ class CV_EXPORTS SiftFeatureDetector : public FeatureDetector ...@@ -1231,10 +1238,10 @@ class CV_EXPORTS SiftFeatureDetector : public FeatureDetector
public: public:
SiftFeatureDetector( double threshold=SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(), SiftFeatureDetector( double threshold=SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
double edgeThreshold=SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD(), double edgeThreshold=SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD(),
int angleMode=SIFT::DetectorParams::FIRST_ANGLE,
int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES, int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS, int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE ); int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE );
protected: protected:
virtual void detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const; virtual void detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const;
...@@ -1291,10 +1298,11 @@ protected: ...@@ -1291,10 +1298,11 @@ protected:
class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor
{ {
public: public:
SiftDescriptorExtractor( double magnification, bool isNormalize=true, SiftDescriptorExtractor( double magnification, bool isNormalize=true, bool recalculateAngles=true,
int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES, int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS, int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE ); int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE );
virtual void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const; virtual void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const;
...@@ -1408,10 +1416,7 @@ public: ...@@ -1408,10 +1416,7 @@ public:
* query The query set of descriptors * query The query set of descriptors
* matches Indices of the closest matches from the training set * matches Indices of the closest matches from the training set
*/ */
void match( const Mat& query, vector<int>& matches ) const;
// TODO: remove vector<double>* distances = 0 ???
void match( const Mat& query, vector<int>& matches, vector<double>* distances = 0 ) const;
/* /*
* Find the best matches between two descriptor sets, with constraints * Find the best matches between two descriptor sets, with constraints
...@@ -1479,15 +1484,10 @@ inline void DescriptorMatcher::add( const Mat& descriptors ) ...@@ -1479,15 +1484,10 @@ inline void DescriptorMatcher::add( const Mat& descriptors )
} }
} }
inline void DescriptorMatcher::match( const Mat& query, vector<int>& matches, vector<double>* distances ) const inline void DescriptorMatcher::match( const Mat& query, vector<int>& matches ) const
{ {
if( distances ) vector<double> innDistances;
matchImpl( query, train, Mat(), matches, *distances ); matchImpl( query, train, Mat(), matches, innDistances );
else
{
vector<double> innDistances;
matchImpl( query, train, Mat(), matches, innDistances );
}
} }
inline void DescriptorMatcher::match( const Mat& query, const Mat& mask, inline void DescriptorMatcher::match( const Mat& query, const Mat& mask,
......
...@@ -78,9 +78,9 @@ void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints, ...@@ -78,9 +78,9 @@ void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints,
/****************************************************************************************\ /****************************************************************************************\
* SiftDescriptorExtractor * * SiftDescriptorExtractor *
\****************************************************************************************/ \****************************************************************************************/
SiftDescriptorExtractor::SiftDescriptorExtractor( double magnification, bool isNormalize, SiftDescriptorExtractor::SiftDescriptorExtractor( double magnification, bool isNormalize, bool recalculateAngles,
int nOctaves, int nOctaveLayers, int firstOctave ) int nOctaves, int nOctaveLayers, int firstOctave, int angleMode )
: sift( magnification, isNormalize, nOctaves, nOctaveLayers, firstOctave ) : sift( magnification, isNormalize, recalculateAngles, nOctaves, nOctaveLayers, firstOctave, angleMode )
{} {}
void SiftDescriptorExtractor::compute( const Mat& image, void SiftDescriptorExtractor::compute( const Mat& image,
......
...@@ -152,9 +152,9 @@ void StarFeatureDetector::detectImpl( const Mat& image, const Mat& mask, vector< ...@@ -152,9 +152,9 @@ void StarFeatureDetector::detectImpl( const Mat& image, const Mat& mask, vector<
/* /*
SiftFeatureDetector SiftFeatureDetector
*/ */
SiftFeatureDetector::SiftFeatureDetector(double threshold, double edgeThreshold, int angleMode, SiftFeatureDetector::SiftFeatureDetector(double threshold, double edgeThreshold,
int nOctaves, int nOctaveLayers, int firstOctave) : int nOctaves, int nOctaveLayers, int firstOctave, int angleMode) :
sift(threshold, edgeThreshold, angleMode, nOctaves, nOctaveLayers, firstOctave) sift(threshold, edgeThreshold, nOctaves, nOctaveLayers, firstOctave, angleMode)
{ {
} }
......
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
// MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#include "precomp.hpp" #include "precomp.hpp"
#include<iostream> #include <iostream>
#include<limits> #include <limits>
#define log2(a) (log((a))/CV_LOG2) #define log2(a) (log((a))/CV_LOG2)
...@@ -1981,18 +1981,18 @@ using namespace cv; ...@@ -1981,18 +1981,18 @@ using namespace cv;
SIFT::SIFT() SIFT::SIFT()
{} {}
SIFT::SIFT( double _threshold, double _edgeThreshold, int _angleMode, SIFT::SIFT( double _threshold, double _edgeThreshold, int _nOctaves,
int _nOctaves, int _nOctaveLayers, int _firstOctave ) int _nOctaveLayers, int _firstOctave, int _angleMode )
{ {
detectorParams = DetectorParams(_threshold, _edgeThreshold, _angleMode); detectorParams = DetectorParams(_threshold, _edgeThreshold);
commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave); commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave, _angleMode);
} }
SIFT::SIFT( double _magnification, bool _isNormalize, SIFT::SIFT( double _magnification, bool _isNormalize, bool _recalculateAngles, int _nOctaves,
int _nOctaves, int _nOctaveLayers, int _firstOctave ) int _nOctaveLayers, int _firstOctave, int _angleMode )
{ {
descriptorParams = DescriptorParams(_magnification, _isNormalize); descriptorParams = DescriptorParams(_magnification, _isNormalize, _recalculateAngles);
commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave); commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave, _angleMode);
} }
SIFT::SIFT( const CommonParams& _commParams, SIFT::SIFT( const CommonParams& _commParams,
...@@ -2015,6 +2015,31 @@ inline void ocvKeypointToVl( const KeyPoint& ocvKeypoint, const VL::Sift& vlSift ...@@ -2015,6 +2015,31 @@ inline void ocvKeypointToVl( const KeyPoint& ocvKeypoint, const VL::Sift& vlSift
vlKeypoint = vlSift.getKeypoint(ocvKeypoint.pt.x, ocvKeypoint.pt.y, ocvKeypoint.size); vlKeypoint = vlSift.getKeypoint(ocvKeypoint.pt.x, ocvKeypoint.pt.y, ocvKeypoint.size);
} }
float computeKeypointOrientations( VL::Sift& sift, const VL::Sift::Keypoint& keypoint, int angleMode )
{
float angleVal = -1;
VL::float_t angles[4];
int angleCount = sift.computeKeypointOrientations(angles, keypoint);
if( angleCount > 0 )
{
if( angleMode == SIFT::CommonParams::FIRST_ANGLE )
{
angleVal = angles[0];
}
else if( angleMode == SIFT::CommonParams::AVERAGE_ANGLE )
{
for( int i = 0; i < angleCount; i++ )
angleVal += angles[i];
angleVal /= angleCount;
}
else
{
assert(0);
}
}
return angleVal;
}
// detectors // detectors
void SIFT::operator()(const Mat& img, const Mat& mask, void SIFT::operator()(const Mat& img, const Mat& mask,
vector<KeyPoint>& keypoints) const vector<KeyPoint>& keypoints) const
...@@ -2038,27 +2063,10 @@ void SIFT::operator()(const Mat& img, const Mat& mask, ...@@ -2038,27 +2063,10 @@ void SIFT::operator()(const Mat& img, const Mat& mask,
for( VL::Sift::KeypointsConstIter iter = vlsift.keypointsBegin(); iter != vlsift.keypointsEnd(); ++iter ) for( VL::Sift::KeypointsConstIter iter = vlsift.keypointsBegin(); iter != vlsift.keypointsEnd(); ++iter )
{ {
VL::float_t angles[4]; float angleVal = computeKeypointOrientations( vlsift, *iter, commParams.angleMode );
int angleCount = vlsift.computeKeypointOrientations(angles, *iter); if( angleVal >= 0 )
if( angleCount > 0 )
{ {
double angleVal = 0; keypoints.push_back( vlKeypointToOcv(*iter, angleVal*180.0/CV_PI) );
if( detectorParams.angleMode == DetectorParams::FIRST_ANGLE )
{
angleVal = angles[0];
}
else if( detectorParams.angleMode == DetectorParams::AVERAGE_ANGLE )
{
for( int i = 0; i < angleCount; i++ )
angleVal += angles[i];
angleVal /= angleCount;
}
else
{
assert(0);
}
keypoints.push_back( vlKeypointToOcv(*iter, angleVal*180.0/CV_PI ) );
} }
} }
} }
...@@ -2093,6 +2101,13 @@ void SIFT::operator()(const Mat& img, const Mat& mask, ...@@ -2093,6 +2101,13 @@ void SIFT::operator()(const Mat& img, const Mat& mask,
{ {
VL::Sift::Keypoint vlkpt; VL::Sift::Keypoint vlkpt;
ocvKeypointToVl( *iter, vlsift, vlkpt ); ocvKeypointToVl( *iter, vlsift, vlkpt );
vlsift.computeKeypointDescriptor((VL::float_t*)descriptors.ptr(pi), vlkpt, iter->angle*CV_PI/180.0); float angleVal = iter->angle*CV_PI/180.0;
if( descriptorParams.recalculateAngles )
{
float recalcAngleVal = computeKeypointOrientations( vlsift, vlkpt, commParams.angleMode );
if( recalcAngleVal >= 0 )
angleVal = recalcAngleVal;
}
vlsift.computeKeypointDescriptor((VL::float_t*)descriptors.ptr(pi), vlkpt, angleVal);
} }
} }
...@@ -437,7 +437,7 @@ struct SURFInvoker ...@@ -437,7 +437,7 @@ struct SURFInvoker
maxSize = std::max(maxSize, ((CvSURFPoint*)cvGetSeqElem( keypoints, k ))->size); maxSize = std::max(maxSize, ((CvSURFPoint*)cvGetSeqElem( keypoints, k ))->size);
maxSize = cvCeil((PATCH_SZ+1)*maxSize*1.2f/9.0f); maxSize = cvCeil((PATCH_SZ+1)*maxSize*1.2f/9.0f);
Ptr<CvMat> winbuf = cvCreateMat( 1, maxSize*maxSize, CV_8U ); Ptr<CvMat> winbuf = cvCreateMat( 1, maxSize > 0 ? maxSize*maxSize : 1, CV_8U );
for( k = k1; k < k2; k++ ) for( k = k1; k < k2; k++ )
{ {
......
...@@ -14,8 +14,7 @@ inline Point2f applyHomography( const Mat_<double>& H, const Point2f& pt ) ...@@ -14,8 +14,7 @@ inline Point2f applyHomography( const Mat_<double>& H, const Point2f& pt )
void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr, void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr,
const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2, const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
const vector<int>& matches, const vector<double>& distances, const vector<int>& matches, float maxDist, Mat& drawImg )
float maxDist, Mat& drawImg )
{ {
Scalar RED = CV_RGB(255, 0, 0); Scalar RED = CV_RGB(255, 0, 0);
Scalar PINK = CV_RGB(255,130,230); Scalar PINK = CV_RGB(255,130,230);
...@@ -49,9 +48,8 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr ...@@ -49,9 +48,8 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr
Mat vec1(3, 1, CV_32FC1), vec2; Mat vec1(3, 1, CV_32FC1), vec2;
float err = 3; float err = 3;
vector<int>::const_iterator mit = matches.begin(); vector<int>::const_iterator mit = matches.begin();
vector<double>::const_iterator dit = distances.begin(); assert( matches.size() == keypoints1.size() );
assert( matches.size() == distances.size() && matches.size() == keypoints1.size() ); for( int i1 = 0; mit < matches.end(); ++mit, i1++ )
for( int i1 = 0; mit < matches.end(); ++mit, ++dit, i1++ )
{ {
Point2f pt1 = keypoints1[i1].pt, pt2 = keypoints2[*mit].pt; Point2f pt1 = keypoints1[i1].pt, pt2 = keypoints2[*mit].pt;
Point2f diff = applyHomography(transfMtr, pt1) - pt2; Point2f diff = applyHomography(transfMtr, pt1) - pt2;
...@@ -63,12 +61,13 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr ...@@ -63,12 +61,13 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr
} }
else else
{ {
if( *dit > maxDist ) /*if( *dit > maxDist )
{ {
circle(drawImg, pt1, 3, PINK); circle(drawImg, pt1, 3, PINK);
circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, PINK); circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, PINK);
} }
else // TODO add key point filter
else*/
{ {
circle(drawImg, pt1, 3, BLUE); circle(drawImg, pt1, 3, BLUE);
circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, BLUE); circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, BLUE);
...@@ -93,8 +92,7 @@ FeatureDetector* createDetector( const string& detectorType ) ...@@ -93,8 +92,7 @@ FeatureDetector* createDetector( const string& detectorType )
else if( !detectorType.compare( "SIFT" ) ) else if( !detectorType.compare( "SIFT" ) )
{ {
fd = new SiftFeatureDetector(SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(), fd = new SiftFeatureDetector(SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD(), SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD());
SIFT::DetectorParams::FIRST_ANGLE);
} }
else if( !detectorType.compare( "SURF" ) ) else if( !detectorType.compare( "SURF" ) )
{ {
...@@ -184,17 +182,16 @@ void iter( Ptr<FeatureDetector> detector, Ptr<DescriptorExtractor> descriptor, ...@@ -184,17 +182,16 @@ void iter( Ptr<FeatureDetector> detector, Ptr<DescriptorExtractor> descriptor,
cout << "< Matching keypoints by descriptors... "; cout << "< Matching keypoints by descriptors... ";
vector<int> matches; vector<int> matches;
vector<double> distances;
Ptr<DescriptorMatcher> matcher = createDescMatcher(); Ptr<DescriptorMatcher> matcher = createDescMatcher();
matcher->add( descs2 ); matcher->add( descs2 );
matcher->match( descs1, matches, &distances ); matcher->match( descs1, matches );
cout << ">" << endl; cout << ">" << endl;
// TODO time // TODO time
Mat drawImg; Mat drawImg;
drawCorrespondences( img1, img2, transfMtr, keypoints1, keypoints2, drawCorrespondences( img1, img2, transfMtr, keypoints1, keypoints2,
matches, distances, maxDist, drawImg ); matches, maxDist, drawImg );
imshow( winName, drawImg); imshow( winName, drawImg);
} }
......
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