Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
perfImageMorphology.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  * Benchmark image morphology.
32  */
33 
38 #include <visp3/core/vpConfig.h>
39 
40 #ifdef VISP_HAVE_CATCH2
41 #define CATCH_CONFIG_ENABLE_BENCHMARKING
42 #define CATCH_CONFIG_RUNNER
43 #include <catch.hpp>
44 
45 #include "common.hpp"
46 #include <visp3/core/vpImageMorphology.h>
47 #include <visp3/core/vpImageTools.h>
48 #include <visp3/core/vpIoTools.h>
49 #include <visp3/io/vpImageIo.h>
50 
51 #ifdef ENABLE_VISP_NAMESPACE
52 using namespace VISP_NAMESPACE_NAME;
53 #endif
54 static std::string ipath = vpIoTools::getViSPImagesDataPath();
55 
56 TEST_CASE("Benchmark binary image morphology", "[benchmark]")
57 {
58  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
60  vpImageIo::read(I, imagePath);
61 
62  vpImage<unsigned char> I_Klimt_binarized = I;
63  vpImageTools::binarise(I_Klimt_binarized, (unsigned char)127, (unsigned char)127, (unsigned char)0, (unsigned char)1,
64  (unsigned char)1, true);
65 
66  SECTION("Dilatation")
67  {
68  SECTION("4-connexity")
69  {
71  BENCHMARK("Benchmark dilatation (naive code)")
72  {
73  common_tools::imageDilatationRef(I_Klimt_binarized, connexity);
74  return I_Klimt_binarized;
75  };
76 
77  BENCHMARK("Benchmark dilatation (ViSP)")
78  {
79  vpImageMorphology::dilatation(I_Klimt_binarized, (unsigned char)1, (unsigned char)0, connexity);
80  return I_Klimt_binarized;
81  };
82  }
83 
84  SECTION("8-connexity")
85  {
87  BENCHMARK("Benchmark dilatation (naive code)")
88  {
89  common_tools::imageDilatationRef(I_Klimt_binarized, connexity);
90  return I_Klimt_binarized;
91  };
92 
93  BENCHMARK("Benchmark dilatation (ViSP)")
94  {
95  vpImageMorphology::dilatation(I_Klimt_binarized, (unsigned char)1, (unsigned char)0, connexity);
96  return I_Klimt_binarized;
97  };
98  }
99  }
100 
101  SECTION("Erosion")
102  {
103  SECTION("4-connexity")
104  {
106  BENCHMARK("Benchmark erosion (naive code)")
107  {
108  common_tools::imageErosionRef(I_Klimt_binarized, connexity);
109  return I_Klimt_binarized;
110  };
111 
112  BENCHMARK("Benchmark erosion (ViSP)")
113  {
114  vpImageMorphology::erosion(I_Klimt_binarized, (unsigned char)1, (unsigned char)0, connexity);
115  return I_Klimt_binarized;
116  };
117  }
118 
119  SECTION("8-connexity")
120  {
122  BENCHMARK("Benchmark erosion (naive code)")
123  {
124  common_tools::imageErosionRef(I_Klimt_binarized, connexity);
125  return I_Klimt_binarized;
126  };
127 
128  BENCHMARK("Benchmark erosion (ViSP)")
129  {
130  vpImageMorphology::erosion(I_Klimt_binarized, (unsigned char)1, (unsigned char)0, connexity);
131  return I_Klimt_binarized;
132  };
133  }
134  }
135 }
136 
137 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
138 TEST_CASE("Benchmark gray image morphology", "[benchmark]")
139 {
140  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
142  vpImageIo::read(I, imagePath);
143 
144  cv::Mat img, imgMorph;
145  vpImageConvert::convert(I, img);
146  vpImageConvert::convert(I, imgMorph);
147  cv::Mat cross_SE = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
148  cv::Mat rect_SE = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
149 
150  SECTION("Dilatation")
151  {
152  SECTION("4-connexity")
153  {
155  BENCHMARK("Benchmark dilatation (naive code)")
156  {
157  common_tools::imageDilatationRef(I, connexity);
158  return I;
159  };
160 
161  BENCHMARK("Benchmark dilatation (ViSP)")
162  {
163  vpImageMorphology::dilatation<unsigned char>(I, connexity);
164  return I;
165  };
166 
167  BENCHMARK("Benchmark dilatation (OpenCV)")
168  {
169  cv::morphologyEx(imgMorph, imgMorph, cv::MORPH_DILATE, cross_SE);
170  return I;
171  };
172  }
173 
174  SECTION("8-connexity")
175  {
177  BENCHMARK("Benchmark dilatation (naive code)")
178  {
179  common_tools::imageDilatationRef(I, connexity);
180  return I;
181  };
182 
183  BENCHMARK("Benchmark dilatation (ViSP)")
184  {
185  vpImageMorphology::dilatation<unsigned char>(I, connexity);
186  return I;
187  };
188 
189  BENCHMARK("Benchmark dilatation (OpenCV)")
190  {
191  cv::morphologyEx(imgMorph, imgMorph, cv::MORPH_DILATE, rect_SE);
192  return I;
193  };
194  }
195  }
196 
197  SECTION("Erosion")
198  {
199  SECTION("4-connexity")
200  {
202  BENCHMARK("Benchmark erosion (naive code)")
203  {
204  common_tools::imageErosionRef(I, connexity);
205  return I;
206  };
207 
208  BENCHMARK("Benchmark erosion (ViSP)")
209  {
210  vpImageMorphology::erosion<unsigned char>(I, connexity);
211  return I;
212  };
213 
214  BENCHMARK("Benchmark dilatation (OpenCV)")
215  {
216  cv::morphologyEx(imgMorph, imgMorph, cv::MORPH_ERODE, cross_SE);
217  return I;
218  };
219  }
220 
221  SECTION("8-connexity")
222  {
224  BENCHMARK("Benchmark erosion (naive code)")
225  {
226  common_tools::imageErosionRef(I, connexity);
227  return I;
228  };
229 
230  BENCHMARK("Benchmark erosion (ViSP)")
231  {
232  vpImageMorphology::erosion<unsigned char>(I, connexity);
233  return I;
234  };
235 
236  BENCHMARK("Benchmark dilatation (OpenCV)")
237  {
238  cv::morphologyEx(imgMorph, imgMorph, cv::MORPH_ERODE, rect_SE);
239  return I;
240  };
241  }
242  }
243 }
244 #endif
245 
246 int main(int argc, char *argv[])
247 {
248  Catch::Session session; // There must be exactly one instance
249 
250  bool runBenchmark = false;
251  // Build a new parser on top of Catch's
252  using namespace Catch::clara;
253  auto cli = session.cli() // Get Catch's composite command line parser
254  | Opt(runBenchmark) // bind variable to a new option, with a hint string
255  ["--benchmark"] // the option names it will respond to
256  ("run benchmark?"); // description string for the help output
257 
258  // Now pass the new composite back to Catch so it uses that
259  session.cli(cli);
260 
261  // Let Catch (using Clara) parse the command line
262  session.applyCommandLine(argc, argv);
263 
264  if (runBenchmark) {
265  int numFailed = session.run();
266 
267  // numFailed is clamped to 255 as some unices only use the lower 8 bits.
268  // This clamping has already been applied, so just return it here
269  // You can also do any post run clean-up here
270  return numFailed;
271  }
272 
273  return EXIT_SUCCESS;
274 }
275 #else
276 #include <iostream>
277 
278 int main() { return EXIT_SUCCESS; }
279 #endif
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 dilatation(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
static void erosion(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
static void binarise(vpImage< Type > &I, Type threshold1, Type threshold2, Type value1, Type value2, Type value3, bool useLUT=true)
Definition: vpImageTools.h:473
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427