41 #include <visp3/core/vpImage.h>
42 #include <visp3/core/vpIoTools.h>
43 #include <visp3/core/vpImageTools.h>
44 #include <visp3/io/vpVideoReader.h>
45 #include <visp3/io/vpParseArgv.h>
46 #include <visp3/gui/vpDisplayX.h>
47 #include <visp3/gui/vpDisplayGDI.h>
48 #include <visp3/gui/vpDisplayOpenCV.h>
50 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x040000)
51 # include <opencv2/imgproc.hpp>
55 #define GETOPTARGS "cdi:th"
59 void usage(
const char *name,
const char *badparam, std::string ipath)
62 Test vpImageTools::templateMatching().\n\
65 %s [-i <VISP_IMAGES directory>] \n\
72 -i <VISP_IMAGES directory> %s\n\
73 Set VISP_IMAGES input path.\n\
74 Setting the VISP_INPUT_IMAGE_PATH environment\n\
75 variable produces the same behaviour than using\n\
81 Perform template matching on cube sequence.\n\
83 Print the help.\n\n", ipath.c_str());
86 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
89 bool getOptions(
int argc,
const char **argv, std::string &ipath,
bool &click,
90 bool &doTemplateMatching)
101 usage(argv[0], NULL, ipath);
105 doTemplateMatching =
true;
115 usage(argv[0], optarg_, ipath);
121 if ((c == 1) || (c == -1)) {
123 usage(argv[0], NULL, ipath);
124 std::cerr <<
"ERROR: " << std::endl;
125 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
133 int main(
int argc,
const char **argv)
135 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000)
137 const int h = 5, w = 5;
139 I[0][0] = 1; I[0][1] = 2; I[0][2] = 2; I[0][3] = 4; I[0][4] = 1;
140 I[1][0] = 3; I[1][1] = 4; I[1][2] = 1; I[1][3] = 5; I[1][4] = 2;
141 I[2][0] = 2; I[2][1] = 3; I[2][2] = 3; I[2][3] = 2; I[2][4] = 4;
142 I[3][0] = 4; I[3][1] = 1; I[3][2] = 5; I[3][3] = 4; I[3][4] = 6;
143 I[4][0] = 6; I[4][1] = 3; I[4][2] = 2; I[4][3] = 1; I[4][4] = 3;
147 std::cout <<
"I:\n" << I << std::endl;
148 std::cout <<
"II:\n" << II << std::endl;
149 std::cout <<
"IIsq:\n" << IIsq << std::endl;
151 cv::Mat mat(h, w, CV_64F);
152 for (
int i = 0; i < h; i++) {
153 for (
int j = 0; j < w; j++) {
154 mat.at<
double>(i,j) = I[i][j];
159 cv::integral(mat, sum, sqsum);
160 std::cout <<
"mat:\n" << mat << std::endl;
161 std::cout <<
"sum:\n" << sum << std::endl;
162 std::cout <<
"sqsum:\n" << sqsum << std::endl;
164 for (
int i = 0; i < h; i++) {
165 for (
int j = 0; j < w; j++) {
166 if ( !
vpMath::equal(II[i][j], sum.at<
double>(i,j), std::numeric_limits<double>::epsilon()) ) {
167 std::cerr <<
"Error vpImageTools::integralImage(II), reference: " << std::setprecision(17)
168 << sum.at<
double>(i,j) <<
" ; compute: " << II[i][j] << std::endl;
172 if ( !
vpMath::equal(IIsq[i][j], sqsum.at<
double>(i,j), std::numeric_limits<double>::epsilon()) ) {
173 std::cerr <<
"Error vpImageTools::integralImage(IIsq), reference: " << std::setprecision(17)
174 << sqsum.at<
double>(i,j) <<
" ; compute: " << IIsq[i][j] << std::endl;
183 std::string env_ipath;
184 std::string opt_ipath;
186 std::string filename;
188 bool doTemplateMatching =
false;
195 if (!env_ipath.empty()) {
200 if (!getOptions(argc, argv, opt_ipath, click, doTemplateMatching)) {
205 if (!opt_ipath.empty()) {
211 if (!opt_ipath.empty() && !env_ipath.empty()) {
212 if (ipath != env_ipath) {
213 std::cout << std::endl <<
"WARNING: " << std::endl;
214 std::cout <<
" Since -i <visp image path=" << ipath <<
"> "
215 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
216 <<
" we skip the environment variable." << std::endl;
221 if (opt_ipath.empty() && env_ipath.empty()) {
222 usage(argv[0], NULL, ipath);
223 std::cerr << std::endl <<
"ERROR:" << std::endl;
224 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
225 <<
" environment variable to specify the location of the " << std::endl
226 <<
" image path where test images are located." << std::endl
245 if (doTemplateMatching) {
246 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
248 #if defined(VISP_HAVE_X11)
250 #elif defined(VISP_HAVE_GDI)
252 #elif defined(VISP_HAVE_OPENCV)
256 d.
init(I, 0, 0,
"Image");
259 std::vector<double> benchmark_vec;
261 while (!reader.
end() && !quit) {
266 std::stringstream ss;
272 const unsigned int step_u = 5, step_v = 5;
276 double max_correlation = -1.0;
277 I_score.
getMinMaxLoc(NULL, &max_loc, NULL, &max_correlation);
279 benchmark_vec.push_back(t_proc);
282 ss <<
"Template matching: " << t_proc <<
" ms";
286 ss <<
"Max correlation: " << max_correlation;
310 if (!benchmark_vec.empty()) {
311 std::cout <<
"Processing time, Mean: " <<
vpMath::getMean(benchmark_vec) <<
" ms ; Median: "
319 const unsigned int step_u = 5, step_v = 5;
330 std::cout <<
"Template matching: " << t <<
" ms" << std::endl;
331 std::cout <<
"Template matching (gold): " << t_gold <<
" ms" << std::endl;
333 for (
unsigned int i = 0; i < I_score.
getHeight(); i++) {
334 for (
unsigned int j = 0; j < I_score.
getWidth(); j++) {
335 if ( !
vpMath::equal(I_score[i][j], I_score_gold[i][j], 1e-9) ) {
336 std::cerr <<
"Issue with template matching, gold: " << std::setprecision(17) << I_score_gold[i][j]
337 <<
" ; compute: " << I_score[i][j] << std::endl;
345 std::cerr <<
"\nCatch an exception: " << e << std::endl;
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emited by ViSP classes.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void getMinMaxLoc(vpImagePoint *minLoc, vpImagePoint *maxLoc, Type *minVal=NULL, Type *maxVal=NULL) const
Get the position of the minimum and/or the maximum pixel value within the bitmap and the correspondin...
unsigned int getWidth() const
unsigned int getHeight() const
static double getMedian(const std::vector< double > &v)
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
static bool equal(double x, double y, double s=0.001)
static double getMean(const std::vector< double > &v)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Defines a rectangle in the plane.
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)
long getFrameIndex() const
VISP_EXPORT double measureTimeMs()