43 #include <visp/vpKeyPointSurf.h>
45 #if defined (VISP_HAVE_OPENCV_NONFREE)
46 #if VISP_HAVE_OPENCV_VERSION >= 0x010100 // Require opencv >= 1.1.0
48 #include <visp/vpImageConvert.h>
49 #include <visp/vpImageTools.h>
50 #include <visp/vpDisplay.h>
51 #include <visp/vpDebug.h>
60 double compareSURFDescriptors(
const float* d1,
const float* d2,
61 double best,
int length )
63 double total_cost = 0;
65 assert( length % 4 == 0 );
66 for( i = 0; i < length; i += 4 )
68 double t0 = d1[i] - d2[i];
69 double t1 = d1[i+1] - d2[i+1];
70 double t2 = d1[i+2] - d2[i+2];
71 double t3 = d1[i+3] - d2[i+3];
72 total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
73 if( total_cost > best )
81 int naiveNearestNeighbor(
const float *vec,
int laplacian,
82 const CvSeq *model_keypoints,
83 const CvSeq *model_descriptors )
85 int length = (int)(model_descriptors->elem_size/(
int)
sizeof(float));
87 double d, dist1 = 1e6, dist2 = 1e6;
88 CvSeqReader reader, kreader;
89 cvStartReadSeq( model_keypoints, &kreader, 0 );
90 cvStartReadSeq( model_descriptors, &reader, 0 );
92 for( i = 0; i < model_descriptors->total; i++ )
94 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
95 const float* mvec = (
const float*)reader.ptr;
96 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
97 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
98 if( laplacian != kp->laplacian )
100 d = compareSURFDescriptors( vec, mvec, dist2, length );
107 else if ( d < dist2 )
110 if ( dist1 < 0.6*dist2 )
117 int naiveNearestNeighbor(
const float *vec,
118 const CvSeq *ref_keypoints,
119 const CvSeq *ref_descriptors )
121 int length = (int)(ref_descriptors->elem_size/(
int)
sizeof(float));
122 int i, neighbor = -1;
123 double d, dist1 = 1e6, dist2 = 1e6;
124 CvSeqReader reader, kreader;
125 cvStartReadSeq( ref_keypoints, &kreader, 0 );
126 cvStartReadSeq( ref_descriptors, &reader, 0 );
128 for( i = 0; i < ref_descriptors->total; i++ )
130 const float* mvec = (
const float*)reader.ptr;
131 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
132 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
133 d = compareSURFDescriptors( vec, mvec, dist2, length );
140 else if ( d < dist2 )
143 if ( dist1 < 0.6*dist2 )
151 void findPairs(
const CvSeq* objectKeypoints,
152 const CvSeq* objectDescriptors,
153 const CvSeq* imageKeypoints,
154 const CvSeq* imageDescriptors,
155 std::vector<int>& ptpairs )
158 CvSeqReader reader, kreader;
159 cvStartReadSeq( objectKeypoints, &kreader );
160 cvStartReadSeq( objectDescriptors, &reader );
163 for( i = 0; i < objectDescriptors->total; i++ )
165 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
166 const float* descriptor = (
const float*)reader.ptr;
167 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
168 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
169 int nearest_neighbor = naiveNearestNeighbor( descriptor,
173 if( nearest_neighbor >= 0 )
175 ptpairs.push_back(i);
176 ptpairs.push_back(nearest_neighbor);
193 hessianThreshold = 500;
196 image_keypoints = NULL;
197 image_descriptors = NULL;
198 ref_keypoints = NULL;
199 ref_descriptors = NULL;
207 void vpKeyPointSurf::init()
209 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400) // Require opencv >= 2.4.0
210 cv::initModule_nonfree();
213 storage = cvCreateMemStorage(0);
214 params = cvSURFParams(hessianThreshold, descriptorType);
223 cvReleaseMemStorage(&storage);
224 if(storage_cur!=NULL){
225 cvReleaseMemStorage(&storage_cur);
240 IplImage* model = NULL;
245 CvSize size = cvSize(width, height);
246 model = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
247 model->imageData = (
char*)I.
bitmap;
252 cvExtractSURF( model, 0, &ref_keypoints, &ref_descriptors, storage, params );
254 const unsigned int nbPoints = (
unsigned int)ref_keypoints->total;
258 for(
unsigned int i = 0; i < nbPoints; i++ )
260 CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem(ref_keypoints, (
int)i);
267 model->imageData = NULL;
268 cvReleaseImageHeader(&model);
270 cvReleaseImage(&model);
297 const unsigned int height,
const unsigned int width)
302 vpTRACE(
"Bad size for the subimage");
304 "Bad size for the subimage"));
310 (
unsigned int)iP.
get_i(),
311 (
unsigned int)iP.
get_j(),
312 height, width, subImage);
316 for(
unsigned int k = 0; k < nbRefPoint; k++)
348 (
unsigned int)rectangle.
getWidth()));
364 IplImage* currentImage = NULL;
369 CvSize size = cvSize(width, height);
370 currentImage = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
371 currentImage->imageData = (
char*)I.
bitmap;
378 if(storage_cur != NULL){
379 cvReleaseMemStorage(&storage_cur);
382 storage_cur = cvCreateMemStorage(0);
384 cvExtractSURF( currentImage, 0, &image_keypoints, &image_descriptors,
385 storage_cur, params );
387 CvSeqReader reader, kreader;
388 cvStartReadSeq( ref_keypoints, &kreader );
389 cvStartReadSeq( ref_descriptors, &reader );
392 std::list<int> indexImagePair;
393 std::list<int> indexReferencePair;
396 unsigned int nbrPair = 0;
398 for(
int i = 0; i < ref_descriptors->total; i++ )
400 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
401 const float* descriptor = (
const float*)reader.ptr;
402 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
403 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
404 int nearest_neighbor = naiveNearestNeighbor( descriptor,
408 if( nearest_neighbor >= 0 )
410 indexReferencePair.push_back(i);
411 indexImagePair.push_back(nearest_neighbor);
416 std::list<int>::const_iterator indexImagePairIter = indexImagePair.begin();
417 std::list<int>::const_iterator indexReferencePairIter = indexReferencePair.begin();
427 for (
unsigned int i = 0; i < nbrPair; i++)
429 int index = *indexImagePairIter;
431 CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem(image_keypoints, index);
439 ++indexImagePairIter;
440 ++indexReferencePairIter;
444 currentImage->imageData = NULL;
445 cvReleaseImageHeader(¤tImage);
447 cvReleaseImage(¤tImage);
474 const unsigned int height,
const unsigned int width)
479 vpTRACE(
"Bad size for the subimage");
481 "Bad size for the subimage"));
487 (
unsigned int)iP.
get_i(),
488 (
unsigned int)iP.
get_j(),
489 height, width, subImage);
491 unsigned int nbMatchedPoint = this->
matchPoint(subImage);
493 for(
unsigned int k = 0; k < nbMatchedPoint; k++)
501 return(nbMatchedPoint);
527 (
unsigned int)rectangle.
getWidth()));
596 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
620 if(descriptorList.
nb != laplacianList.
nb){
621 vpTRACE(
"Error, the two lists have different number of element");
626 cvStartReadSeq( ref_descriptors, &reader );
628 descriptorList.
front();
630 laplacianList.
front();
632 while(!descriptorList.
outside()){
633 float* descriptor = descriptorList.
value();
635 int nearest_neighbor = naiveNearestNeighbor( descriptor, laplacianList.
value(), ref_keypoints, ref_descriptors);
637 if(nearest_neighbor >= 0){
640 tab[0] = nearest_neighbor;
645 descriptorList.
next();
646 laplacianList.
next();
655 std::list<int*>* pairPoints =
new std::list<int*>;
657 if(descriptorList.size() != laplacianList.size()){
658 vpTRACE(
"Error, the two lists have different number of element");
663 cvStartReadSeq( ref_descriptors, &reader );
665 std::list<float*>::const_iterator descriptorListIter = descriptorList.begin();
666 std::list<int>::const_iterator laplacianListIter = laplacianList.begin();
667 descriptorList.front();
669 while(descriptorListIter != descriptorList.end()){
670 float* descriptor = *descriptorListIter;
672 int nearest_neighbor = naiveNearestNeighbor( descriptor, *laplacianListIter, ref_keypoints, ref_descriptors);
674 if(nearest_neighbor >= 0){
677 tab[0] = nearest_neighbor;
679 pairPoints->push_back(tab);
682 ++descriptorListIter;
697 vpTRACE(
"Index of the reference point out of range");
701 float* descriptor = NULL;
704 cvStartReadSeq( ref_descriptors, &reader );
706 for(
int j = 0; j < ref_descriptors->total; j++ ){
708 descriptor = (
float*)reader.ptr;
711 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
725 vpTRACE(
"Index of the reference point out of range");
730 cvStartReadSeq( ref_keypoints, &reader );
734 for(
int j = 0; j < ref_keypoints->total; j++ ){
736 const CvSURFPoint* kp = (
const CvSURFPoint*)reader.ptr;
737 laplacian = kp->laplacian;
740 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
756 vpTRACE(
"Index of the reference point out of range");
761 cvStartReadSeq( ref_keypoints, &reader );
763 for(
int j = 0; j < ref_keypoints->total; j++ ){
765 const CvSURFPoint* kp = (
const CvSURFPoint*)reader.ptr;
770 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
void set_j(const double j)
class that defines what is a Keypoint. This class provides all the basic elements to implement classe...
void getDescriptorParamReferencePoint(const int index, int &size, float &dir)
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
unsigned int getWidth() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Provide simple list management.
Type * bitmap
points toward the bitmap
Class to define colors available for display functionnalities.
int getLaplacianReferencePoint(const int index)
void set_i(const double i)
error that can be emited by ViSP classes.
unsigned int matchPoint(const vpImage< unsigned char > &I)
void display(const vpImage< unsigned char > &Iref, const vpImage< unsigned char > &Icurrent, unsigned int size=3)
static const vpColor green
void next(void)
position the current element on the next one
void front(void)
Position the current element on the first element of the list.
float * getDescriptorReferencePoint(const int index)
type & value(void)
return the value of the current element
bool _reference_computed
flag to indicate if the reference has been built.
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void addRight(const type &el)
add a new element in the list, at the right of the current one
std::vector< vpImagePoint > referenceImagePointsList
unsigned int buildReference(const vpImage< unsigned char > &I)
std::vector< unsigned int > matchedReferencePoints
unsigned int getHeight() const
Defines a rectangle in the plane.
std::vector< vpImagePoint > currentImagePointsList
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
virtual ~vpKeyPointSurf()