43 #include <visp/vpKeyPointSurf.h>
45 #if defined (VISP_HAVE_OPENCV_NONFREE)
46 #if (VISP_HAVE_OPENCV_VERSION >= 0x010100) && VISP_HAVE_OPENCV_VERSION < 0x030000// Require opencv >= 1.1.0 < 3.0.0
48 #include <visp/vpImageConvert.h>
49 #include <visp/vpImageTools.h>
50 #include <visp/vpDisplay.h>
51 #include <visp/vpDebug.h>
59 double compareSURFDescriptors(
const float* d1,
const float* d2,
double best,
int length );
60 int naiveNearestNeighbor(
const float *vec,
int laplacian,
61 const CvSeq *model_keypoints,
62 const CvSeq *model_descriptors );
63 int naiveNearestNeighbor(
const float *vec,
64 const CvSeq *ref_keypoints,
65 const CvSeq *ref_descriptors );
66 void findPairs(
const CvSeq* objectKeypoints,
67 const CvSeq* objectDescriptors,
68 const CvSeq* imageKeypoints,
69 const CvSeq* imageDescriptors,
70 std::vector<int>& ptpairs );
73 double compareSURFDescriptors(
const float* d1,
const float* d2,
double best,
int length )
75 double total_cost = 0;
77 assert( length % 4 == 0 );
78 for( i = 0; i < length; i += 4 )
80 double t0 = d1[i] - d2[i];
81 double t1 = d1[i+1] - d2[i+1];
82 double t2 = d1[i+2] - d2[i+2];
83 double t3 = d1[i+3] - d2[i+3];
84 total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
85 if( total_cost > best )
93 int naiveNearestNeighbor(
const float *vec,
int laplacian,
94 const CvSeq *model_keypoints,
95 const CvSeq *model_descriptors )
97 int length = (int)(model_descriptors->elem_size/(
int)
sizeof(float));
99 double d, dist1 = 1e6, dist2 = 1e6;
100 CvSeqReader reader, kreader;
101 cvStartReadSeq( model_keypoints, &kreader, 0 );
102 cvStartReadSeq( model_descriptors, &reader, 0 );
104 for( i = 0; i < model_descriptors->total; i++ )
106 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
107 const float* mvec = (
const float*)reader.ptr;
108 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
109 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
110 if( laplacian != kp->laplacian )
112 d = compareSURFDescriptors( vec, mvec, dist2, length );
119 else if ( d < dist2 )
122 if ( dist1 < 0.6*dist2 )
129 int naiveNearestNeighbor(
const float *vec,
130 const CvSeq *ref_keypoints,
131 const CvSeq *ref_descriptors )
133 int length = (int)(ref_descriptors->elem_size/(
int)
sizeof(float));
134 int i, neighbor = -1;
135 double d, dist1 = 1e6, dist2 = 1e6;
136 CvSeqReader reader, kreader;
137 cvStartReadSeq( ref_keypoints, &kreader, 0 );
138 cvStartReadSeq( ref_descriptors, &reader, 0 );
140 for( i = 0; i < ref_descriptors->total; i++ )
142 const float* mvec = (
const float*)reader.ptr;
143 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
144 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
145 d = compareSURFDescriptors( vec, mvec, dist2, length );
152 else if ( d < dist2 )
155 if ( dist1 < 0.6*dist2 )
163 void findPairs(
const CvSeq* objectKeypoints,
164 const CvSeq* objectDescriptors,
165 const CvSeq* imageKeypoints,
166 const CvSeq* imageDescriptors,
167 std::vector<int>& ptpairs )
170 CvSeqReader reader, kreader;
171 cvStartReadSeq( objectKeypoints, &kreader );
172 cvStartReadSeq( objectDescriptors, &reader );
175 for( i = 0; i < objectDescriptors->total; i++ )
177 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
178 const float* descriptor = (
const float*)reader.ptr;
179 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
180 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
181 int nearest_neighbor = naiveNearestNeighbor( descriptor,
185 if( nearest_neighbor >= 0 )
187 ptpairs.push_back(i);
188 ptpairs.push_back(nearest_neighbor);
204 storage(NULL), params(), storage_cur(NULL), image_keypoints(NULL), image_descriptors(NULL),
205 ref_keypoints(NULL), ref_descriptors(NULL), hessianThreshold(500), descriptorType(extendedDescriptor)
213 void vpKeyPointSurf::init()
215 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400) // Require opencv >= 2.4.0
216 cv::initModule_nonfree();
219 storage = cvCreateMemStorage(0);
220 params = cvSURFParams(hessianThreshold, descriptorType);
229 cvReleaseMemStorage(&storage);
230 if(storage_cur!=NULL){
231 cvReleaseMemStorage(&storage_cur);
246 IplImage* model = NULL;
251 CvSize size = cvSize(width, height);
252 model = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
253 model->imageData = (
char*)I.
bitmap;
258 cvExtractSURF( model, 0, &ref_keypoints, &ref_descriptors, storage, params );
260 const unsigned int nbPoints = (
unsigned int)ref_keypoints->total;
264 for(
unsigned int i = 0; i < nbPoints; i++ )
266 CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem(ref_keypoints, (
int)i);
273 model->imageData = NULL;
274 cvReleaseImageHeader(&model);
276 cvReleaseImage(&model);
303 const unsigned int height,
const unsigned int width)
308 vpTRACE(
"Bad size for the subimage");
310 "Bad size for the subimage"));
316 (
unsigned int)iP.
get_i(),
317 (
unsigned int)iP.
get_j(),
318 height, width, subImage);
322 for(
unsigned int k = 0; k < nbRefPoint; k++)
354 (
unsigned int)rectangle.
getWidth()));
370 IplImage* currentImage = NULL;
375 CvSize size = cvSize(width, height);
376 currentImage = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
377 currentImage->imageData = (
char*)I.
bitmap;
384 if(storage_cur != NULL){
385 cvReleaseMemStorage(&storage_cur);
388 storage_cur = cvCreateMemStorage(0);
390 cvExtractSURF( currentImage, 0, &image_keypoints, &image_descriptors,
391 storage_cur, params );
393 CvSeqReader reader, kreader;
394 cvStartReadSeq( ref_keypoints, &kreader );
395 cvStartReadSeq( ref_descriptors, &reader );
398 std::list<int> indexImagePair;
399 std::list<int> indexReferencePair;
402 unsigned int nbrPair = 0;
404 for(
int i = 0; i < ref_descriptors->total; i++ )
406 const CvSURFPoint* kp = (
const CvSURFPoint*)kreader.ptr;
407 const float* descriptor = (
const float*)reader.ptr;
408 CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
409 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
410 int nearest_neighbor = naiveNearestNeighbor( descriptor,
414 if( nearest_neighbor >= 0 )
416 indexReferencePair.push_back(i);
417 indexImagePair.push_back(nearest_neighbor);
422 std::list<int>::const_iterator indexImagePairIter = indexImagePair.begin();
423 std::list<int>::const_iterator indexReferencePairIter = indexReferencePair.begin();
433 for (
unsigned int i = 0; i < nbrPair; i++)
435 int index = *indexImagePairIter;
437 CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem(image_keypoints, index);
445 ++indexImagePairIter;
446 ++indexReferencePairIter;
450 currentImage->imageData = NULL;
451 cvReleaseImageHeader(¤tImage);
453 cvReleaseImage(¤tImage);
480 const unsigned int height,
const unsigned int width)
485 vpTRACE(
"Bad size for the subimage");
487 "Bad size for the subimage"));
493 (
unsigned int)iP.
get_i(),
494 (
unsigned int)iP.
get_j(),
495 height, width, subImage);
497 unsigned int nbMatchedPoint = this->
matchPoint(subImage);
499 for(
unsigned int k = 0; k < nbMatchedPoint; k++)
507 return(nbMatchedPoint);
533 (
unsigned int)rectangle.
getWidth()));
602 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
626 if(descriptorList.
nb != laplacianList.
nb){
627 vpTRACE(
"Error, the two lists have different number of element");
632 cvStartReadSeq( ref_descriptors, &reader );
634 descriptorList.
front();
636 laplacianList.
front();
638 while(!descriptorList.
outside()){
639 float* descriptor = descriptorList.
value();
641 int nearest_neighbor = naiveNearestNeighbor( descriptor, laplacianList.
value(), ref_keypoints, ref_descriptors);
643 if(nearest_neighbor >= 0){
646 tab[0] = nearest_neighbor;
651 descriptorList.
next();
652 laplacianList.
next();
661 std::list<int*>* pairPoints =
new std::list<int*>;
663 if(descriptorList.size() != laplacianList.size()){
664 vpTRACE(
"Error, the two lists have different number of element");
669 cvStartReadSeq( ref_descriptors, &reader );
671 std::list<float*>::const_iterator descriptorListIter = descriptorList.begin();
672 std::list<int>::const_iterator laplacianListIter = laplacianList.begin();
673 descriptorList.front();
675 while(descriptorListIter != descriptorList.end()){
676 float* descriptor = *descriptorListIter;
678 int nearest_neighbor = naiveNearestNeighbor( descriptor, *laplacianListIter, ref_keypoints, ref_descriptors);
680 if(nearest_neighbor >= 0){
683 tab[0] = nearest_neighbor;
685 pairPoints->push_back(tab);
688 ++descriptorListIter;
703 vpTRACE(
"Index of the reference point out of range");
707 float* descriptor = NULL;
710 cvStartReadSeq( ref_descriptors, &reader );
712 for(
int j = 0; j < ref_descriptors->total; j++ ){
714 descriptor = (
float*)reader.ptr;
717 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
731 vpTRACE(
"Index of the reference point out of range");
736 cvStartReadSeq( ref_keypoints, &reader );
740 for(
int j = 0; j < ref_keypoints->total; j++ ){
742 const CvSURFPoint* kp = (
const CvSURFPoint*)reader.ptr;
743 laplacian = kp->laplacian;
746 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
762 vpTRACE(
"Index of the reference point out of range");
767 cvStartReadSeq( ref_keypoints, &reader );
769 for(
int j = 0; j < ref_keypoints->total; j++ ){
771 const CvSURFPoint* kp = (
const CvSURFPoint*)reader.ptr;
776 CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
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)
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 set_i(const double ii)
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)
void set_j(const double jj)
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()