42 #include <visp3/core/vpImageConvert.h> 43 #include <visp3/core/vpImageFilter.h> 44 #include <visp3/core/vpRGBa.h> 45 #include <visp3/core/vpIoTools.h> 46 #include <visp3/io/vpImageIo.h> 47 #include <visp3/io/vpParseArgv.h> 49 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 50 #include <opencv2/imgproc/imgproc.hpp> 54 #define GETOPTARGS "cdi:p:h" 65 void usage(
const char *name,
const char *badparam, std::string ipath)
68 Test vpImageFilter class.\n\ 71 %s [-i <input image path>] [-p <personal image path>]\n\ 77 -i <input image path> %s\n\ 78 Set image input path.\n\ 79 From this path read \"Klimt/Klimt.pgm,\n\ 80 .ppm, .jpeg and .png images.\n\ 81 Setting the VISP_INPUT_IMAGE_PATH environment\n\ 82 variable produces the same behaviour than using\n\ 85 -p <personal image path> \n\ 86 Path to an image used to test image reading function.\n\ 87 Example: -p /my_path_to/image.png\n\ 90 Print the help.\n\n", ipath.c_str());
93 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
105 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &ppath)
119 usage(argv[0], NULL, ipath);
128 usage(argv[0], optarg_, ipath);
134 if ((c == 1) || (c == -1)) {
136 usage(argv[0], NULL, ipath);
137 std::cerr <<
"ERROR: " << std::endl;
138 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
145 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 146 bool check_results(
const cv::Mat &mat,
const vpImage<double> &I,
unsigned int half_size_y,
147 unsigned int half_size_x)
149 for (
unsigned int i = half_size_y; i < I.
getHeight() - half_size_y; i++) {
150 for (
unsigned int j = half_size_x; j < I.
getWidth() - half_size_x; j++) {
151 if (!
vpMath::equal(mat.at<
double>(static_cast<int>(i), static_cast<int>(j)), I[i][j], std::numeric_limits<double>::epsilon())) {
160 bool check_results(
const cv::Mat &mat,
const vpImage<double> &I,
unsigned int margin,
double threshold)
162 for (
unsigned int i = margin; i < I.
getHeight() - margin; i++) {
163 for (
unsigned int j = margin; j < I.
getWidth() - margin; j++) {
164 if (!
vpMath::equal(mat.at<
unsigned char>(static_cast<int>(i), static_cast<int>(j)), I[i][j], threshold)) {
173 bool check_results(
const cv::Mat &mat,
const vpImage<vpRGBa> &I,
unsigned int margin,
double threshold)
175 for (
unsigned int i = margin; i < I.
getHeight() - margin; i++) {
176 for (
unsigned int j = margin; j < I.
getWidth() - margin; j++) {
177 if (!
vpMath::equal(static_cast<double>(mat.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j))[2]), I[i][j].R, threshold)) {
180 if (!
vpMath::equal(static_cast<double>(mat.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j))[1]), I[i][j].G, threshold)) {
183 if (!
vpMath::equal(static_cast<double>(mat.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j))[0]), I[i][j].B, threshold)) {
194 int main(
int argc,
const char *argv[])
197 std::string env_ipath;
198 std::string opt_ipath;
199 std::string opt_ppath;
201 std::string filename;
208 if (!env_ipath.empty())
212 if (getOptions(argc, argv, opt_ipath, opt_ppath) ==
false) {
217 if (!opt_ipath.empty())
222 if (!opt_ipath.empty() && !env_ipath.empty()) {
223 if (ipath != env_ipath) {
224 std::cout << std::endl <<
"WARNING: " << std::endl;
225 std::cout <<
" Since -i <visp image path=" << ipath <<
"> " 226 <<
" is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
227 <<
" we skip the environment variable." << std::endl;
235 for (
unsigned int i = 0, cpt = 1; i < kernel_1.getRows(); i++) {
236 for (
unsigned int j = 0; j < kernel_1.getCols(); j++, cpt++) {
237 kernel_1[i][j] = cpt;
240 std::cout <<
"kernel_1:\n" << kernel_1 << std::endl;
243 for (
unsigned int i = 0, cpt = 1; i < kernel_2.getRows(); i++) {
244 for (
unsigned int j = 0; j < kernel_2.getCols(); j++, cpt++) {
245 kernel_2[i][j] = cpt;
248 std::cout <<
"kernel_2:\n" << kernel_2 << std::endl;
251 for (
unsigned int i = 0, cpt = 1; i < kernel_3.getRows(); i++) {
252 for (
unsigned int j = 0; j < kernel_3.getCols(); j++, cpt++) {
253 kernel_3[i][j] = cpt;
256 std::cout <<
"kernel_3:\n" << kernel_3 << std::endl;
261 for (
unsigned int i = 0; i < I.
getSize(); i++) {
262 I.
bitmap[i] = (
unsigned char)i;
264 std::cout <<
"I:\n" << I << std::endl;
272 std::cout <<
"\nI_correlation_1:\n" << I_correlation_1 << std::endl;
273 std::cout <<
"I_correlation_2:\n" << I_correlation_2 << std::endl;
274 std::cout <<
"I_correlation_3:\n" << I_correlation_3 << std::endl;
276 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 280 cv::Mat mat_kernel_1(2, 2, CV_64F);
281 for (
int i = 0, cpt = 1; i < mat_kernel_1.rows; i++) {
282 for (
int j = 0; j < mat_kernel_1.cols; j++, cpt++) {
283 mat_kernel_1.at<
double>(i, j) = cpt;
287 cv::Mat mat_kernel_2(3, 3, CV_64F);
288 for (
int i = 0, cpt = 1; i < mat_kernel_2.rows; i++) {
289 for (
int j = 0; j < mat_kernel_2.cols; j++, cpt++) {
290 mat_kernel_2.at<
double>(i, j) = cpt;
294 cv::Mat mat_kernel_3(2, 3, CV_64F);
295 for (
int i = 0, cpt = 1; i < mat_kernel_3.rows; i++) {
296 for (
int j = 0; j < mat_kernel_3.cols; j++, cpt++) {
297 mat_kernel_3.at<
double>(i, j) = cpt;
301 cv::Mat matImg_correlation_1, matImg_correlation_2, matImg_correlation_3;
302 cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
303 cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
304 cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
306 std::cout <<
"\nTest correlation on small image:" << std::endl;
307 std::cout <<
"(I_correlation_1 == matImg_correlation_1)? " 308 << check_results(matImg_correlation_1, I_correlation_1, kernel_1.
getRows() / 2, kernel_1.getCols() / 2)
310 std::cout <<
"(I_correlation_2 == matImg_correlation_2)? " 311 << check_results(matImg_correlation_2, I_correlation_2, kernel_2.
getRows() / 2, kernel_2.getCols() / 2)
313 std::cout <<
"(I_correlation_3 == matImg_correlation_3)? " 314 << check_results(matImg_correlation_3, I_correlation_3, kernel_3.
getRows() / 2, kernel_3.getCols() / 2)
324 std::cout <<
"\nI_convolution_1:\n" << I_convolution_1 << std::endl;
325 std::cout <<
"I_convolution_2:\n" << I_convolution_2 << std::endl;
326 std::cout <<
"I_convolution_3:\n" << I_convolution_3 << std::endl;
328 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 329 cv::Mat mat_kernel_1_flip, mat_kernel_2_flip, mat_kernel_3_flip;
330 cv::flip(mat_kernel_1, mat_kernel_1_flip, -1);
331 cv::flip(mat_kernel_2, mat_kernel_2_flip, -1);
332 cv::flip(mat_kernel_3, mat_kernel_3_flip, -1);
334 cv::Mat matImg_convolution_1, matImg_convolution_2, matImg_convolution_3;
336 cv::Point anchor1(mat_kernel_1_flip.cols - mat_kernel_1_flip.cols / 2 - 1,
337 mat_kernel_1_flip.rows - mat_kernel_1_flip.rows / 2 - 1);
338 cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
340 cv::Point anchor2(mat_kernel_2_flip.cols - mat_kernel_2_flip.cols / 2 - 1,
341 mat_kernel_2_flip.rows - mat_kernel_2_flip.rows / 2 - 1);
342 cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
344 cv::Point anchor3(mat_kernel_3_flip.cols - mat_kernel_3_flip.cols / 2 - 1,
345 mat_kernel_3_flip.rows - mat_kernel_3_flip.rows / 2 - 1);
346 cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
348 std::cout <<
"\nTest convolution on small image:" << std::endl;
349 std::cout <<
"(I_convolution_1 == matImg_convolution_1)? " 350 << check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2)
352 std::cout <<
"(I_convolution_2 == matImg_convolution_2)? " 353 << check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2)
355 std::cout <<
"(I_convolution_3 == matImg_convolution_3)? " 356 << check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2)
359 if (opt_ppath.empty()) {
363 filename = opt_ppath;
365 printf(
"Image \"%s\" read successfully\n", filename.c_str());
374 std::cout <<
"\nTime to do 3 correlation filtering: " << t <<
" ms ; Mean: " << t / 3.0 <<
" ms" << std::endl;
376 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 380 cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
381 cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
382 cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
384 std::cout <<
"Time to do 3 cv::filter2D: " << t <<
" ms ; Mean: " << t / 3.0 <<
" ms" << std::endl;
386 std::cout <<
"\nTest correlation on Klimt image:" << std::endl;
387 bool test = check_results(matImg_correlation_1, I_correlation_1, kernel_1.
getRows() / 2, kernel_1.getCols() / 2);
388 std::cout <<
"(I_correlation_1 == matImg_correlation_1)? " << test << std::endl;
390 std::cerr <<
"Failed test1 correlation with vpImageFilter::filter()!" << std::endl;
394 test = check_results(matImg_correlation_2, I_correlation_2, kernel_2.
getRows() / 2, kernel_2.getCols() / 2);
395 std::cout <<
"(I_correlation_2 == matImg_correlation_2)? " << test << std::endl;
397 std::cerr <<
"Failed test2 correlation with vpImageFilter::filter()!" << std::endl;
401 test = check_results(matImg_correlation_3, I_correlation_3, kernel_3.
getRows() / 2, kernel_3.getCols() / 2);
402 std::cout <<
"(I_correlation_3 == matImg_correlation_3)? " << test << std::endl;
404 std::cerr <<
"Failed test3 correlation with vpImageFilter::filter()!" << std::endl;
415 std::cout <<
"\nTime to do 3 convolution filtering: " << t <<
" ms ; Mean: " << t / 3.0 <<
" ms" << std::endl;
417 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 420 cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
421 cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
422 cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
424 std::cout <<
"Time to do 3 cv::filter2D: " << t <<
" ms ; Mean: " << t / 3.0 <<
" ms" << std::endl;
426 std::cout <<
"\nTest convolution on Klimt image:" << std::endl;
427 test = check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2);
428 std::cout <<
"(I_convolution_1 == matImg_convolution_1)? " << test << std::endl;
430 std::cerr <<
"Failed test1 convolution with vpImageFilter::filter()!" << std::endl;
434 test = check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2);
435 std::cout <<
"(I_convolution_2 == matImg_convolution_2)? " << test << std::endl;
437 std::cerr <<
"Failed test2 convolution with vpImageFilter::filter()!" << std::endl;
441 test = check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2);
442 std::cout <<
"(I_convolution_3 == matImg_convolution_3)? " << test << std::endl;
444 std::cerr <<
"Failed test3 convolution with vpImageFilter::filter()!" << std::endl;
453 for (
unsigned int i = 0; i < kernel_sobel_x.getRows(); i++) {
454 for (
unsigned int j = 0; j < kernel_sobel_x.getCols(); j++) {
455 kernel_sobel_x[i][j] = kernel_sobel_x_flip[i][kernel_sobel_x.getCols()-1-j];
463 std::cout <<
"\nTime to do Sobel: " << t <<
" ms" << std::endl;
465 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 466 cv::Mat matImg_sobel_x;
468 cv::Sobel(matImg, matImg_sobel_x, CV_64F, 1, 0, 5);
470 std::cout <<
"Time to do cv::Sobel: " << t <<
" ms" << std::endl;
472 std::cout <<
"\nTest Sobel on Klimt image:" << std::endl;
473 std::cout <<
"(I_sobel_x == matImg_sobel_x)? " 474 << check_results(matImg_sobel_x, I_sobel_x, kernel_sobel_x.
getRows() / 2, kernel_sobel_x.getCols() / 2)
483 std::cout <<
"\nTime to do Sobel Iu and Iv: " << t <<
" ms" << std::endl;
485 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 486 cv::Mat matImg_sobel_y;
487 cv::Sobel(matImg, matImg_sobel_y, CV_64F, 0, 1, 5);
489 std::cout <<
"(Iu == matImg_sobel_x)? " 490 << check_results(matImg_sobel_x, Iu, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
492 std::cout <<
"(Iv == matImg_sobel_y)? " 493 << check_results(matImg_sobel_y, Iv, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
500 kernel_sep_x[0] = 1.0;
501 kernel_sep_x[1] = 2.0;
502 kernel_sep_x[2] = 0.0;
503 kernel_sep_x[3] = -2.0;
504 kernel_sep_x[4] = -1.0;
506 kernel_sep_y[0] = 1.0;
507 kernel_sep_y[1] = 4.0;
508 kernel_sep_y[2] = 6.0;
509 kernel_sep_y[3] = 4.0;
510 kernel_sep_y[4] = 1.0;
515 std::cout <<
"\nTime to do sepFilter: " << t <<
" ms" << std::endl;
517 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 518 test = check_results(matImg_sobel_x, Iu, I_sep_filtered.getRows() / 2, kernel_sobel_x.getCols() / 2);
519 std::cout <<
"(I_sep_filtered == matImg_sobel_x)? " << test << std::endl;
522 std::cerr <<
"Failed separable filter!" << std::endl;
530 std::cout <<
"\nTest Gaussian Blur on Klimt grayscale image:" << std::endl;
535 if (opt_ppath.empty()) {
539 filename = opt_ppath;
541 printf(
"Image \"%s\" read successfully\n", filename.c_str());
544 unsigned int gaussian_filter_size = 7;
549 std::cout <<
"Time to do ViSP Gaussian Blur on grayscale images: " << t <<
" ms" << std::endl;
551 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 552 cv::Mat matImg, matImg_blur;
555 cv::GaussianBlur(matImg, matImg_blur, cv::Size(gaussian_filter_size, gaussian_filter_size), sigma, 0);
557 std::cout <<
"Time to do OpenCV Gaussian Blur on grayscale images: " << t <<
" ms" << std::endl;
559 double threshold = 3.;
560 unsigned int margin = 3;
561 bool test = check_results(matImg_blur, I_blur, margin, threshold);
562 std::cout <<
"(I_blur == matImg_blur)? " << test << std::endl;
565 std::cerr <<
"Failed Gaussian blur filter on grayscale image!" << std::endl;
573 std::cout <<
"\nTest Gaussian Blur on Klimt color image:" << std::endl;
578 if (opt_ppath.empty()) {
582 filename = opt_ppath;
584 printf(
"Image \"%s\" read successfully\n", filename.c_str());
587 unsigned int gaussian_filter_size = 7;
592 std::cout <<
"Time to do ViSP Gaussian Blur on color images: " << t <<
" ms" << std::endl;
594 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020408) 595 cv::Mat matImg_rgb, matImg_rgb_blur;
598 cv::GaussianBlur(matImg_rgb, matImg_rgb_blur, cv::Size(gaussian_filter_size, gaussian_filter_size), sigma, 0);
600 std::cout <<
"Time to do OpenCV Gaussian Blur on color images: " << t <<
" ms" << std::endl;
602 double threshold = 3.;
603 unsigned int margin = 3;
604 bool test = check_results(matImg_rgb_blur, I_rgb_blur, margin, threshold);
605 std::cout <<
"(I_rgb_blur == matImg_rgb_blur)? " << test << std::endl;
608 std::cerr <<
"Failed Gaussian blur filter on color image!" << std::endl;
615 std::cerr <<
"Catch an exception: " << e.
what() << std::endl;
619 std::cout <<
"\ntestImageFilter is ok." << std::endl;
Implementation of a matrix and operations on matrices.
unsigned int getWidth() const
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
static bool equal(double x, double y, double s=0.001)
error that can be emited by ViSP classes.
VISP_EXPORT double measureTimeMs()
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
const char * what() const
unsigned int getRows() const
unsigned int getSize() const
static void gaussianBlur(const vpImage< unsigned char > &I, vpImage< double > &GI, unsigned int size=7, double sigma=0., bool normalize=true)
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M, bool convolve=false)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Implementation of column vector and the associated operations.
unsigned int getHeight() const
static double getSobelKernelX(double *filter, unsigned int size)