国外论坛上关于cvExtractSURF函数的说明

来源:互联网 发布:张店淘宝客服招聘 编辑:程序博客网 时间:2024/05/01 10:44

You can view the implementation of *cvExtractSURF(...)* here:
http://opencvlibrary.svn.sourceforge.net/viewvc/opencvlibrary/trunk/opencv/src/cv/cvsurf.cpp,
however it doesn't contain much comments.


*cvExtractSURF( const CvArr* img, const CvArr* mask, CvSeq** keypoints,
CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params )*

Here, *img* is the image. Use an
*IplImage<http://opencv.willowgarage.com/wiki/CxCore#IplImage>
* for the image. To load an image from disk, use
*cvLoadImage(...)*<http://opencv.willowgarage.com/wiki/HighGui#cvLoadImage>,
and to create your own image, use
*cvCreateImage(...)*<http://opencv.willowgarage.com/wiki/CxCore#CreateImage>.
Lets say you have a IplImage *image* and want to extract the rectangle
(x,y)->(x+dx,y+dy) from it as an IplImage rectangle, you might do this:

CvSize size = cvSize(dx,dy);
IplImage* rectangle = cvCreateImage(size, IPL_DEPTH_8U, 1);
for (int i = 0; i < dx; ++i) {
    for (int j = 0; j < dy; ++j) {
        CV_IMAGE_ELEM(rectangle,unsigned char,i,j) =
CV_IMAGE_ELEM(image,unsigned char,x+i,y+j);
    }
}

I'm not sure how *mask* is used, but a quick google search gives
http://www.emgu.com/wiki/files/1.4.0.0/html/ad54862f-3d1c-c177-3bdb-768619f8dd90.htmwhich
says "The optional input 8-bit mask. The features are only found in
the areas that contain more than 50% of non-zero mask pixels". Just set it
to NULL.

*keypoints* and
*descriptors*<http://en.wikipedia.org/wiki/Feature_%28computer_vision%29>are
where the results are placed. Initialize them as null-pointers and
cvExtractSURF will do the rest for you. Afterwards you can access a
descriptor and corresponding keypoint like this:

int k = 0; // the keypoint you want. There are *keypoints->total* keypoints.
float *seq = (float*)cvGetSeqElem(descriptors, k); // the descriptor of
length 64 or 128
CvPoint2D32f *p = &((CvSURFPoint*)cvGetSeqElem(keypoints, k))->pt; // the
(x,y) coordinates of keypoint *k* can now be accessed as *p->x* and *p->y*

The *CvMemStorage*
<http://opencv.willowgarage.com/wiki/CxCore#CvMemStorage>struct
*storage* is used as a mechanism to simplify memory management. I believe
the *keypoints* and *descriptors* structures are put into *storage*, so you
can't release *storage* until you're done using *keypoints* and *descriptors
*.Put a *CvMemStorage *storage = cvCreateMemStorage(0);* before your first
call to cvExtractSURF and *cvClearMemStorage(storage);* after you're done
using *keypoints* and *descriptors*.

SURF takes a couple of parameters through the *CvSURFParams* struct *params*.
You create *params* with *cvSURFParams(double threshold, int
extended)*where threshold represents the "edgyness" that is required
from a feature to
be recognized as a feature. It can be adjusted to retrieve more or fewer
features. In the paper
<http://www.vision.ee.ethz.ch/%7Esurf/eccv06.pdf>describing the SURF
detector, they use a threshold of 600 on a 800 x 640
image which returned 1418 features. The *extended* parameter is a simple
boolean 1 or 0 which states whether or not to use the extended descriptor.
The extended descriptor consists of 128 instead of 64 values which should
gives a better result at the cost of using more memory. Instead of creating
a new CvSURFParams struct for each call to cvExtractSURF, you could do:

CvSURFParams params = cvSURFParams(600, 1);
cvExtractSURF(..., params);
cvExtractSURF(..., params);

原创粉丝点击