added upright mode to SURF (#825)

This commit is contained in:
Maria Dimashova 2011-06-08 09:23:33 +00:00
parent 2d2b8a496e
commit b5163291dd
4 changed files with 126 additions and 82 deletions

View File

@ -81,6 +81,7 @@ CV_INLINE CvSURFPoint cvSURFPoint( CvPoint2D32f pt, int laplacian,
typedef struct CvSURFParams
{
int extended;
int upright;
double hessianThreshold;
int nOctaves;
@ -395,7 +396,7 @@ public:
CV_WRAP SURF();
//! the full constructor taking all the necessary parameters
CV_WRAP SURF(double _hessianThreshold, int _nOctaves=4,
int _nOctaveLayers=2, bool _extended=false);
int _nOctaveLayers=2, bool _extended=false, bool _upright=false);
//! returns the descriptor size in float's (64 or 128)
CV_WRAP int descriptorSize() const;
@ -1519,7 +1520,7 @@ protected:
class CV_EXPORTS SurfFeatureDetector : public FeatureDetector
{
public:
SurfFeatureDetector( double hessianThreshold=400., int octaves=3, int octaveLayers=4 );
SurfFeatureDetector( double hessianThreshold=400., int octaves=3, int octaveLayers=4, bool upright=false );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
@ -1897,7 +1898,7 @@ protected:
class CV_EXPORTS SurfDescriptorExtractor : public DescriptorExtractor
{
public:
SurfDescriptorExtractor( int nOctaves=4, int nOctaveLayers=2, bool extended=false );
SurfDescriptorExtractor( int nOctaves=4, int nOctaveLayers=2, bool extended=false, bool upright=false );
virtual void read( const FileNode &fn );
virtual void write( FileStorage &fs ) const;

View File

@ -191,8 +191,8 @@ int SiftDescriptorExtractor::descriptorType() const
* SurfDescriptorExtractor *
\****************************************************************************************/
SurfDescriptorExtractor::SurfDescriptorExtractor( int nOctaves,
int nOctaveLayers, bool extended )
: surf( 0.0, nOctaves, nOctaveLayers, extended )
int nOctaveLayers, bool extended, bool upright )
: surf( 0.0, nOctaves, nOctaveLayers, extended, upright )
{}
void SurfDescriptorExtractor::computeImpl( const Mat& image,
@ -218,8 +218,9 @@ void SurfDescriptorExtractor::read( const FileNode &fn )
int nOctaves = fn["nOctaves"];
int nOctaveLayers = fn["nOctaveLayers"];
bool extended = (int)fn["extended"] != 0;
bool upright = (int)fn["upright"] != 0;
surf = SURF( 0.0, nOctaves, nOctaveLayers, extended );
surf = SURF( 0.0, nOctaves, nOctaveLayers, extended, upright );
}
void SurfDescriptorExtractor::write( FileStorage &fs ) const
@ -229,6 +230,7 @@ void SurfDescriptorExtractor::write( FileStorage &fs ) const
fs << "nOctaves" << surf.nOctaves;
fs << "nOctaveLayers" << surf.nOctaveLayers;
fs << "extended" << surf.extended;
fs << "upright" << surf.upright;
}
int SurfDescriptorExtractor::descriptorSize() const

View File

@ -407,8 +407,8 @@ void SiftFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoi
/*
* SurfFeatureDetector
*/
SurfFeatureDetector::SurfFeatureDetector( double hessianThreshold, int octaves, int octaveLayers)
: surf(hessianThreshold, octaves, octaveLayers)
SurfFeatureDetector::SurfFeatureDetector( double hessianThreshold, int octaves, int octaveLayers, bool upright )
: surf(hessianThreshold, octaves, octaveLayers, false, upright)
{}
void SurfFeatureDetector::read (const FileNode& fn)
@ -416,8 +416,9 @@ void SurfFeatureDetector::read (const FileNode& fn)
double hessianThreshold = fn["hessianThreshold"];
int octaves = fn["octaves"];
int octaveLayers = fn["octaveLayers"];
bool upright = (int)fn["upright"] != 0;
surf = SURF( hessianThreshold, octaves, octaveLayers );
surf = SURF( hessianThreshold, octaves, octaveLayers, false, upright );
}
void SurfFeatureDetector::write (FileStorage& fs) const
@ -427,6 +428,7 @@ void SurfFeatureDetector::write (FileStorage& fs) const
fs << "hessianThreshold" << surf.hessianThreshold;
fs << "octaves" << surf.nOctaves;
fs << "octaveLayers" << surf.nOctaveLayers;
fs << "upright" << surf.upright;
}
void SurfFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const

