44#include <visp3/core/vpConfig.h>
46#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && \
47 (((VISP_HAVE_OPENCV_VERSION < 0x050000) && defined(HAVE_OPENCV_CALIB3D) && defined(HAVE_OPENCV_FEATURES2D)) || \
48 ((VISP_HAVE_OPENCV_VERSION >= 0x050000) && defined(HAVE_OPENCV_3D) && defined(HAVE_OPENCV_FEATURES)))
50#include <visp3/core/vpHomogeneousMatrix.h>
51#include <visp3/core/vpImage.h>
52#include <visp3/core/vpIoTools.h>
53#include <visp3/gui/vpDisplayFactory.h>
54#include <visp3/io/vpImageIo.h>
55#include <visp3/io/vpParseArgv.h>
56#include <visp3/io/vpVideoReader.h>
57#include <visp3/mbt/vpMbEdgeTracker.h>
58#include <visp3/vision/vpKeyPoint.h>
61#define GETOPTARGS "cdh"
63#ifdef ENABLE_VISP_NAMESPACE
67void usage(
const char *name,
const char *badparam);
68bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display);
78void usage(
const char *name,
const char *badparam)
81Test keypoints matching.\n\
91 Disable the mouse click. Useful to automate the \n\
92 execution of this program without human intervention.\n\
95 Turn off the display.\n\
101 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
115bool getOptions(
int argc,
const char **argv,
bool &click_allowed,
bool &display)
123 click_allowed =
false;
129 usage(argv[0],
nullptr);
133 usage(argv[0], optarg_);
138 if ((c == 1) || (c == -1)) {
140 usage(argv[0],
nullptr);
141 std::cerr <<
"ERROR: " << std::endl;
142 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
149template <
typename Type>
150void run_test(
const std::string &env_ipath,
bool opt_click_allowed,
bool opt_display,
vpImage<Type> &I,
153#if defined(VISP_HAVE_DATASET)
154#if VISP_HAVE_DATASET_VERSION >= 0x030600
155 std::string ext(
"png");
157 std::string ext(
"pgm");
161 std::string ext(
"png");
172 vpDisplay *display =
nullptr, *display2 =
nullptr;
175 Imatch.
resize(I.getHeight(), 2 * I.getWidth());
178#ifdef VISP_HAVE_DISPLAY
184 std::cout <<
"No image viewer is available..." << std::endl;
193#if defined(VISP_HAVE_PUGIXML)
194 tracker.loadConfigFile(tracker_config_file);
195 tracker.getCameraParameters(cam);
209 cam.initPersProjWithoutDistortion(547.7367575, 542.0744058, 338.7036994, 234.5083345);
210 tracker.setCameraParameters(cam);
211 tracker.setNearClippingDistance(0.01);
212 tracker.setFarClippingDistance(100.0);
221 tracker.loadModel(cao_model_file);
225 if (opt_display && opt_click_allowed) {
226 tracker.initClick(I, init_file);
229 vpHomogeneousMatrix cMoi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
238 cv::Ptr<cv::FeatureDetector> detector;
239 cv::Ptr<cv::DescriptorExtractor> extractor;
240 cv::Ptr<cv::DescriptorMatcher> matcher;
242#if defined(VISP_HAVE_OPENCV) && \
243 (((VISP_HAVE_OPENCV_VERSION < 0x050000) && defined(HAVE_OPENCV_FEATURES2D)) || \
244 ((VISP_HAVE_OPENCV_VERSION >= 0x050000) && defined(HAVE_OPENCV_FEATURES)))
245#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
246 detector = cv::ORB::create(500, 1.2f, 1);
247 extractor = cv::ORB::create(500, 1.2f, 1);
248#elif (VISP_HAVE_OPENCV_VERSION >= 0x020301)
249 detector = cv::FeatureDetector::create(
"ORB");
250 extractor = cv::DescriptorExtractor::create(
"ORB");
253 matcher = cv::DescriptorMatcher::create(
"BruteForce-Hamming");
256 std::vector<cv::KeyPoint> trainKeyPoints;
259 detector->detect(matImg, trainKeyPoints);
262 std::vector<vpPolygon> polygons;
263 std::vector<std::vector<vpPoint> > roisPt;
264 std::pair<std::vector<vpPolygon>, std::vector<std::vector<vpPoint> > > pair =
tracker.getPolygonFaces(
false);
265 polygons = pair.first;
266 roisPt = pair.second;
269 std::vector<cv::Point3f> points3f;
273 cv::Mat trainDescriptors;
274 extractor->compute(matImg, trainKeyPoints, trainDescriptors);
276 if (trainKeyPoints.size() !=
static_cast<size_t>(trainDescriptors.rows) || trainKeyPoints.size() != points3f.size()) {
286 bool opt_click =
false;
292 std::vector<cv::KeyPoint> queryKeyPoints;
293 detector->detect(matImg, queryKeyPoints);
295 cv::Mat queryDescriptors;
296 extractor->compute(matImg, queryKeyPoints, queryDescriptors);
298 std::vector<std::vector<cv::DMatch> > knn_matches;
299 std::vector<cv::DMatch> matches;
300 matcher->knnMatch(queryDescriptors, trainDescriptors, knn_matches, 2);
301 for (std::vector<std::vector<cv::DMatch> >::const_iterator it = knn_matches.begin(); it != knn_matches.end();
303 if (it->size() > 1) {
304 double ratio = (*it)[0].distance / (*it)[1].distance;
306 matches.push_back((*it)[0]);
312 for (std::vector<cv::DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it) {
313 vpPoint pt(points3f[
static_cast<size_t>(it->trainIdx)].x, points3f[
static_cast<size_t>(it->trainIdx)].y,
314 points3f[
static_cast<size_t>(it->trainIdx)].z);
316 double x = 0.0,
y = 0.0;
318 queryKeyPoints[
static_cast<size_t>(it->queryIdx)].pt.y, x, y);
325 bool is_pose_estimated =
false;
326 if (estimated_pose.
npt >= 4) {
328 unsigned int nb_inliers =
static_cast<unsigned int>(0.7 * estimated_pose.
npt);
333 is_pose_estimated =
true;
336 is_pose_estimated =
false;
340 is_pose_estimated =
false;
349 for (std::vector<cv::DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it) {
350 vpImagePoint leftPt(trainKeyPoints[
static_cast<size_t>(it->trainIdx)].pt.y, trainKeyPoints[
static_cast<size_t>(it->trainIdx)].pt.x);
351 vpImagePoint rightPt(queryKeyPoints[
static_cast<size_t>(it->queryIdx)].pt.y,
352 queryKeyPoints[
static_cast<size_t>(it->queryIdx)].pt.x + Iref.
getWidth());
356 if (is_pose_estimated) {
367 if (opt_click_allowed && opt_display) {
396int main(
int argc,
const char **argv)
399 std::string env_ipath;
400 bool opt_click_allowed =
true;
401 bool opt_display =
true;
404 if (getOptions(argc, argv, opt_click_allowed, opt_display) ==
false) {
412 if (env_ipath.empty()) {
413 std::cerr <<
"Please set the VISP_INPUT_IMAGE_PATH environment "
422 std::cout <<
"-- Test on gray level images" << std::endl;
423 run_test(env_ipath, opt_click_allowed, opt_display, I, Imatch, Iref);
429 std::cout <<
"-- Test on color images" << std::endl;
430 run_test(env_ipath, opt_click_allowed, opt_display, I, Imatch, Iref);
435 std::cerr <<
e.what() << std::endl;
439 std::cout <<
"testKeyPoint-4 is ok !" << std::endl;
446 std::cerr <<
"You need OpenCV library." << std::endl;
Generic class defining intrinsic camera parameters.
static const vpColor none
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 displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void flush(const vpImage< unsigned char > &I)
unsigned int getDownScalingFactor()
error that can be emitted by ViSP classes.
Implementation of an homogeneous matrix and operations on such kind of matrices.
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)
static void compute3DForPointsInPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, std::vector< cv::KeyPoint > &candidates, const std::vector< vpPolygon > &polygons, const std::vector< std::vector< vpPoint > > &roisPt, std::vector< cv::Point3f > &points, cv::Mat *descriptors=nullptr)
static double rad(double deg)
Make the complete tracking of an object by using its CAD model.
void setMu1(const double &mu_1)
void setRange(const unsigned int &range)
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
void setNbTotalSample(const int &ntotal_sample)
void setMaskNumber(const unsigned int &mask_number)
void setThreshold(const double &threshold)
void setSampleStep(const double &sample_step)
void setMaskSize(const unsigned int &mask_size)
void setMu2(const double &mu_2)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Class used for pose computation from N points (pose from point only). Some of the algorithms implemen...
void setRansacMaxTrials(const int &rM)
void addPoint(const vpPoint &P)
void setRansacNbInliersToReachConsensus(const unsigned int &nbC)
unsigned int npt
Number of point used in pose computation.
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, FuncCheckValidityPose func=nullptr)
void setRansacThreshold(const double &t)
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)
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.