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