15 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
22 #include <mrpt/otherlibs/do_opencv_includes.h>
23 #ifdef HAVE_OPENCV_NONFREE // MRPT_HAS_OPENCV_NONFREE
24 #include <opencv2/nonfree/nonfree.hpp>
26 #ifdef HAVE_OPENCV_FEATURES2D
27 #include <opencv2/features2d/features2d.hpp>
29 #ifdef HAVE_OPENCV_XFEATURES2D
30 #include <opencv2/xfeatures2d.hpp>
46 #if MRPT_OPENCV_VERSION_NUM >= 0x211
53 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
56 IplImage* create_init_img(
const IplImage*,
int,
double);
57 IplImage*** build_gauss_pyr(IplImage*,
int,
int,
double);
58 IplImage*** build_dog_pyr(IplImage***,
int,
int);
59 CvSeq* scale_space_extrema(IplImage***,
int,
int,
double,
int, CvMemStorage*);
60 int is_extremum(IplImage***,
int,
int,
int,
int);
61 struct feature* new_feature(
void);
62 void calc_feature_scales(CvSeq*,
double,
int);
63 void adjust_for_img_dbl(CvSeq*);
64 void calc_feature_oris(CvSeq*, IplImage***);
65 void compute_descriptors(CvSeq*, IplImage***,
int,
int);
66 int feature_cmp(
void*,
void*,
void*);
67 void release_pyr(IplImage****,
int,
int);
69 #endif // MRPT_HAS_OPENCV
76 unsigned int nDesiredFeatures,
const TImageROI& ROI)
const
78 bool usingROI =
false;
98 img_grayscale.
swap(auximg);
101 switch (options.SIFTOptions.implementation)
111 char filImg[2000], filOut[2000], filFeat[2000];
114 GetTempPathA(1000, filOut);
116 GetTempPathA(1000, filImg);
121 bool onlyDesc = feats.
size() > 0 ? true :
false;
125 GetTempPathA(1000, filFeat);
127 filFeat, 1000,
"temp_feats.txt");
129 for (
size_t i = 0; i < feats.
size(); i++)
131 listPoints(i, 0) = feats[i]->x;
132 listPoints(i, 1) = feats[i]->y;
134 listPoints.saveToTextFile(
145 os::strcpy(paramImg, 1000,
"extractSIFT.exe -i");
159 "[extractFeaturesSIFT] Could not launch external "
160 "process... (extractSIFT.exe)")
167 aux.loadFromTextFile(filOut);
168 std::cout <<
"[computeSiftFeatures] " << aux.rows() <<
" features."
172 nFeats = feats.
size();
179 for (
size_t i = 0; itFeat != feats.
end(); i++, itFeat++)
182 (*itFeat)->x = usingROI ? aux(i, 0) + ROI.
xMin : aux(i, 0);
183 (*itFeat)->y = usingROI ? aux(i, 1) + ROI.
yMin : aux(i, 1);
184 (*itFeat)->orientation = aux(i, 2);
185 (*itFeat)->scale = aux(i, 3);
186 (*itFeat)->ID = init_ID + i;
189 aux.extractRow(i, (*itFeat)->descriptors.SIFT, 4);
195 "Unfortunately, this SIFT Implementation only runs in Windows "
196 "OS, try Hess implementation");
207 "Usage of Vedaldi Binary not implemented yet, please, try "
211 "Unfortunately, this SIFT Implementation only runs in Windows "
212 "OS, try Hess implementation");
222 char filImg[2000], filOut[2000];
227 GetTempPathA(1000, filOut);
229 GetTempPathA(1000, filImg);
234 bool valid = img_grayscale.
saveToFile(filImg);
237 "An error occurred when saving input image into a .pgm "
244 format(
"cmd /C gmic.exe %s -o %s -quiet", filImg, filImg)
251 "[extractFeaturesSIFT] Could not launch external "
252 "process... (gmic.exe)");
257 os::strcpy(paramImg, 1000,
"cmd /C siftWin32.exe <");
266 "[extractFeaturesSIFT] Could not launch external "
267 "process... (siftWin32.exe)");
272 unsigned int dLen, nFeats;
276 "Error in extract SIFT with Lowe binary, output file not "
282 for (
size_t i = 0; i < nFeats; i++)
287 feat->ID = init_ID + i;
292 float fx, fy, fo, fs;
293 fscanf(f,
"%f %f %f %f", &fy, &fx, &fo, &fs);
295 feat->x = usingROI ? fx + ROI.
xMin : fx;
296 feat->y = usingROI ? fy + ROI.
yMin : fy;
297 feat->orientation = fo;
301 feat->descriptors.SIFT.resize(dLen);
303 for (
unsigned int k = 0; k < dLen; k++)
306 feat->descriptors.SIFT[k] = (
unsigned char)
c;
316 "Unfortunately, this SIFT Implementation only runs in Windows "
317 "OS, try Hess implementation");
326 #if !MRPT_HAS_SIFT_HESS
328 "Method not available since MRPT has been compiled without "
329 "Hess' SIFT library")
330 #elif MRPT_HAS_OPENCV // OK, we have Hess' sift:
332 IplImage ***gauss_pyr, ***dog_pyr;
333 CvMemStorage* storage;
342 const IplImage* ipl_im = img_grayscale.
getAs<IplImage>();
344 octvs = log((
float)(MIN(init_img->width, init_img->height))) /
349 dog_pyr = build_dog_pyr(gauss_pyr, octvs,
SIFT_INTVLS);
350 storage = cvCreateMemStorage(0);
351 features = scale_space_extrema(
353 options.SIFTOptions.threshold,
354 options.SIFTOptions.edgeThreshold,
358 calc_feature_oris(features, gauss_pyr);
363 cvSeqSort(features, (CvCmpFunc)feature_cmp,
nullptr);
366 if (nDesiredFeatures > 0)
368 if (nDesiredFeatures < (
unsigned int)features->total)
370 features,
nullptr, features->total - nDesiredFeatures);
372 cout <<
"[Warning] Detected less features than the "
374 << features->total <<
" vs " << nDesiredFeatures
379 convertCvSeqInCFeatureList(features, feats, init_ID, ROI);
382 cvClearSeq(features);
383 cvReleaseMemStorage(&storage);
384 cvReleaseImage(&init_img);
389 "Method not available since MRPT has been compiled without "
391 #endif // MRPT_HAS_OPENCV
399 #if defined(HAVE_OPENCV_NONFREE) || \
400 defined(HAVE_OPENCV_XFEATURES2D) // MRPT_HAS_OPENCV_NONFREE
402 #if MRPT_OPENCV_VERSION_NUM >= 0x211 && MRPT_OPENCV_VERSION_NUM < 0x300
404 SiftFeatureDetector SIFTDetector(
412 SiftDescriptorExtractor SIFTDescriptor;
414 vector<KeyPoint> cv_feats;
416 const IplImage* cGrey = img_grayscale.
getAs<IplImage>();
418 Mat theImg = cvarrToMat(cGrey);
419 SIFTDetector.detect(theImg, cv_feats);
422 SIFTDescriptor.compute(theImg, cv_feats, desc);
426 const size_t N = cv_feats.size();
427 unsigned int nMax = nDesiredFeatures != 0 && N > nDesiredFeatures
430 const int offset = (int)this->options.patchSize / 2 + 1;
431 const size_t size_2 = options.patchSize / 2;
432 const size_t imgH =
img.getHeight();
433 const size_t imgW =
img.getWidth();
435 unsigned int cont = 0;
438 while (cont != nMax && i != N)
440 const int xBorderInf = (int)floor(cv_feats[i].pt.x - size_2);
441 const int xBorderSup = (int)floor(cv_feats[i].pt.x + size_2);
442 const int yBorderInf = (int)floor(cv_feats[i].pt.y - size_2);
443 const int yBorderSup = (int)floor(cv_feats[i].pt.y + size_2);
445 if (options.patchSize == 0 ||
446 ((xBorderSup < (
int)imgW) && (xBorderInf > 0) &&
447 (yBorderSup < (int)imgH) && (yBorderInf > 0)))
452 ft->x = cv_feats[i].pt.x;
453 ft->y = cv_feats[i].pt.y;
454 ft->response = cv_feats[i].response;
455 ft->orientation = cv_feats[i].angle;
456 ft->scale = cv_feats[i].size;
459 ft->descriptors.SIFT.resize(128);
461 &(ft->descriptors.SIFT[0]), &desc.data[128 * i],
463 sizeof(ft->descriptors.SIFT[0]));
465 if (options.patchSize > 0)
482 vector<KeyPoint> cv_feats;
484 cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create(
485 nDesiredFeatures, 3, options.SIFTOptions.threshold,
486 options.SIFTOptions.edgeThreshold, 1.6);
487 const IplImage* cGrey = img_grayscale.
getAs<IplImage>();
488 Mat theImg = cvarrToMat(cGrey);
490 sift->detect(theImg, cv_feats);
493 sift->compute(theImg, cv_feats, desc);
497 const size_t N = cv_feats.size();
498 unsigned int nMax = nDesiredFeatures != 0 && N > nDesiredFeatures
501 const int offset = (int)this->options.patchSize / 2 + 1;
502 const size_t size_2 = options.patchSize / 2;
503 const size_t imgH =
img.getHeight();
504 const size_t imgW =
img.getWidth();
506 unsigned int cont = 0;
510 while (cont != nMax && i != N)
512 const int xBorderInf = (int)floor(cv_feats[i].pt.x - size_2);
513 const int xBorderSup = (int)floor(cv_feats[i].pt.x + size_2);
514 const int yBorderInf = (int)floor(cv_feats[i].pt.y - size_2);
515 const int yBorderSup = (int)floor(cv_feats[i].pt.y + size_2);
517 if (options.patchSize == 0 ||
518 ((xBorderSup < (
int)imgW) && (xBorderInf > 0) &&
519 (yBorderSup < (int)imgH) && (yBorderInf > 0)))
524 ft->x = cv_feats[i].pt.x;
525 ft->y = cv_feats[i].pt.y;
526 ft->response = cv_feats[i].response;
527 ft->orientation = cv_feats[i].angle;
528 ft->scale = cv_feats[i].size;
531 ft->descriptors.SIFT.resize(128);
533 &(ft->descriptors.SIFT[0]), &desc.data[128 * i],
535 sizeof(ft->descriptors.SIFT[0]));
537 if (options.patchSize > 0)
554 "This method requires OpenCV >= 2.1.1 with nonfree module")
574 switch (options.SIFTOptions.implementation)
579 char filImg[2000], filOut[2000], filFeat[2000];
585 GetTempPathA(1000, filImg);
587 GetTempPathA(1000, filOut);
589 GetTempPathA(1000, filFeat);
590 os::strcat(filFeat, 1000,
"temp_KLT_feats.txt");
594 for (feat = in_features.
begin(); feat != in_features.
end(); feat++)
595 os::fprintf(fout,
"%.6f %.6f\n", (*feat)->x, (*feat)->y);
606 os::strcpy(paramImg, 1000,
"extractSIFT.exe -i");
617 "[extractFeaturesSIFT] Could not launch external "
618 "process... (extractSIFT.exe)");
623 aux.loadFromTextFile(filOut);
624 size_t nRows = aux.rows();
626 std::cout <<
"[computeSiftFeatures1] " << nRows <<
" features.\n";
632 feat = in_features.
begin();
634 for (i = 0; i < nRows; i++)
636 if (aux(i, 0) != lx ||
640 (*feat)->orientation = aux(i, 2);
641 (*feat)->scale = aux(i, 3);
644 aux.extractRow(i, (*feat)->descriptors.SIFT, 4);
661 #if !MRPT_HAS_SIFT_HESS
663 "Method not available since MRPT has been compiled without "
664 "Hess' SIFT library")
665 #elif MRPT_HAS_OPENCV // OK, we have Hess' sift:
667 IplImage ***gauss_pyr, ***dog_pyr;
668 CvMemStorage* storage;
678 const IplImage* ipl_im = img_grayscale.
getAs<IplImage>();
681 octvs = log((
float)(MIN(init_img->width, init_img->height))) /
686 dog_pyr = build_dog_pyr(gauss_pyr, octvs,
SIFT_INTVLS);
688 storage = cvCreateMemStorage(0);
689 features =
static_cast<CvSeq*
>(
690 my_scale_space_extrema(
692 options.SIFTOptions.threshold,
693 options.SIFTOptions.edgeThreshold,
697 calc_feature_oris(features, gauss_pyr);
702 insertCvSeqInCFeatureList(features, in_features);
705 cvClearSeq(features);
708 cvReleaseMemStorage(&storage);
709 cvReleaseImage(&init_img);
747 "Method not available since MRPT has been compiled without "
749 #endif // MRPT_HAS_OPENCV
754 cout <<
"SIFT Extraction method not supported for features with "
755 "already known image coordinates"
767 void* features_,
CFeatureList& list,
unsigned int init_ID,
770 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
771 CvSeq* features =
reinterpret_cast<CvSeq*
>(features_);
774 bool usingROI =
false;
778 int n = features->total;
783 for (
int k = 0; k <
n; k++)
785 thisFeat = (
feature*)cvGetSeqElem(features, k);
788 feat->x = usingROI ? thisFeat->
x + ROI.
xMin : thisFeat->
x;
789 feat->y = usingROI ? thisFeat->
y + ROI.
yMin : thisFeat->
y;
791 feat->orientation = thisFeat->
ori;
792 feat->scale = thisFeat->
scl;
793 feat->descriptors.SIFT.resize(thisFeat->
d);
794 for (
int i = 0; i < thisFeat->
d; i++)
795 feat->descriptors.SIFT[i] = (
unsigned char)thisFeat->
descr[i];
801 "Method not available since MRPT has been compiled without OpenCV")
802 #endif // MRPT_HAS_OPENCV
808 void* features_,
CFeatureList& list,
unsigned int init_ID)
const
810 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
811 CvSeq* features =
reinterpret_cast<CvSeq*
>(features_);
813 int n = features->total;
819 for (itFeat = list.
begin(), k = 0; itFeat != list.
end() && k <
n; k++)
821 thisFeat = (
feature*)cvGetSeqElem(features, k);
822 if ((*itFeat)->x == thisFeat->
x && (*itFeat)->y == thisFeat->
y)
825 (*itFeat)->orientation = thisFeat->
ori;
826 (*itFeat)->scale = thisFeat->
scl;
827 (*itFeat)->descriptors.SIFT.resize(thisFeat->
d);
828 for (
int i = 0; i < thisFeat->
d; i++)
829 (*itFeat)->descriptors.SIFT[i] =
830 (
unsigned char)thisFeat->
descr[i];
837 "Method not available since MRPT has been compiled without OpenCV")
838 #endif // MRPT_HAS_OPENCV
849 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
850 CvSeq* features =
reinterpret_cast<CvSeq*
>(features_);
855 for (i = 0; i <
n; i++)
857 feat = CV_GET_SEQ_ELEM(
struct feature, features, i);
862 "Method not available since MRPT has been compiled without OpenCV")
863 #endif // MRPT_HAS_OPENCV
870 CFeatureList& featList,
void* dog_pyr_,
int octvs,
int intvls,
871 double contr_thr,
int curv_thr,
void* storage_)
const
875 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
876 CvMemStorage* storage =
reinterpret_cast<CvMemStorage*
>(storage_);
877 IplImage*** dog_pyr =
reinterpret_cast<IplImage***
>(dog_pyr_);
887 features = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(
struct feature), storage);
888 for (itFeats = featList.
begin(); itFeats != featList.
end(); itFeats++)
893 float gr = 0.0, gc = 0.0;
895 if ((*itFeats)->y < 0 || (*itFeats)->x < 0)
900 for (o = 0; o < octvs; o++)
902 float r = (*itFeats)->y / pow(2.0, o);
903 float c = (*itFeats)->x / pow(2.0, o);
905 for (i = 1; i <= intvls; i++)
908 double val =
s * getLaplacianValue(dog_pyr, o, i,
r,
c);
932 feat = new_feature();
936 feat->
img_pt.y = feat->
y = (*itFeats)->y;
943 cvSeqPush(features, feat);
949 "Method not available since MRPT has been compiled without OpenCV")
950 #endif // MRPT_HAS_OPENCV
957 void* dog_pyr_,
int octv,
int intvl,
float row,
float col)
const
959 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
960 IplImage*** dog_pyr =
reinterpret_cast<IplImage***
>(dog_pyr_);
964 for (j = -1; j <= 1; j++)
965 for (k = -1; k <= 1; k++)
971 if (k == 0 && j == 0)
982 "Method not available since MRPT has been compiled without OpenCV")
983 #endif // MRPT_HAS_OPENCV
992 void* dog_pyr_,
int octv,
int intvl,
float row,
float col,
993 unsigned int& nMin,
unsigned int& nMax)
const
995 #if MRPT_HAS_OPENCV && MRPT_HAS_SIFT_HESS
996 IplImage*** dog_pyr =
reinterpret_cast<IplImage***
>(dog_pyr_);
1005 for (i = -1; i <= 1; i++)
1006 for (j = -1; j <= 1; j++)
1007 for (k = -1; k <= 1; k++)
1022 "Method not available since MRPT has been compiled without OpenCV")
1023 #endif // MRPT_HAS_OPENCV