44 #include <visp3/core/vpConfig.h>
46 #if defined(HAVE_OPENCV_IMGPROC) && (defined(HAVE_OPENCV_FEATURES2D) || defined(HAVE_OPENCV_FEATURES))
48 #if defined(HAVE_OPENCV_FEATURES)
49 #include <opencv2/features.hpp>
52 #if defined(HAVE_OPENCV_FEATURES2D)
53 #include <opencv2/features2d/features2d.hpp>
56 #include <visp3/core/vpImage.h>
57 #include <visp3/core/vpIoTools.h>
58 #include <visp3/gui/vpDisplayFactory.h>
59 #include <visp3/io/vpImageIo.h>
60 #include <visp3/io/vpParseArgv.h>
61 #include <visp3/io/vpVideoReader.h>
64 #define GETOPTARGS "cdh"
66 #ifdef ENABLE_VISP_NAMESPACE
70 void usage(
const char *name,
const char *badparam);
71 bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display);
80 void usage(
const char *name,
const char *badparam)
83 Test keypoints matching.\n\
93 Disable the mouse click. Useful to automate the \n\
94 execution of this program without human intervention.\n\
97 Turn off the display.\n\
103 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
117 bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display)
125 click_allowed =
false;
131 usage(argv[0],
nullptr);
136 usage(argv[0], optarg_);
142 if ((c == 1) || (c == -1)) {
144 usage(argv[0],
nullptr);
145 std::cerr <<
"ERROR: " << std::endl;
146 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
153 template <
typename Type>
154 void run_test(
const std::string &env_ipath,
bool opt_click_allowed,
bool opt_display,
vpImage<Type> &Iref,
157 #if VISP_HAVE_DATASET_VERSION >= 0x030600
158 std::string ext(
"png");
160 std::string ext(
"pgm");
171 cv::Ptr<cv::FeatureDetector> detector;
172 cv::Ptr<cv::DescriptorExtractor> extractor;
173 cv::Ptr<cv::DescriptorMatcher> matcher;
175 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
176 detector = cv::ORB::create();
177 extractor = cv::ORB::create();
179 detector = cv::FeatureDetector::create(
"ORB");
180 extractor = cv::DescriptorExtractor::create(
"ORB");
182 matcher = cv::DescriptorMatcher::create(
"BruteForce-Hamming");
184 std::vector<cv::KeyPoint> trainKeyPoints;
185 cv::Mat matImg, trainDescriptors;
187 detector->detect(matImg, trainKeyPoints);
188 extractor->compute(matImg, trainKeyPoints, trainDescriptors);
201 #ifdef VISP_HAVE_DISPLAY
205 std::cout <<
"No image viewer is available..." << std::endl;
209 bool opt_click =
false;
220 std::vector<cv::KeyPoint> queryKeyPoints;
221 detector->detect(matImg, queryKeyPoints);
223 cv::Mat queryDescriptors;
224 extractor->compute(matImg, queryKeyPoints, queryDescriptors);
226 std::vector<std::vector<cv::DMatch> > knn_matches;
227 std::vector<cv::DMatch> matches;
228 matcher->knnMatch(queryDescriptors, trainDescriptors, knn_matches, 2);
229 for (std::vector<std::vector<cv::DMatch> >::const_iterator it = knn_matches.begin(); it != knn_matches.end();
231 if (it->size() > 1) {
232 double ratio = (*it)[0].distance / (*it)[1].distance;
234 matches.push_back((*it)[0]);
240 for (std::vector<cv::DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it) {
241 vpImagePoint leftPt(trainKeyPoints[(
size_t)it->trainIdx].pt.y, trainKeyPoints[(
size_t)it->trainIdx].pt.x);
242 vpImagePoint rightPt(queryKeyPoints[(
size_t)it->queryIdx].pt.y,
243 queryKeyPoints[(
size_t)it->queryIdx].pt.x + Iref.
getWidth());
251 if (opt_click_allowed && opt_display) {
277 int main(
int argc,
const char **argv)
280 std::string env_ipath;
281 bool opt_click_allowed =
true;
282 bool opt_display =
true;
285 if (getOptions(argc, argv, opt_click_allowed, opt_display) ==
false) {
293 if (env_ipath.empty()) {
294 std::cerr <<
"Please set the VISP_INPUT_IMAGE_PATH environment "
303 std::cout <<
"-- Test on gray level images" << std::endl;
304 run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
310 std::cout <<
"-- Test on color images" << std::endl;
311 run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
316 std::cerr << e.
what() << std::endl;
320 std::cout <<
"testKeyPoint-3 is ok !" << std::endl;
327 std::cerr <<
"You need OpenCV library." << std::endl;
static const vpColor green
Class that defines generic functionalities for display.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
const char * what() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
unsigned int getHeight() const
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void acquire(vpImage< vpRGBa > &I)
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.