Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testImageFilter.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Test some functions from vpImageFilter class.
32 */
33
39
40#include <iostream>
41#include <visp3/core/vpImageConvert.h>
42#include <visp3/core/vpImageFilter.h>
43#include <visp3/core/vpIoTools.h>
44#include <visp3/core/vpMath.h>
45#include <visp3/core/vpRGBa.h>
46#include <visp3/io/vpImageIo.h>
47#include <visp3/io/vpParseArgv.h>
48
49// List of allowed command line options
50#define GETOPTARGS "cdi:p:h"
51
52#ifdef ENABLE_VISP_NAMESPACE
53using namespace VISP_NAMESPACE_NAME;
54#endif
55
56namespace
57{
58/*
59 Print the program options.
60
61 \param name : Program name.
62 \param badparam : Bad parameter name.
63 \param ipath : Input image path.
64 */
65void usage(const char *name, const char *badparam, std::string ipath)
66{
67 fprintf(stdout, "\n\
68 Test vpImageFilter class.\n\
69 \n\
70 SYNOPSIS\n\
71 %s [-i <input image path>] [-p <personal image path>]\n\
72 [-h]\n \
73 ",
74 name);
75
76 fprintf(stdout, "\n\
77 OPTIONS: Default\n\
78 -i <input image path> %s\n\
79 Set image input path.\n\
80 From this path read \"Klimt/Klimt.pgm,\n\
81 .ppm, .jpeg and .png images.\n\
82 Setting the VISP_INPUT_IMAGE_PATH environment\n\
83 variable produces the same behaviour than using\n\
84 this option.\n\
85 \n\
86 -p <personal image path> \n\
87 Path to an image used to test image reading function.\n\
88 Example: -p /my_path_to/image.png\n\
89 \n\
90 -h\n\
91 Print the help.\n\n",
92 ipath.c_str());
93
94 if (badparam)
95 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
96}
97
107bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath)
108{
109 const char *optarg_;
110 int c;
111 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
112
113 switch (c) {
114 case 'i':
115 ipath = optarg_;
116 break;
117 case 'p':
118 ppath = optarg_;
119 break;
120 case 'h':
121 usage(argv[0], nullptr, ipath);
122 return false;
123
124 case 'c':
125 case 'd':
126 break;
127
128 default:
129 usage(argv[0], optarg_, ipath);
130 return false;
131 }
132 }
133
134 if ((c == 1) || (c == -1)) {
135 // standalone param or error
136 usage(argv[0], nullptr, ipath);
137 std::cerr << "ERROR: " << std::endl;
138 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
139 return false;
140 }
141
142 return true;
143}
144
145#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
146bool check_results(const cv::Mat &mat, const vpImage<double> &I, unsigned int half_size_y, 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>(static_cast<int>(i), static_cast<int>(j)), I[i][j],
151 std::numeric_limits<double>::epsilon())) {
152 return false;
153 }
154 }
155 }
156
157 return true;
158}
159
160bool check_results(const cv::Mat &mat, const vpImage<double> &I, unsigned int margin, double threshold)
161{
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)) {
165 return false;
166 }
167 }
168 }
169
170 return true;
171}
172
173bool check_results(const cv::Mat &mat, const vpImage<vpRGBa> &I, unsigned int margin, double threshold)
174{
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,
178 threshold)) {
179 return false;
180 }
181 if (!vpMath::equal(static_cast<double>(mat.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j))[1]), I[i][j].G,
182 threshold)) {
183 return false;
184 }
185 if (!vpMath::equal(static_cast<double>(mat.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j))[0]), I[i][j].B,
186 threshold)) {
187 return false;
188 }
189 }
190 }
191
192 return true;
193}
194#endif
195} // namespace
196
197int main(int argc, const char *argv[])
198{
199 try {
200 std::string env_ipath;
201 std::string opt_ipath;
202 std::string opt_ppath;
203 std::string ipath;
204 std::string filename;
205
206 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
207 // environment variable value
209
210 // Set the default input path
211 if (!env_ipath.empty())
212 ipath = env_ipath;
213
214 // Read the command line options
215 if (getOptions(argc, argv, opt_ipath, opt_ppath) == false) {
216 exit(EXIT_FAILURE);
217 }
218
219 // Get the option values
220 if (!opt_ipath.empty())
221 ipath = opt_ipath;
222
223 // Compare ipath and env_ipath. If they differ, we take into account
224 // the input path coming from the command line option
225 if (!opt_ipath.empty() && !env_ipath.empty()) {
226 if (ipath != env_ipath) {
227 std::cout << std::endl << "WARNING: " << std::endl;
228 std::cout << " Since -i <visp image path=" << ipath << "> "
229 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
230 << " we skip the environment variable." << std::endl;
231 }
232 }
233
234 //
235 // Here starts really the test
236 //
237 vpMatrix kernel_1(2, 2);
238 for (unsigned int i = 0, cpt = 1; i < kernel_1.getRows(); i++) {
239 for (unsigned int j = 0; j < kernel_1.getCols(); j++, cpt++) {
240 kernel_1[i][j] = cpt;
241 }
242 }
243 std::cout << "kernel_1:\n" << kernel_1 << std::endl;
244
245 vpMatrix kernel_2(3, 3);
246 for (unsigned int i = 0, cpt = 1; i < kernel_2.getRows(); i++) {
247 for (unsigned int j = 0; j < kernel_2.getCols(); j++, cpt++) {
248 kernel_2[i][j] = cpt;
249 }
250 }
251 std::cout << "kernel_2:\n" << kernel_2 << std::endl;
252
253 vpMatrix kernel_3(2, 3);
254 for (unsigned int i = 0, cpt = 1; i < kernel_3.getRows(); i++) {
255 for (unsigned int j = 0; j < kernel_3.getCols(); j++, cpt++) {
256 kernel_3[i][j] = cpt;
257 }
258 }
259 std::cout << "kernel_3:\n" << kernel_3 << std::endl;
260
261 {
262 // Test on small images first
264 for (unsigned int i = 0; i < I.getSize(); i++) {
265 I.bitmap[i] = (unsigned char)i;
266 }
267 std::cout << "I:\n" << I << std::endl;
268
269 // Test correlation
270 vpImage<double> I_correlation_1, I_correlation_2, I_correlation_3;
271 vpImageFilter::filter(I, I_correlation_1, kernel_1);
272 vpImageFilter::filter(I, I_correlation_2, kernel_2);
273 vpImageFilter::filter(I, I_correlation_3, kernel_3);
274
275 std::cout << "\nI_correlation_1:\n" << I_correlation_1 << std::endl;
276 std::cout << "I_correlation_2:\n" << I_correlation_2 << std::endl;
277 std::cout << "I_correlation_3:\n" << I_correlation_3 << std::endl;
278
279#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
280 cv::Mat matImg;
281 vpImageConvert::convert(I, matImg);
282
283 cv::Mat mat_kernel_1(2, 2, CV_64F);
284 for (int i = 0, cpt = 1; i < mat_kernel_1.rows; i++) {
285 for (int j = 0; j < mat_kernel_1.cols; j++, cpt++) {
286 mat_kernel_1.at<double>(i, j) = cpt;
287 }
288 }
289
290 cv::Mat mat_kernel_2(3, 3, CV_64F);
291 for (int i = 0, cpt = 1; i < mat_kernel_2.rows; i++) {
292 for (int j = 0; j < mat_kernel_2.cols; j++, cpt++) {
293 mat_kernel_2.at<double>(i, j) = cpt;
294 }
295 }
296
297 cv::Mat mat_kernel_3(2, 3, CV_64F);
298 for (int i = 0, cpt = 1; i < mat_kernel_3.rows; i++) {
299 for (int j = 0; j < mat_kernel_3.cols; j++, cpt++) {
300 mat_kernel_3.at<double>(i, j) = cpt;
301 }
302 }
303
304 cv::Mat matImg_correlation_1, matImg_correlation_2, matImg_correlation_3;
305 cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
306 cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
307 cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
308
309 std::cout << "\nTest correlation on small image:" << std::endl;
310 std::cout << "(I_correlation_1 == matImg_correlation_1)? "
311 << check_results(matImg_correlation_1, I_correlation_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2)
312 << std::endl;
313 std::cout << "(I_correlation_2 == matImg_correlation_2)? "
314 << check_results(matImg_correlation_2, I_correlation_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2)
315 << std::endl;
316 std::cout << "(I_correlation_3 == matImg_correlation_3)? "
317 << check_results(matImg_correlation_3, I_correlation_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2)
318 << std::endl;
319#endif
320
321 // Test convolution
322 vpImage<double> I_convolution_1, I_convolution_2, I_convolution_3;
323 vpImageFilter::filter(I, I_convolution_1, kernel_1, true);
324 vpImageFilter::filter(I, I_convolution_2, kernel_2, true);
325 vpImageFilter::filter(I, I_convolution_3, kernel_3, true);
326
327 std::cout << "\nI_convolution_1:\n" << I_convolution_1 << std::endl;
328 std::cout << "I_convolution_2:\n" << I_convolution_2 << std::endl;
329 std::cout << "I_convolution_3:\n" << I_convolution_3 << std::endl;
330
331#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
332 cv::Mat mat_kernel_1_flip, mat_kernel_2_flip, mat_kernel_3_flip;
333 cv::flip(mat_kernel_1, mat_kernel_1_flip, -1);
334 cv::flip(mat_kernel_2, mat_kernel_2_flip, -1);
335 cv::flip(mat_kernel_3, mat_kernel_3_flip, -1);
336
337 cv::Mat matImg_convolution_1, matImg_convolution_2, matImg_convolution_3;
338
339 cv::Point anchor1(mat_kernel_1_flip.cols - mat_kernel_1_flip.cols / 2 - 1,
340 mat_kernel_1_flip.rows - mat_kernel_1_flip.rows / 2 - 1);
341 cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
342
343 cv::Point anchor2(mat_kernel_2_flip.cols - mat_kernel_2_flip.cols / 2 - 1,
344 mat_kernel_2_flip.rows - mat_kernel_2_flip.rows / 2 - 1);
345 cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
346
347 cv::Point anchor3(mat_kernel_3_flip.cols - mat_kernel_3_flip.cols / 2 - 1,
348 mat_kernel_3_flip.rows - mat_kernel_3_flip.rows / 2 - 1);
349 cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
350
351 std::cout << "\nTest convolution on small image:" << std::endl;
352 std::cout << "(I_convolution_1 == matImg_convolution_1)? "
353 << check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2)
354 << std::endl;
355 std::cout << "(I_convolution_2 == matImg_convolution_2)? "
356 << check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2)
357 << std::endl;
358 std::cout << "(I_convolution_3 == matImg_convolution_3)? "
359 << check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2)
360 << std::endl;
361#endif
362 if (opt_ppath.empty()) {
363 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
364 vpImageIo::read(I, filename);
365 }
366 else {
367 filename = opt_ppath;
368 vpImageIo::read(I, filename);
369 printf("Image \"%s\" read successfully\n", filename.c_str());
370 }
371
372 // Test correlation
373 double t = vpTime::measureTimeMs();
374 vpImageFilter::filter(I, I_correlation_1, kernel_1);
375 vpImageFilter::filter(I, I_correlation_2, kernel_2);
376 vpImageFilter::filter(I, I_correlation_3, kernel_3);
378 std::cout << "\nTime to do 3 correlation filtering: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
379
380#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
381 vpImageConvert::convert(I, matImg);
382
384 cv::filter2D(matImg, matImg_correlation_1, CV_64F, mat_kernel_1);
385 cv::filter2D(matImg, matImg_correlation_2, CV_64F, mat_kernel_2);
386 cv::filter2D(matImg, matImg_correlation_3, CV_64F, mat_kernel_3);
388 std::cout << "Time to do 3 cv::filter2D: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
389
390 std::cout << "\nTest correlation on Klimt image:" << std::endl;
391 bool test = check_results(matImg_correlation_1, I_correlation_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2);
392 std::cout << "(I_correlation_1 == matImg_correlation_1)? " << test << std::endl;
393 if (!test) {
394 std::cerr << "Failed test1 correlation with vpImageFilter::filter()!" << std::endl;
395 return EXIT_FAILURE;
396 }
397
398 test = check_results(matImg_correlation_2, I_correlation_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2);
399 std::cout << "(I_correlation_2 == matImg_correlation_2)? " << test << std::endl;
400 if (!test) {
401 std::cerr << "Failed test2 correlation with vpImageFilter::filter()!" << std::endl;
402 return EXIT_FAILURE;
403 }
404
405 test = check_results(matImg_correlation_3, I_correlation_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2);
406 std::cout << "(I_correlation_3 == matImg_correlation_3)? " << test << std::endl;
407 if (!test) {
408 std::cerr << "Failed test3 correlation with vpImageFilter::filter()!" << std::endl;
409 return EXIT_FAILURE;
410 }
411#endif
412
413 // Test convolution
415 vpImageFilter::filter(I, I_convolution_1, kernel_1, true);
416 vpImageFilter::filter(I, I_convolution_2, kernel_2, true);
417 vpImageFilter::filter(I, I_convolution_3, kernel_3, true);
419 std::cout << "\nTime to do 3 convolution filtering: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
420
421#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
422
424 cv::filter2D(matImg, matImg_convolution_1, CV_64F, mat_kernel_1_flip, anchor1);
425 cv::filter2D(matImg, matImg_convolution_2, CV_64F, mat_kernel_2_flip, anchor2);
426 cv::filter2D(matImg, matImg_convolution_3, CV_64F, mat_kernel_3_flip, anchor3);
428 std::cout << "Time to do 3 cv::filter2D: " << t << " ms ; Mean: " << t / 3.0 << " ms" << std::endl;
429
430 std::cout << "\nTest convolution on Klimt image:" << std::endl;
431 test = check_results(matImg_convolution_1, I_convolution_1, kernel_1.getRows() / 2, kernel_1.getCols() / 2);
432 std::cout << "(I_convolution_1 == matImg_convolution_1)? " << test << std::endl;
433 if (!test) {
434 std::cerr << "Failed test1 convolution with vpImageFilter::filter()!" << std::endl;
435 return EXIT_FAILURE;
436 }
437
438 test = check_results(matImg_convolution_2, I_convolution_2, kernel_2.getRows() / 2, kernel_2.getCols() / 2);
439 std::cout << "(I_convolution_2 == matImg_convolution_2)? " << test << std::endl;
440 if (!test) {
441 std::cerr << "Failed test2 convolution with vpImageFilter::filter()!" << std::endl;
442 return EXIT_FAILURE;
443 }
444
445 test = check_results(matImg_convolution_3, I_convolution_3, kernel_3.getRows() / 2, kernel_3.getCols() / 2);
446 std::cout << "(I_convolution_3 == matImg_convolution_3)? " << test << std::endl;
447 if (!test) {
448 std::cerr << "Failed test3 convolution with vpImageFilter::filter()!" << std::endl;
449 return EXIT_FAILURE;
450 }
451#endif
452
453 // Test Sobel
454 vpMatrix kernel_sobel_x_flip(5, 5);
455 vpImageFilter::getSobelKernelX(kernel_sobel_x_flip.data, 2);
456 vpMatrix kernel_sobel_x(5, 5);
457 for (unsigned int i = 0; i < kernel_sobel_x.getRows(); i++) {
458 for (unsigned int j = 0; j < kernel_sobel_x.getCols(); j++) {
459 kernel_sobel_x[i][j] = kernel_sobel_x_flip[i][kernel_sobel_x.getCols() - 1 - j];
460 }
461 }
462
463 vpImage<double> I_sobel_x;
465 vpImageFilter::filter(I, I_sobel_x, kernel_sobel_x, true);
467 std::cout << "\nTime to do Sobel: " << t << " ms" << std::endl;
468
469#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
470 cv::Mat matImg_sobel_x;
472 cv::Sobel(matImg, matImg_sobel_x, CV_64F, 1, 0, 5);
474 std::cout << "Time to do cv::Sobel: " << t << " ms" << std::endl;
475
476 std::cout << "\nTest Sobel on Klimt image:" << std::endl;
477 std::cout << "(I_sobel_x == matImg_sobel_x)? "
478 << check_results(matImg_sobel_x, I_sobel_x, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
479 << std::endl;
480#endif
481
482 vpImage<double> I_double, Iu, Iv;
483 vpImageConvert::convert(I, I_double);
485 vpImageFilter::filter(I_double, Iu, Iv, kernel_sobel_x, true);
487 std::cout << "\nTime to do Sobel Iu and Iv: " << t << " ms" << std::endl;
488
489#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
490 cv::Mat matImg_sobel_y;
491 cv::Sobel(matImg, matImg_sobel_y, CV_64F, 0, 1, 5);
492
493 std::cout << "(Iu == matImg_sobel_x)? "
494 << check_results(matImg_sobel_x, Iu, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
495 << std::endl;
496 std::cout << "(Iv == matImg_sobel_y)? "
497 << check_results(matImg_sobel_y, Iv, kernel_sobel_x.getRows() / 2, kernel_sobel_x.getCols() / 2)
498 << std::endl;
499#endif
500
501 // Test Sobel separable filters
502 vpImage<double> I_sep_filtered;
503 vpColVector kernel_sep_x(5);
504 kernel_sep_x[0] = 1.0;
505 kernel_sep_x[1] = 2.0;
506 kernel_sep_x[2] = 0.0;
507 kernel_sep_x[3] = -2.0;
508 kernel_sep_x[4] = -1.0;
509 vpColVector kernel_sep_y(5);
510 kernel_sep_y[0] = 1.0;
511 kernel_sep_y[1] = 4.0;
512 kernel_sep_y[2] = 6.0;
513 kernel_sep_y[3] = 4.0;
514 kernel_sep_y[4] = 1.0;
515
517 vpImageFilter::sepFilter(I, I_sep_filtered, kernel_sep_x, kernel_sep_y);
519 std::cout << "\nTime to do sepFilter: " << t << " ms" << std::endl;
520
521#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
522 test = check_results(matImg_sobel_x, Iu, I_sep_filtered.getRows() / 2, kernel_sobel_x.getCols() / 2);
523 std::cout << "(I_sep_filtered == matImg_sobel_x)? " << test << std::endl;
524
525 if (!test) {
526 std::cerr << "Failed separable filter!" << std::endl;
527 return EXIT_FAILURE;
528 }
529
530 // Test median filter on gray-scale image
531 std::cout << "\nTest median on grayscale image:" << std::endl;
532 vpImage<unsigned char> I_median(3, 3);
533 for (unsigned int r = 0; r < 3; r++) {
534 for (unsigned int c = 0; c < 3; c++) {
535 I_median[r][c] = r * 3 + c;
536 }
537 }
538 double median = vpImageFilter::median(I_median);
539 double expectedMedian = 4.;
540 test = vpMath::equal(median, expectedMedian);
541 std::cout << "(median (=" << median << ") == expectedMedian(" << expectedMedian << "))? " << test << std::endl;
542
543 if (!test) {
544 std::cerr << "Failed median filter on gray-scale image!" << std::endl;
545 return EXIT_FAILURE;
546 }
547
548 std::cout << "\nTest median on vpRGBa image:" << std::endl;
549 vpImage<vpRGBa> I_median_rgba(3, 3);
550 for (unsigned int r = 0; r < 3; r++) {
551 for (unsigned int c = 0; c < 3; c++) {
552 I_median_rgba[r][c].R = r * 3 + c;
553 I_median_rgba[r][c].G = 2 * (r * 3 + c);
554 I_median_rgba[r][c].B = 3 * (r * 3 + c);
555 }
556 }
557 std::vector<float> median_rgba = vpImageFilter::median(I_median_rgba);
558 std::vector<float> expected_median_rgba = { 4.f, 8.f, 12.f };
559 for (unsigned int i = 0; i < 3; i++) {
560 bool test_local = vpMath::equal(median_rgba[i], expected_median_rgba[i]);
561 test &= test_local;
562 std::cout << "(median_rgba[" << i << "] (=" << median_rgba[i] << ") == expected_median_rgba[" << i << "] ( " << expected_median_rgba[i] << "))? " << test_local << std::endl;
563 }
564 if (!test) {
565 std::cerr << "Failed median filter on vpRGBa image!" << std::endl;
566 return EXIT_FAILURE;
567 }
568#endif
569 }
570 {
571 // Test Gaussian blur on grayscale image
572
573 std::cout << "\nTest Gaussian Blur on Klimt grayscale image:" << std::endl;
575 vpImage<double> I_blur;
576 // Test on real image
577
578 if (opt_ppath.empty()) {
579 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
580 vpImageIo::read(I, filename);
581 }
582 else {
583 filename = opt_ppath;
584 vpImageIo::read(I, filename);
585 printf("Image \"%s\" read successfully\n", filename.c_str());
586 }
587
588 unsigned int gaussian_filter_size = 7;
589 double sigma = 3;
590 double t = vpTime::measureTimeMs();
591 vpImageFilter::gaussianBlur(I, I_blur, gaussian_filter_size, sigma);
593 std::cout << "Time to do ViSP Gaussian Blur on grayscale images: " << t << " ms" << std::endl;
594
595#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
596 cv::Mat matImg, matImg_blur;
597 vpImageConvert::convert(I, matImg);
599 cv::GaussianBlur(matImg, matImg_blur, cv::Size(gaussian_filter_size, gaussian_filter_size), sigma, 0);
601 std::cout << "Time to do OpenCV Gaussian Blur on grayscale images: " << t << " ms" << std::endl;
602
603 double threshold = 3.;
604 unsigned int margin = 3;
605 bool test = check_results(matImg_blur, I_blur, margin, threshold);
606 std::cout << "(I_blur == matImg_blur)? " << test << std::endl;
607
608 if (!test) {
609 std::cerr << "Failed Gaussian blur filter on grayscale image!" << std::endl;
610 return EXIT_FAILURE;
611 }
612#endif
613 }
614
615 {
616 // Test Gaussian blur on color image
617 std::cout << "\nTest Gaussian Blur on Klimt color image:" << std::endl;
618
619 vpImage<vpRGBa> I_rgb, I_rgb_blur;
620 // Test on real image
621
622 if (opt_ppath.empty()) {
623 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
624 vpImageIo::read(I_rgb, filename);
625 }
626 else {
627 filename = opt_ppath;
628 vpImageIo::read(I_rgb, filename);
629 printf("Image \"%s\" read successfully\n", filename.c_str());
630 }
631
632 unsigned int gaussian_filter_size = 7;
633 double sigma = 3;
634 double t = vpTime::measureTimeMs();
635 vpImageFilter::gaussianBlur(I_rgb, I_rgb_blur, gaussian_filter_size, sigma);
637 std::cout << "Time to do ViSP Gaussian Blur on color images: " << t << " ms" << std::endl;
638
639#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
640 cv::Mat matImg_rgb, matImg_rgb_blur;
641 vpImageConvert::convert(I_rgb, matImg_rgb);
643 cv::GaussianBlur(matImg_rgb, matImg_rgb_blur, cv::Size(gaussian_filter_size, gaussian_filter_size), sigma, 0);
645 std::cout << "Time to do OpenCV Gaussian Blur on color images: " << t << " ms" << std::endl;
646
647 double threshold = 3.;
648 unsigned int margin = 3;
649 bool test = check_results(matImg_rgb_blur, I_rgb_blur, margin, threshold);
650 std::cout << "(I_rgb_blur == matImg_rgb_blur)? " << test << std::endl;
651
652 if (!test) {
653 std::cerr << "Failed Gaussian blur filter on color image!" << std::endl;
654 return EXIT_FAILURE;
655 }
656#endif
657 }
658
659 }
660 catch (const vpException &e) {
661 std::cerr << "Catch an exception: " << e.what() << std::endl;
662 return EXIT_FAILURE;
663 }
664
665 std::cout << "\ntestImageFilter is ok." << std::endl;
666 return EXIT_SUCCESS;
667}
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static FilterType getSobelKernelX(FilterType *filter, unsigned int size)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false, const vpImage< bool > *p_mask=nullptr)
static void sepFilter(const vpImage< unsigned char > &I, vpImage< double > &If, const vpColVector &kernelH, const vpColVector &kernelV)
static void gaussianBlur(const vpImage< ImageType > &I, vpImage< OutputType > &GI, unsigned int size=7, FilterType sigma=0., bool normalize=true, const vpImage< bool > *p_mask=nullptr)
static float median(const cv::Mat &cv_I)
Calculates the median value of a single channel. The algorithm is based on based on https://github....
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getRows() const
Definition vpImage.h:212
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()