41 #if defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION < 0x030000) 43 #include <visp3/core/vpDebug.h> 44 #include <visp3/core/vpDisplay.h> 45 #include <visp3/core/vpImageConvert.h> 46 #include <visp3/core/vpImageTools.h> 54 double compareSURFDescriptors(
const float *d1,
const float *d2,
double best,
int length);
55 int naiveNearestNeighbor(
const float *vec,
int laplacian,
const CvSeq *model_keypoints,
const CvSeq *model_descriptors);
56 int naiveNearestNeighbor(
const float *vec,
const CvSeq *ref_keypoints,
const CvSeq *ref_descriptors);
57 void findPairs(
const CvSeq *objectKeypoints,
const CvSeq *objectDescriptors,
const CvSeq *imageKeypoints,
58 const CvSeq *imageDescriptors, std::vector<int> &ptpairs);
61 double compareSURFDescriptors(
const float *d1,
const float *d2,
double best,
int length)
63 double total_cost = 0;
65 assert(length % 4 == 0);
66 for (i = 0; i < length; i += 4) {
67 double t0 = d1[i] - d2[i];
68 double t1 = d1[i + 1] - d2[i + 1];
69 double t2 = d1[i + 2] - d2[i + 2];
70 double t3 = d1[i + 3] - d2[i + 3];
71 total_cost += t0 * t0 + t1 * t1 + t2 * t2 + t3 * t3;
72 if (total_cost > best)
80 int naiveNearestNeighbor(
const float *vec,
int laplacian,
const CvSeq *model_keypoints,
const CvSeq *model_descriptors)
82 int length = (int)(model_descriptors->elem_size / (
int)
sizeof(float));
84 double d, dist1 = 1e6, dist2 = 1e6;
85 CvSeqReader reader, kreader;
86 cvStartReadSeq(model_keypoints, &kreader, 0);
87 cvStartReadSeq(model_descriptors, &reader, 0);
89 for (i = 0; i < model_descriptors->total; i++) {
90 const CvSURFPoint *kp = (
const CvSURFPoint *)kreader.ptr;
91 const float *mvec = (
const float *)reader.ptr;
92 CV_NEXT_SEQ_ELEM(kreader.seq->elem_size, kreader);
93 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
94 if (laplacian != kp->laplacian)
96 d = compareSURFDescriptors(vec, mvec, dist2, length);
101 }
else if (d < dist2)
104 if (dist1 < 0.6 * dist2)
111 int naiveNearestNeighbor(
const float *vec,
const CvSeq *ref_keypoints,
const CvSeq *ref_descriptors)
113 int length = (int)(ref_descriptors->elem_size / (
int)
sizeof(float));
114 int i, neighbor = -1;
115 double dist1 = 1e6, dist2 = 1e6;
116 CvSeqReader reader, kreader;
117 cvStartReadSeq(ref_keypoints, &kreader, 0);
118 cvStartReadSeq(ref_descriptors, &reader, 0);
120 for (i = 0; i < ref_descriptors->total; i++) {
121 const float *mvec = (
const float *)reader.ptr;
122 CV_NEXT_SEQ_ELEM(kreader.seq->elem_size, kreader);
123 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
124 double d = compareSURFDescriptors(vec, mvec, dist2, length);
129 }
else if (d < dist2)
132 if (dist1 < 0.6 * dist2)
138 void findPairs(
const CvSeq *objectKeypoints,
const CvSeq *objectDescriptors,
const CvSeq *imageKeypoints,
139 const CvSeq *imageDescriptors, std::vector<int> &ptpairs)
142 CvSeqReader reader, kreader;
143 cvStartReadSeq(objectKeypoints, &kreader);
144 cvStartReadSeq(objectDescriptors, &reader);
147 for (i = 0; i < objectDescriptors->total; i++) {
148 const CvSURFPoint *kp = (
const CvSURFPoint *)kreader.ptr;
149 const float *descriptor = (
const float *)reader.ptr;
150 CV_NEXT_SEQ_ELEM(kreader.seq->elem_size, kreader);
151 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
152 int nearest_neighbor = naiveNearestNeighbor(descriptor, kp->laplacian, imageKeypoints, imageDescriptors);
153 if (nearest_neighbor >= 0) {
154 ptpairs.push_back(i);
155 ptpairs.push_back(nearest_neighbor);
167 vpKeyPointSurf::vpKeyPointSurf()
168 :
vpBasicKeyPoint(), storage(NULL), params(), storage_cur(NULL), image_keypoints(NULL), image_descriptors(NULL),
169 ref_keypoints(NULL), ref_descriptors(NULL), hessianThreshold(500), descriptorType(extendedDescriptor)
177 void vpKeyPointSurf::init()
179 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400) // Require opencv >= 2.4.0 180 cv::initModule_nonfree();
183 storage = cvCreateMemStorage(0);
184 params = cvSURFParams(hessianThreshold, descriptorType);
191 vpKeyPointSurf::~vpKeyPointSurf()
193 cvReleaseMemStorage(&storage);
194 if (storage_cur != NULL) {
195 cvReleaseMemStorage(&storage_cur);
210 IplImage *model = NULL;
215 CvSize size = cvSize(width, height);
216 model = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
217 model->imageData = (
char *)I.
bitmap;
222 cvExtractSURF(model, 0, &ref_keypoints, &ref_descriptors, storage, params);
224 unsigned int nbPoints = (
unsigned int)ref_keypoints->total;
228 for (
unsigned int i = 0; i < nbPoints; i++) {
229 CvSURFPoint *r1 = (CvSURFPoint *)cvGetSeqElem(ref_keypoints, (
int)i);
236 model->imageData = NULL;
237 cvReleaseImageHeader(&model);
239 cvReleaseImage(&model);
264 unsigned int height,
unsigned int width)
267 vpTRACE(
"Bad size for the subimage");
277 for (
unsigned int k = 0; k < nbRefPoint; k++) {
317 IplImage *currentImage = NULL;
322 CvSize size = cvSize(width, height);
323 currentImage = cvCreateImageHeader(size, IPL_DEPTH_8U, 1);
324 currentImage->imageData = (
char *)I.
bitmap;
331 if (storage_cur != NULL) {
332 cvReleaseMemStorage(&storage_cur);
335 storage_cur = cvCreateMemStorage(0);
337 cvExtractSURF(currentImage, 0, &image_keypoints, &image_descriptors, storage_cur, params);
339 CvSeqReader reader, kreader;
340 cvStartReadSeq(ref_keypoints, &kreader);
341 cvStartReadSeq(ref_descriptors, &reader);
343 std::list<int> indexImagePair;
344 std::list<int> indexReferencePair;
346 unsigned int nbrPair = 0;
348 for (
int i = 0; i < ref_descriptors->total; i++) {
349 const CvSURFPoint *kp = (
const CvSURFPoint *)kreader.ptr;
350 const float *descriptor = (
const float *)reader.ptr;
351 CV_NEXT_SEQ_ELEM(kreader.seq->elem_size, kreader);
352 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
353 int nearest_neighbor = naiveNearestNeighbor(descriptor, kp->laplacian, image_keypoints, image_descriptors);
354 if (nearest_neighbor >= 0) {
355 indexReferencePair.push_back(i);
356 indexImagePair.push_back(nearest_neighbor);
361 std::list<int>::const_iterator indexImagePairIter = indexImagePair.begin();
362 std::list<int>::const_iterator indexReferencePairIter = indexReferencePair.begin();
372 for (
unsigned int i = 0; i < nbrPair; i++) {
373 int index = *indexImagePairIter;
375 CvSURFPoint *r1 = (CvSURFPoint *)cvGetSeqElem(image_keypoints, index);
382 ++indexImagePairIter;
383 ++indexReferencePairIter;
387 currentImage->imageData = NULL;
388 cvReleaseImageHeader(¤tImage);
390 cvReleaseImage(¤tImage);
415 unsigned int height,
unsigned int width)
418 vpTRACE(
"Bad size for the subimage");
426 unsigned int nbMatchedPoint = this->
matchPoint(subImage);
428 for (
unsigned int k = 0; k < nbMatchedPoint; k++) {
433 return (nbMatchedPoint);
523 std::list<int *> *vpKeyPointSurf::matchPoint(std::list<float *> descriptorList, std::list<int> laplacianList)
525 std::list<int *> *pairPoints =
new std::list<int *>;
527 if (descriptorList.size() != laplacianList.size()) {
528 vpTRACE(
"Error, the two lists have different number of element");
533 cvStartReadSeq(ref_descriptors, &reader);
535 std::list<float *>::const_iterator descriptorListIter = descriptorList.begin();
536 std::list<int>::const_iterator laplacianListIter = laplacianList.begin();
537 descriptorList.front();
539 while (descriptorListIter != descriptorList.end()) {
540 float *descriptor = *descriptorListIter;
542 int nearest_neighbor = naiveNearestNeighbor(descriptor, *laplacianListIter, ref_keypoints, ref_descriptors);
544 if (nearest_neighbor >= 0) {
547 tab[0] = nearest_neighbor;
549 pairPoints->push_back(tab);
552 ++descriptorListIter;
565 float *vpKeyPointSurf::getDescriptorReferencePoint(
int index)
568 vpTRACE(
"Index of the reference point out of range");
572 float *descriptor = NULL;
575 cvStartReadSeq(ref_descriptors, &reader);
577 for (
int j = 0; j < ref_descriptors->total; j++) {
579 descriptor = (
float *)reader.ptr;
582 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
594 int vpKeyPointSurf::getLaplacianReferencePoint(
int index)
597 vpTRACE(
"Index of the reference point out of range");
602 cvStartReadSeq(ref_keypoints, &reader);
606 for (
int j = 0; j < ref_keypoints->total; j++) {
608 const CvSURFPoint *kp = (
const CvSURFPoint *)reader.ptr;
609 laplacian = kp->laplacian;
612 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
626 void vpKeyPointSurf::getDescriptorParamReferencePoint(
int index,
int &size,
float &dir)
629 vpTRACE(
"Index of the reference point out of range");
634 cvStartReadSeq(ref_keypoints, &reader);
636 for (
int j = 0; j < ref_keypoints->total; j++) {
638 const CvSURFPoint *kp = (
const CvSURFPoint *)reader.ptr;
643 CV_NEXT_SEQ_ELEM(reader.seq->elem_size, reader);
647 #elif !defined(VISP_BUILD_SHARED_LIBS) 650 void dummy_vpKeyPointSurf(){};
class that defines what is a Keypoint. This class provides all the basic elements to implement classe...
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Type * bitmap
points toward the bitmap
Class to define RGB colors available for display functionnalities.
error that can be emited by ViSP classes.
static const vpColor green
Class that implements the SURF key points and technics thanks to the OpenCV library.
bool _reference_computed
flag to indicate if the reference has been built.
unsigned int buildReference(const vpImage< unsigned char > &I)
std::vector< vpImagePoint > referenceImagePointsList
unsigned int matchPoint(const vpImage< unsigned char > &I)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
unsigned int getHeight() const
std::vector< unsigned int > matchedReferencePoints
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 ...
unsigned int getWidth() const