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