Visual Servoing Platform  version 3.6.1 under development (2024-10-02)
testGaussianFilter.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 Gaussian filter.
32  */
33 
40 #include <visp3/core/vpConfig.h>
41 
42 #if defined(VISP_HAVE_SIMDLIB) && defined(VISP_HAVE_CATCH2) && (VISP_HAVE_DATASET_VERSION >= 0x030400)
43 #define CATCH_CONFIG_RUNNER
44 #include <catch.hpp>
45 #include <visp3/core/vpGaussianFilter.h>
46 #include <visp3/core/vpImageTools.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/io/vpImageIo.h>
49 
50 #ifdef ENABLE_VISP_NAMESPACE
51 using namespace VISP_NAMESPACE_NAME;
52 #endif
53 
54 TEST_CASE("Test vpGaussianFilter (unsigned char)")
55 {
56  const std::string filepath = vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Klimt/Klimt.pgm");
58  vpImageIo::read(I, filepath);
59 
60  std::vector<float> sigmas = { 0.5f, 2.0f, 5.0f, 7.0f };
61  for (auto sigma : sigmas) {
62  vpGaussianFilter gaussianFilter(I.getWidth(), I.getHeight(), sigma);
63 
64  vpImage<unsigned char> I_blurred;
65  gaussianFilter.apply(I, I_blurred);
66 
67  vpImage<unsigned char> I_blurred_ref;
68  const std::string filepath_ref = vpIoTools::createFilePath(
69  vpIoTools::getViSPImagesDataPath(), "Gaussian-filter/Klimt_gray_Gaussian_blur_sigma=%.1f.png");
70  char buffer[FILENAME_MAX];
71  snprintf(buffer, FILENAME_MAX, filepath_ref.c_str(), sigma);
72  const std::string filename = buffer;
73  vpImageIo::read(I_blurred_ref, filename);
74 
76  vpImageTools::imageDifferenceAbsolute(I_blurred, I_blurred_ref, I_diff);
77  vpImage<double> I_diff_dbl;
78  vpImageConvert::convert(I_diff, I_diff_dbl);
79  std::cout << "sigma: " << sigma << " ; I_diff_dbl: " << I_diff_dbl.getMeanValue() << std::endl;
80  const double threshold = 1.5;
81  CHECK(I_diff_dbl.getMeanValue() < threshold);
82  }
83 }
84 
85 TEST_CASE("Test vpGaussianFilter (vpRGBa)")
86 {
87  const std::string filepath = vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Klimt/Klimt.ppm");
89  vpImageIo::read(I, filepath);
90 
91  std::vector<float> sigmas = { 0.5f, 2.0f, 5.0f, 7.0f };
92  for (auto sigma : sigmas) {
93  vpGaussianFilter gaussianFilter(I.getWidth(), I.getHeight(), sigma);
94 
95  vpImage<vpRGBa> I_blurred;
96  gaussianFilter.apply(I, I_blurred);
97 
98  vpImage<vpRGBa> I_blurred_ref;
99  const std::string filepath_ref = vpIoTools::createFilePath(
100  vpIoTools::getViSPImagesDataPath(), "Gaussian-filter/Klimt_RGB_Gaussian_blur_sigma=%.1f.png");
101  char buffer[FILENAME_MAX];
102  snprintf(buffer, FILENAME_MAX, filepath_ref.c_str(), sigma);
103  const std::string filename = buffer;
104  vpImageIo::read(I_blurred_ref, filename);
105 
106  vpImage<vpRGBa> I_diff;
107  vpImageTools::imageDifferenceAbsolute(I_blurred, I_blurred_ref, I_diff);
108  vpImage<unsigned char> I_diff_R, I_diff_G, I_diff_B;
109  vpImageConvert::split(I_diff, &I_diff_R, &I_diff_G, &I_diff_B);
110 
111  vpImage<double> I_diff_R_dbl, I_diff_G_dbl, I_diff_B_dbl;
112  vpImageConvert::convert(I_diff_R, I_diff_R_dbl);
113  vpImageConvert::convert(I_diff_G, I_diff_G_dbl);
114  vpImageConvert::convert(I_diff_B, I_diff_B_dbl);
115 
116  std::cout << "sigma: " << sigma << " ; I_diff_R_dbl: " << I_diff_R_dbl.getMeanValue()
117  << " ; I_diff_G_dbl: " << I_diff_G_dbl.getMeanValue()
118  << " ; I_diff_B_dbl: " << I_diff_B_dbl.getMeanValue() << std::endl;
119  const double threshold = 1.5;
120  CHECK(I_diff_R_dbl.getMeanValue() < threshold);
121  CHECK(I_diff_G_dbl.getMeanValue() < threshold);
122  CHECK(I_diff_B_dbl.getMeanValue() < threshold);
123  }
124 }
125 
126 TEST_CASE("Test vpGaussianFilter (vpRGBa + deinterleave)")
127 {
128  const std::string filepath = vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Klimt/Klimt.ppm");
129  vpImage<vpRGBa> I;
130  vpImageIo::read(I, filepath);
131 
132  std::vector<float> sigmas = { 0.5f, 2.0f, 5.0f, 7.0f };
133  for (auto sigma : sigmas) {
134  const bool deinterleave = true;
135  vpGaussianFilter gaussianFilter(I.getWidth(), I.getHeight(), sigma, deinterleave);
136 
137  vpImage<vpRGBa> I_blurred;
138  gaussianFilter.apply(I, I_blurred);
139 
140  vpImage<vpRGBa> I_blurred_ref;
141  const std::string filepath_ref = vpIoTools::createFilePath(
142  vpIoTools::getViSPImagesDataPath(), "Gaussian-filter/Klimt_RGB_Gaussian_blur_sigma=%.1f.png");
143  char buffer[FILENAME_MAX];
144  snprintf(buffer, FILENAME_MAX, filepath_ref.c_str(), sigma);
145  const std::string filename = buffer;
146  vpImageIo::read(I_blurred_ref, filename);
147 
148  vpImage<vpRGBa> I_diff;
149  vpImageTools::imageDifferenceAbsolute(I_blurred, I_blurred_ref, I_diff);
150  vpImage<unsigned char> I_diff_R, I_diff_G, I_diff_B;
151  vpImageConvert::split(I_diff, &I_diff_R, &I_diff_G, &I_diff_B);
152 
153  vpImage<double> I_diff_R_dbl, I_diff_G_dbl, I_diff_B_dbl;
154  vpImageConvert::convert(I_diff_R, I_diff_R_dbl);
155  vpImageConvert::convert(I_diff_G, I_diff_G_dbl);
156  vpImageConvert::convert(I_diff_B, I_diff_B_dbl);
157 
158  std::cout << "sigma: " << sigma << " ; I_diff_R_dbl: " << I_diff_R_dbl.getMeanValue()
159  << " ; I_diff_G_dbl: " << I_diff_G_dbl.getMeanValue()
160  << " ; I_diff_B_dbl: " << I_diff_B_dbl.getMeanValue() << std::endl;
161  const double threshold = 1.5;
162  CHECK(I_diff_R_dbl.getMeanValue() < threshold);
163  CHECK(I_diff_G_dbl.getMeanValue() < threshold);
164  CHECK(I_diff_B_dbl.getMeanValue() < threshold);
165  }
166 }
167 
168 int main(int argc, char *argv[])
169 {
170  Catch::Session session; // There must be exactly one instance
171 
172  // Let Catch (using Clara) parse the command line
173  session.applyCommandLine(argc, argv);
174 
175  int numFailed = session.run();
176 
177  // numFailed is clamped to 255 as some unices only use the lower 8 bits.
178  // This clamping has already been applied, so just return it here
179  // You can also do any post run clean-up here
180  return numFailed;
181 }
182 #else
183 int main() { return EXIT_SUCCESS; }
184 #endif
Gaussian filter class.
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=nullptr)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:147
static void imageDifferenceAbsolute(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Idiff)
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getHeight() const
Definition: vpImage.h:181
double getMeanValue(const vpImage< bool > *p_mask=nullptr, unsigned int *nbValidPoints=nullptr) const
Return the mean value of the bitmap.
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427