Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
testImageFilter.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Test some functions from vpImageFilter class.
33  *
34  *****************************************************************************/
41 #include <iostream>
42 #include <visp3/core/vpImageConvert.h>
43 #include <visp3/core/vpImageFilter.h>
44 #include <visp3/core/vpIoTools.h>
45 #include <visp3/io/vpImageIo.h>
46 #include <visp3/io/vpParseArgv.h>
47 
48 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
49 #include <opencv2/imgproc/imgproc.hpp>
50 #endif
51 
52 // List of allowed command line options
53 #define GETOPTARGS "cdi:p:h"
54 
55 namespace
56 {
57 /*
58  Print the program options.
59 
60  \param name : Program name.
61  \param badparam : Bad parameter name.
62  \param ipath: Input image path.
63  */
64 void usage(const char *name, const char *badparam, std::string ipath)
65 {
66  fprintf(stdout, "\n\
67  Test vpImageFilter class.\n\
68  \n\
69  SYNOPSIS\n\
70  %s [-i <input image path>] [-p <personal image path>]\n\
71  [-h]\n \
72  ", name);
73 
74  fprintf(stdout, "\n\
75  OPTIONS: Default\n\
76  -i <input image path> %s\n\
77  Set image input path.\n\
78  From this path read \"Klimt/Klimt.pgm,\n\
79  .ppm, .jpeg and .png images.\n\
80  Setting the VISP_INPUT_IMAGE_PATH environment\n\
81  variable produces the same behaviour than using\n\
82  this option.\n\
83  \n\
84  -p <personal image path> \n\
85  Path to an image used to test image reading function.\n\
86  Example: -p /my_path_to/image.png\n\
87  \n\
88  -h\n\
89  Print the help.\n\n", ipath.c_str());
90 
91  if (badparam)
92  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
93 }
94 
104 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath)
105 {
106  const char *optarg_;
107  int c;
108  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
109 
110  switch (c) {
111  case 'i':
112  ipath = optarg_;
113  break;
114  case 'p':
115  ppath = optarg_;
116  break;
117  case 'h':
118  usage(argv[0], NULL, ipath);
119  return false;
120  break;
121 
122  case 'c':
123  case 'd':
124  break;
125 
126  default:
127  usage(argv[0], optarg_, ipath);
128  return false;
129  break;
130  }
131  }
132 
133  if ((c == 1) || (c == -1)) {
134  // standalone param or error
135  usage(argv[0], NULL, ipath);
136  std::cerr << "ERROR: " << std::endl;
137  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
138  return false;
139  }
140 
141  return true;
142 }
143 
144 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
145 bool check_results(const cv::Mat &mat, const vpImage<double> &I, const unsigned int half_size_y,
146  const unsigned int half_size_x)
147 {
148  for (unsigned int i = half_size_y; i < I.getHeight() - half_size_y; i++) {
149  for (unsigned int j = half_size_x; j < I.getWidth() - half_size_x; j++) {
150  if (!vpMath::equal(mat.at<double>((int)i, (int)j), I[i][j], std::numeric_limits<double>::epsilon())) {
151  return false;
152  }
153  }
154  }
155 
156  return true;
157 }
158 #endif
159 }
160 
161 int main(int argc, const char *argv[])
162 {
163  try {
164  std::string env_ipath;
165  std::string opt_ipath;
166  std::string opt_ppath;
167  std::string ipath;
168  std::string filename;
169 
170  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
171  // environment variable value
172  env_ipath = vpIoTools::getViSPImagesDataPath();
173 
174  // Set the default input path
175  if (!env_ipath.empty())
176  ipath = env_ipath;
177 
178  // Read the command line options
179  if (getOptions(argc, argv, opt_ipath, opt_ppath) == false) {
180  exit(EXIT_FAILURE);
181  }
182 
183  // Get the option values
184  if (!opt_ipath.empty())
185  ipath = opt_ipath;
186 
187  // Compare ipath and env_ipath. If they differ, we take into account
188  // the input path comming from the command line option
189  if (!opt_ipath.empty() && !env_ipath.empty()) {
190  if (ipath != env_ipath) {
191  std::cout << std::endl << "WARNING: " << std::endl;
192  std::cout << " Since -i <visp image path=" << ipath << "> "
193  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
194  << " we skip the environment variable." << std::endl;
195  }
196  }
197 
198  //
199  // Here starts really the test
200  //
201 
202  // Test on small images first
203  vpImage<unsigned char> I(6, 6);
204  for (unsigned int i = 0; i < I.getSize(); i++) {
205  I.bitmap[i] = (unsigned char)i;
206  }
207  std::cout << "I:\n" << I << std::endl;
208 
209  vpMatrix kernel_1(2, 2);
210  for (unsigned int i = 0, cpt = 1; i < kernel_1.getRows(); i++) {
211  for (unsigned int j = 0; j < kernel_1.getCols(); j++, cpt++) {
212  kernel_1[i][j] = cpt;
213  }
214  }
215  std::cout << "kernel_1:\n" << kernel_1 << std::endl;
216 
217  vpMatrix kernel_2(3, 3);
218  for (unsigned int i = 0, cpt = 1; i < kernel_2.getRows(); i++) {
219  for (unsigned int j = 0; j < kernel_2.getCols(); j++, cpt++) {
220  kernel_2[i][j] = cpt;
221  }
222  }
223  std::cout << "kernel_2:\n" << kernel_2 << std::endl;
224 
225  vpMatrix kernel_3(2, 3);
226  for (unsigned int i = 0, cpt = 1; i < kernel_3.getRows(); i++) {
227  for (unsigned int j = 0; j < kernel_3.getCols(); j++, cpt++) {
228  kernel_3[i][j] = cpt;
229  }
230  }
231  std::cout << "kernel_3:\n" << kernel_3 << std::endl;
232 
233  // Test correlation
234  vpImage<double> I_correlation_1, I_correlation_2, I_correlation_3;
235  vpImageFilter::filter(I, I_correlation_1, kernel_1);
236  vpImageFilter::filter(I, I_correlation_2, kernel_2);
237  vpImageFilter::filter(I, I_correlation_3, kernel_3);
238 
239  std::cout << "\nI_correlation_1:\n" << I_correlation_1 << std::endl;
240  std::cout << "I_correlation_2:\n" << I_correlation_2 << std::endl;
241  std::cout << "I_correlation_3:\n" << I_correlation_3 << std::endl;
242 
243 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
244  cv::Mat matImg;
245  vpImageConvert::convert(I, matImg);
246 
247  cv::Mat mat_kernel_1(2, 2, CV_64F);
248  for (int i = 0, cpt = 1; i < mat_kernel_1.rows; i++) {
249  for (int j = 0; j < mat_kernel_1.cols; j++, cpt++) {
250  mat_kernel_1.at<double>(i, j) = cpt;
251  }
252  }
253 
254  cv::Mat mat_kernel_2(3, 3, CV_64F);
255  for (int i = 0, cpt = 1; i < mat_kernel_2.rows; i++) {
256  for (int j = 0; j < mat_kernel_2.cols; j++, cpt++) {
257  mat_kernel_2.at<double>(i, j) = cpt;
258  }
259  }
260 
261  cv::Mat mat_kernel_3(2, 3, CV_64F);
262  for (int i = 0, cpt = 1; i < mat_kernel_3.rows; i++) {
263  for (int j = 0; j < mat_kernel_3.cols; j++, cpt++) {
264  mat_kernel_3.at<double>(i, j) = cpt;
265  }
266  }
267 
268  cv::Mat matImg_correlation_1, matImg_correlation_2, matImg_correlation_3;
269  cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
270  cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
271  cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
272 
273  std::cout << "\nTest correlation on small image:" << std::endl;
274  std::cout << "(I_correlation_1 == matImg_correlation_1)? "
275  << check_results(matImg_correlation_1, I_correlation_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2)
276  << std::endl;
277  std::cout << "(I_correlation_2 == matImg_correlation_2)? "
278  << check_results(matImg_correlation_2, I_correlation_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2)
279  << std::endl;
280  std::cout << "(I_correlation_3 == matImg_correlation_3)? "
281  << check_results(matImg_correlation_3, I_correlation_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2)
282  << std::endl;
283 #endif
284 
285  // Test convolution
286  vpImage<double> I_convolution_1, I_convolution_2, I_convolution_3;
287  vpImageFilter::filter(I, I_convolution_1, kernel_1, true);
288  vpImageFilter::filter(I, I_convolution_2, kernel_2, true);
289  vpImageFilter::filter(I, I_convolution_3, kernel_3, true);
290 
291  std::cout << "\nI_convolution_1:\n" << I_convolution_1 << std::endl;
292  std::cout << "I_convolution_2:\n" << I_convolution_2 << std::endl;
293  std::cout << "I_convolution_3:\n" << I_convolution_3 << std::endl;
294 
295 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
296  cv::Mat mat_kernel_1_flip, mat_kernel_2_flip, mat_kernel_3_flip;
297  cv::flip(mat_kernel_1, mat_kernel_1_flip, -1);
298  cv::flip(mat_kernel_2, mat_kernel_2_flip, -1);
299  cv::flip(mat_kernel_3, mat_kernel_3_flip, -1);
300 
301  cv::Mat matImg_convolution_1, matImg_convolution_2, matImg_convolution_3;
302 
303  cv::Point anchor1(mat_kernel_1_flip.cols - mat_kernel_1_flip.cols / 2 - 1,
304  mat_kernel_1_flip.rows - mat_kernel_1_flip.rows / 2 - 1);
305  cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
306 
307  cv::Point anchor2(mat_kernel_2_flip.cols - mat_kernel_2_flip.cols / 2 - 1,
308  mat_kernel_2_flip.rows - mat_kernel_2_flip.rows / 2 - 1);
309  cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
310 
311  cv::Point anchor3(mat_kernel_3_flip.cols - mat_kernel_3_flip.cols / 2 - 1,
312  mat_kernel_3_flip.rows - mat_kernel_3_flip.rows / 2 - 1);
313  cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
314 
315  std::cout << "\nTest convolution on small image:" << std::endl;
316  std::cout << "(I_convolution_1 == matImg_convolution_1)? "
317  << check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2)
318  << std::endl;
319  std::cout << "(I_convolution_2 == matImg_convolution_2)? "
320  << check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2)
321  << std::endl;
322  std::cout << "(I_convolution_3 == matImg_convolution_3)? "
323  << check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2)
324  << std::endl;
325 #endif
326 
327  // Test on real image
328  if (opt_ppath.empty()) {
329  filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
330  vpImageIo::read(I, filename);
331  } else {
332  filename = opt_ppath;
333  vpImageIo::read(I, filename);
334  printf("Image \"%s\" read successfully\n", filename.c_str());
335  }
336 
337  // Test correlation
338  double t = vpTime::measureTimeMs();
339  vpImageFilter::filter(I, I_correlation_1, kernel_1);
340  vpImageFilter::filter(I, I_correlation_2, kernel_2);
341  vpImageFilter::filter(I, I_correlation_3, kernel_3);
342  t = vpTime::measureTimeMs() - t;
343  std::cout << "\nTime to do 3 correlation filtering: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
344 
345 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
346  vpImageConvert::convert(I, matImg);
347 
348  t = vpTime::measureTimeMs();
349  cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
350  cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
351  cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
352  t = vpTime::measureTimeMs() - t;
353  std::cout << "Time to do 3 cv::filter2D: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
354 
355  std::cout << "\nTest correlation on Klimt image:" << std::endl;
356  bool test = check_results(matImg_correlation_1, I_correlation_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2);
357  std::cout << "(I_correlation_1 == matImg_correlation_1)? " << test << std::endl;
358  if (!test) {
359  std::cerr << "Failed test1 correlation with vpImageFilter::filter()!" << std::endl;
360  return EXIT_FAILURE;
361  }
362 
363  test = check_results(matImg_correlation_2, I_correlation_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2);
364  std::cout << "(I_correlation_2 == matImg_correlation_2)? " << test << std::endl;
365  if (!test) {
366  std::cerr << "Failed test2 correlation with vpImageFilter::filter()!" << std::endl;
367  return EXIT_FAILURE;
368  }
369 
370  test = check_results(matImg_correlation_3, I_correlation_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2);
371  std::cout << "(I_correlation_3 == matImg_correlation_3)? " << test << std::endl;
372  if (!test) {
373  std::cerr << "Failed test3 correlation with vpImageFilter::filter()!" << std::endl;
374  return EXIT_FAILURE;
375  }
376 #endif
377 
378  // Test convolution
379  t = vpTime::measureTimeMs();
380  vpImageFilter::filter(I, I_convolution_1, kernel_1, true);
381  vpImageFilter::filter(I, I_convolution_2, kernel_2, true);
382  vpImageFilter::filter(I, I_convolution_3, kernel_3, true);
383  t = vpTime::measureTimeMs() - t;
384  std::cout << "\nTime to do 3 convolution filtering: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
385 
386 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
387 
388  t = vpTime::measureTimeMs();
389  cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
390  cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
391  cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
392  t = vpTime::measureTimeMs() - t;
393  std::cout << "Time to do 3 cv::filter2D: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
394 
395  std::cout << "\nTest convolution on Klimt image:" << std::endl;
396  test = check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2);
397  std::cout << "(I_convolution_1 == matImg_convolution_1)? " << test << std::endl;
398  if (!test) {
399  std::cerr << "Failed test1 convolution with vpImageFilter::filter()!" << std::endl;
400  return EXIT_FAILURE;
401  }
402 
403  test = check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2);
404  std::cout << "(I_convolution_2 == matImg_convolution_2)? " << test << std::endl;
405  if (!test) {
406  std::cerr << "Failed test2 convolution with vpImageFilter::filter()!" << std::endl;
407  return EXIT_FAILURE;
408  }
409 
410  test = check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2);
411  std::cout << "(I_convolution_3 == matImg_convolution_3)? " << test << std::endl;
412  if (!test) {
413  std::cerr << "Failed test3 convolution with vpImageFilter::filter()!" << std::endl;
414  return EXIT_FAILURE;
415  }
416 #endif
417 
418  // Test Sobel
419  vpMatrix kernel_sobel_x_flip(5, 5);
420  vpImageFilter::getSobelKernelX(kernel_sobel_x_flip.data, 2);
421  vpMatrix kernel_sobel_x(5, 5);
422  for (unsigned int i = 0; i < kernel_sobel_x.getRows(); i++) {
423  for (unsigned int j = 0; j < kernel_sobel_x.getCols(); j++) {
424  kernel_sobel_x[i][j] = kernel_sobel_x_flip[i][kernel_sobel_x.getCols()-1-j];
425  }
426  }
427 
428  vpImage<double> I_sobel_x;
429  t = vpTime::measureTimeMs();
430  vpImageFilter::filter(I, I_sobel_x, kernel_sobel_x, true);
431  t = vpTime::measureTimeMs() - t;
432  std::cout << "\nTime to do Sobel: " << t << " ms" << std::endl;
433 
434 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
435  cv::Mat matImg_sobel_x;
436  t = vpTime::measureTimeMs();
437  cv::Sobel(matImg, matImg_sobel_x, CV_64F, 1, 0, 5);
438  t = vpTime::measureTimeMs() - t;
439  std::cout << "Time to do cv::Sobel: " << t << " ms" << std::endl;
440 
441  std::cout << "\nTest Sobel on Klimt image:" << std::endl;
442  std::cout << "(I_sobel_x == matImg_sobel_x)? "
443  << check_results(matImg_sobel_x, I_sobel_x, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
444  << std::endl;
445 #endif
446 
447  vpImage<double> I_double, Iu, Iv;
448  vpImageConvert::convert(I, I_double);
449  t = vpTime::measureTimeMs();
450  vpImageFilter::filter(I_double, Iu, Iv, kernel_sobel_x, true);
451  t = vpTime::measureTimeMs() - t;
452  std::cout << "\nTime to do Sobel Iu and Iv: " << t << " ms" << std::endl;
453 
454 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
455  cv::Mat matImg_sobel_y;
456  cv::Sobel(matImg, matImg_sobel_y, CV_64F, 0, 1, 5);
457 
458  std::cout << "(Iu == matImg_sobel_x)? "
459  << check_results(matImg_sobel_x, Iu, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
460  << std::endl;
461  std::cout << "(Iv == matImg_sobel_y)? "
462  << check_results(matImg_sobel_y, Iv, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
463  << std::endl;
464 #endif
465 
466  // Test Sobel separable filters
467  vpImage<double> I_sep_filtered;
468  vpColVector kernel_sep_x(5);
469  kernel_sep_x[0] = 1.0;
470  kernel_sep_x[1] = 2.0;
471  kernel_sep_x[2] = 0.0;
472  kernel_sep_x[3] = -2.0;
473  kernel_sep_x[4] = -1.0;
474  vpColVector kernel_sep_y(5);
475  kernel_sep_y[0] = 1.0;
476  kernel_sep_y[1] = 4.0;
477  kernel_sep_y[2] = 6.0;
478  kernel_sep_y[3] = 4.0;
479  kernel_sep_y[4] = 1.0;
480 
481  t = vpTime::measureTimeMs();
482  vpImageFilter::sepFilter(I, I_sep_filtered, kernel_sep_x, kernel_sep_y);
483  t = vpTime::measureTimeMs() - t;
484  std::cout << "\nTime to do sepFilter: " << t << " ms" << std::endl;
485 
486 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408)
487  test = check_results(matImg_sobel_x, Iu, I_sep_filtered.getRows() / 2, kernel_sobel_x.getCols() / 2);
488  std::cout << "(I_sep_filtered == matImg_sobel_x)? " << test << std::endl;
489 
490  if (!test) {
491  std::cerr << "Failed separable filter!" << std::endl;
492  return EXIT_FAILURE;
493  }
494 #endif
495  } catch (const vpException &e) {
496  std::cerr << "Catch an exception: " << e.what() << std::endl;
497  return EXIT_FAILURE;
498  }
499 
500  std::cout << "\ntestImageFilter is ok." << std::endl;
501  return EXIT_SUCCESS;
502 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1316
unsigned int getWidth() const
Definition: vpImage.h:239
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void sepFilter(const vpImage< unsigned char > &I, vpImage< double > &If, const vpColVector &kernelH, const vpColVector &kernelV)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:133
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:290
error that can be emited by ViSP classes.
Definition: vpException.h:71
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:88
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
const char * what() const
unsigned int getRows() const
Definition: vpImage.h:211
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1541
unsigned int getSize() const
Definition: vpImage.h:219
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:207
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
unsigned int getHeight() const
Definition: vpImage.h:178
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M, const bool convolve=false)
static double getSobelKernelX(double *filter, unsigned int size)