View File

@ -114,6 +114,7 @@ CvSURFParams cvSURFParams(double threshold, int extended)
CvSURFParams params;
params.hessianThreshold = threshold;
params.extended = extended;
params.upright = 0;
params.nOctaves = 4;
params.nOctaveLayers = 2;
return params;
@ -630,6 +631,10 @@ struct SURFInvoker
kp->size = -1;
continue;
}
float descriptor_dir = 90.f;
if (params->upright == 0)
{
icvResizeHaarPattern( dx_s, dx_t, NX, 4, grad_wav_size, sum->cols );
icvResizeHaarPattern( dy_s, dy_t, NY, 4, grad_wav_size, sum->cols );
for( kk = 0, nangle = 0; kk < nOriSamples; kk++ )
@ -680,17 +685,22 @@ struct SURFInvoker
besty = sumy;
}
}
float descriptor_dir = cvFastArctan( besty, bestx );
descriptor_dir = cvFastArctan( besty, bestx );
}
kp->dir = descriptor_dir;
if( !descriptors )
continue;
descriptor_dir *= (float)(CV_PI/180);
/* Extract a window of pixels around the keypoint of size 20s */
int win_size = (int)((PATCH_SZ+1)*s);
CV_Assert( winbuf->cols >= win_size*win_size );
CvMat win = cvMat(win_size, win_size, CV_8U, winbuf->data.ptr);
if (params->upright == 0)
{
descriptor_dir *= (float)(CV_PI/180);
float sin_dir = sin(descriptor_dir);
float cos_dir = cos(descriptor_dir) ;
float cos_dir = cos(descriptor_dir);
/* Subpixel interpolation version (slower). Subpixel not required since
the pixels will all get averaged when we scale down to 20 pixels */
@ -717,7 +727,34 @@ struct SURFInvoker
WIN[i*win_size + j] = img->data.ptr[y*img->step + x];
}
}
}
else
{
/* extract rect - slightly optimized version of the code above
TODO: find faster code, as this is simply an extract rect operation,
e.g. by using cvGetSubRect, problem is the border processing */
// descriptor_dir == 90 grad
// sin_dir == 1
// cos_dir == 0
float win_offset = -(float)(win_size-1)/2;
int start_x = cvRound(center.x + win_offset);
int start_y = cvRound(center.y - win_offset);
uchar* WIN = win.data.ptr;
for( i = 0; i < win_size; i++, start_x++ )
{
int pixel_x = start_x;
int pixel_y = start_y;
for( j=0; j<win_size; j++, pixel_y-- )
{
x = MAX( pixel_x, 0 );
y = MAX( pixel_y, 0 );
x = MIN( x, img->cols-1 );
y = MIN( y, img->rows-1 );
WIN[i*win_size + j] = img->data.ptr[y*img->step+x];
}
}
}
/* Scale the window to size PATCH_SZ so each pixel's size is s. This
makes calculating the gradients with wavelets of size 2s easy */
cvResize( &win, &_patch, CV_INTER_AREA );
@ -924,14 +961,16 @@ SURF::SURF()
{
hessianThreshold = 100;
extended = 1;
upright = 0;
nOctaves = 4;
nOctaveLayers = 2;
}
SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended)
SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended, bool _upright)
{
hessianThreshold = _threshold;
extended = _extended;
upright = _upright;
nOctaves = _nOctaves;
nOctaveLayers = _nOctaveLayers;
}