44#include <visp3/core/vpConfig.h>
46#if defined(VISP_HAVE_OPENCV) && 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
70void usage(
const char *name,
const char *badparam);
71bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display);
80void usage(
const char *name,
const char *badparam)
83Test 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);
117bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display)
125 click_allowed =
false;
131 usage(argv[0],
nullptr);
135 usage(argv[0], optarg_);
140 if ((c == 1) || (c == -1)) {
142 usage(argv[0],
nullptr);
143 std::cerr <<
"ERROR: " << std::endl;
144 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
151template <
typename Type>
152void run_test(
const std::string &env_ipath,
bool opt_click_allowed,
bool opt_display,
vpImage<Type> &Iref,
155#if defined(VISP_HAVE_DATASET)
156#if VISP_HAVE_DATASET_VERSION >= 0x030600
157 std::string ext(
"png");
159 std::string ext(
"pgm");
163 std::string ext(
"png");
174 cv::Ptr<cv::FeatureDetector> detector;
175 cv::Ptr<cv::DescriptorExtractor> extractor;
176 cv::Ptr<cv::DescriptorMatcher> matcher;
178#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000)
179 detector = cv::ORB::create();
180 extractor = cv::ORB::create();
181#elif defined(VISP_HAVE_OPENCV)
182 detector = cv::FeatureDetector::create(
"ORB");
183 extractor = cv::DescriptorExtractor::create(
"ORB");
185 matcher = cv::DescriptorMatcher::create(
"BruteForce-Hamming");
187 std::vector<cv::KeyPoint> trainKeyPoints;
188 cv::Mat matImg, trainDescriptors;
190 detector->detect(matImg, trainKeyPoints);
191 extractor->compute(matImg, trainKeyPoints, trainDescriptors);
204#ifdef VISP_HAVE_DISPLAY
208 std::cout <<
"No image viewer is available..." << std::endl;
212 bool opt_click =
false;
223 std::vector<cv::KeyPoint> queryKeyPoints;
224 detector->detect(matImg, queryKeyPoints);
226 cv::Mat queryDescriptors;
227 extractor->compute(matImg, queryKeyPoints, queryDescriptors);
229 std::vector<std::vector<cv::DMatch> > knn_matches;
230 std::vector<cv::DMatch> matches;
231 matcher->knnMatch(queryDescriptors, trainDescriptors, knn_matches, 2);
232 for (std::vector<std::vector<cv::DMatch> >::const_iterator it = knn_matches.begin(); it != knn_matches.end();
234 if (it->size() > 1) {
235 double ratio = (*it)[0].distance / (*it)[1].distance;
237 matches.push_back((*it)[0]);
243 for (std::vector<cv::DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it) {
244 vpImagePoint leftPt(trainKeyPoints[
static_cast<size_t>(it->trainIdx)].pt.y, trainKeyPoints[
static_cast<size_t>(it->trainIdx)].pt.x);
245 vpImagePoint rightPt(queryKeyPoints[
static_cast<size_t>(it->queryIdx)].pt.y,
246 queryKeyPoints[
static_cast<size_t>(it->queryIdx)].pt.x + Iref.
getWidth());
254 if (opt_click_allowed && opt_display) {
280int main(
int argc,
const char **argv)
283 std::string env_ipath;
284 bool opt_click_allowed =
true;
285 bool opt_display =
true;
288 if (getOptions(argc, argv, opt_click_allowed, opt_display) ==
false) {
296 if (env_ipath.empty()) {
297 std::cerr <<
"Please set the VISP_INPUT_IMAGE_PATH environment "
306 std::cout <<
"-- Test on gray level images" << std::endl;
307 run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
313 std::cout <<
"-- Test on color images" << std::endl;
314 run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
319 std::cerr <<
e.what() << std::endl;
323 std::cout <<
"testKeyPoint-3 is ok !" << std::endl;
330 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.
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 open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.