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
49 static std::string ipath = vpIoTools::getViSPImagesDataPath();
50
51 TEST_CASE("Benchmark binary image morphology", "[benchmark]") {
52 std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
53 vpImage<unsigned char> I;
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 {
64 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_4;
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 {
78 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_8;
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 {
95 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_4;
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 {
109 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_8;
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)
124 TEST_CASE("Benchmark gray image morphology", "[benchmark]") {
125 std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
126 vpImage<unsigned char> I;
127 vpImageIo::read(I, imagePath);
128
129 cv::Mat img, imgMorph;
130 vpImageConvert::convert(I, img);
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 {
139 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_4;
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 {
158 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_8;
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 {
180 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_4;
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 {
199 const vpImageMorphology::vpConnexityType connexity = vpImageMorphology::CONNEXITY_8;
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
main(int argc,char * argv[])219 int 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
main()251 int main()
252 {
253 return 0;
254 }
255 #endif
256