Visual Servoing Platform version 3.5.0
perfColorConversion.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 color image conversion.
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 <thread>
44#include <visp3/core/vpIoTools.h>
45#include <visp3/io/vpImageIo.h>
46#include "common.hpp"
47
48static std::string ipath = vpIoTools::getViSPImagesDataPath();
49static std::string imagePathColor = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
50static std::string imagePathGray = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
51static int nThreads = 0;
52
53TEST_CASE("Benchmark rgba to grayscale (naive code)", "[benchmark]") {
55 vpImageIo::read(I, imagePathColor);
56
58
59 BENCHMARK("Benchmark rgba to grayscale (naive code)") {
60 common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(I.bitmap),
61 I_gray.bitmap, I.getSize());
62 return I_gray;
63 };
64}
65
66TEST_CASE("Benchmark rgba to grayscale (ViSP)", "[benchmark]") {
68 vpImageIo::read(I, imagePathColor);
69
71
72 BENCHMARK("Benchmark rgba to grayscale (ViSP)") {
73 vpImageConvert::convert(I, I_gray, nThreads);
74 return I_gray;
75 };
76}
77
78TEST_CASE("Benchmark grayscale to rgba (naive code)", "[benchmark]") {
80 vpImageIo::read(I, imagePathGray);
81
82 vpImage<vpRGBa> I_color(I.getHeight(), I.getWidth());
83
84 BENCHMARK("Benchmark grayscale to rgba (naive code)") {
85 common_tools::grayToRGBaRef(I.bitmap, reinterpret_cast<unsigned char *>(I_color.bitmap),
86 I.getSize());
87 return I_color;
88 };
89}
90
91TEST_CASE("Benchmark grayscale to rgba (ViSP)", "[benchmark]") {
93 vpImageIo::read(I, imagePathGray);
94
95 vpImage<vpRGBa> I_color(I.getHeight(), I.getWidth());
96
97 BENCHMARK("Benchmark grayscale to rgba (ViSP)") {
98 vpImageConvert::convert(I, I_color);
99 return I_color;
100 };
101}
102
103TEST_CASE("Benchmark split RGBa (ViSP)", "[benchmark]") {
105 vpImageIo::read(I, imagePathColor);
106
107 vpImage<unsigned char> R, G, B, A;
108 BENCHMARK("Benchmark split RGBa (ViSP)") {
109 vpImageConvert::split(I, &R, &G, &B, &A);
110 return R;
111 };
112}
113
114TEST_CASE("Benchmark merge to RGBa (ViSP)", "[benchmark]") {
116 vpImageIo::read(I, imagePathColor);
117
118 vpImage<unsigned char> R, G, B, A;
119 vpImageConvert::split(I, &R, &G, &B, &A);
120
121 vpImage<vpRGBa> I_merge(I.getHeight(), I.getWidth());
122 BENCHMARK("Benchmark merge to RGBa (ViSP)") {
123 vpImageConvert::merge(&R, &G, &B, &A, I_merge);
124 return I_merge;
125 };
126}
127
128TEST_CASE("Benchmark bgr to grayscale (naive code)", "[benchmark]") {
130 vpImageIo::read(I, imagePathColor);
131
132 std::vector<unsigned char> bgr;
133 common_tools::RGBaToBGR(I, bgr);
134
136
137 BENCHMARK("Benchmark bgr to grayscale (naive code)") {
138 common_tools::BGRToGrayRef(bgr.data(),
139 reinterpret_cast<unsigned char *>(I_gray.bitmap),
140 I_gray.getWidth(), I_gray.getHeight(), false);
141 return I_gray;
142 };
143}
144
145TEST_CASE("Benchmark bgr to grayscale (ViSP)", "[benchmark]") {
147 vpImageIo::read(I, imagePathColor);
148
149 std::vector<unsigned char> bgr;
150 common_tools::RGBaToBGR(I, bgr);
151
153
154 BENCHMARK("Benchmark bgr to grayscale (ViSP)") {
155 vpImageConvert::BGRToGrey(bgr.data(),
156 I_gray.bitmap,
157 I.getWidth(), I.getHeight(),
158 false, nThreads);
159 return I_gray;
160 };
161
162#if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
163 SECTION("OpenCV Mat type")
164 {
165 cv::Mat img;
167
168 BENCHMARK("Benchmark bgr to grayscale (ViSP + OpenCV Mat type)") {
169 vpImageConvert::convert(img, I_gray, false, nThreads);
170 return I_gray;
171 };
172 }
173#endif
174}
175
176#if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
177TEST_CASE("Benchmark bgr to grayscale (OpenCV)", "[benchmark]") {
178 cv::Mat img = cv::imread(imagePathColor);
179 cv::Mat img_gray(img.size(), CV_8UC1);
180
181 BENCHMARK("Benchmark bgr to grayscale (OpenCV)") {
182 cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
183 return img_gray;
184 };
185}
186#endif
187
188TEST_CASE("Benchmark bgr to rgba (naive code)", "[benchmark]") {
190 vpImageIo::read(I, imagePathColor);
191
192 std::vector<unsigned char> bgr;
193 common_tools::RGBaToBGR(I, bgr);
194
195 vpImage<vpRGBa> I_bench(I.getHeight(), I.getWidth());
196 BENCHMARK("Benchmark bgr to rgba (naive code)") {
197 common_tools::BGRToRGBaRef(bgr.data(), reinterpret_cast<unsigned char*>(I_bench.bitmap),
198 I.getWidth(), I.getHeight(), false);
199 return I_bench;
200 };
201}
202
203TEST_CASE("Benchmark bgr to rgba (ViSP)", "[benchmark]") {
205 vpImageIo::read(I, imagePathColor);
206
207 std::vector<unsigned char> bgr;
208 common_tools::RGBaToBGR(I, bgr);
209
210 SECTION("Check BGR to RGBa conversion")
211 {
212 vpImage<vpRGBa> ref(I.getHeight(), I.getWidth());
213 common_tools::BGRToRGBaRef(bgr.data(), reinterpret_cast<unsigned char*>(ref.bitmap),
214 I.getWidth(), I.getHeight(), false);
215 vpImage<vpRGBa> rgba(I.getHeight(), I.getWidth());
216 vpImageConvert::BGRToRGBa(bgr.data(), reinterpret_cast<unsigned char *>(rgba.bitmap),
217 I.getWidth(), I.getHeight(), false);
218
219 CHECK((rgba == ref));
220 }
221
222 vpImage<vpRGBa> I_rgba(I.getHeight(), I.getWidth());
223 BENCHMARK("Benchmark bgr to rgba (ViSP)") {
224 vpImageConvert::BGRToRGBa(bgr.data(), reinterpret_cast<unsigned char *>(I_rgba.bitmap),
225 I.getWidth(), I.getHeight(), false);
226 return I_rgba;
227 };
228
229#if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
230 SECTION("OpenCV Mat type")
231 {
232 cv::Mat img;
234
235 BENCHMARK("Benchmark bgr to rgba (ViSP + OpenCV Mat type)") {
236 vpImageConvert::convert(img, I_rgba);
237 return I_rgba;
238 };
239 }
240#endif
241}
242
243TEST_CASE("Benchmark bgra to rgba (naive code)", "[benchmark]") {
245 vpImageIo::read(I, imagePathColor);
246
247 std::vector<unsigned char> bgra;
248 common_tools::RGBaToBGRa(I, bgra);
249
250 vpImage<vpRGBa> I_bench(I.getHeight(), I.getWidth());
251 BENCHMARK("Benchmark bgra to rgba (naive code)") {
252 common_tools::BGRaToRGBaRef(bgra.data(), reinterpret_cast<unsigned char*>(I_bench.bitmap),
253 I.getWidth(), I.getHeight(), false);
254 return I_bench;
255 };
256}
257
258TEST_CASE("Benchmark bgra to rgba (ViSP)", "[benchmark]") {
260 vpImageIo::read(I, imagePathColor);
261
262 std::vector<unsigned char> bgra;
263 common_tools::RGBaToBGRa(I, bgra);
264
265 SECTION("Check BGRa to RGBa conversion")
266 {
267 vpImage<vpRGBa> ref(I.getHeight(), I.getWidth());
268 common_tools::BGRaToRGBaRef(bgra.data(), reinterpret_cast<unsigned char*>(ref.bitmap),
269 I.getWidth(), I.getHeight(), false);
270 vpImage<vpRGBa> rgba(I.getHeight(), I.getWidth());
271 vpImageConvert::BGRaToRGBa(bgra.data(), reinterpret_cast<unsigned char *>(rgba.bitmap),
272 I.getWidth(), I.getHeight(), false);
273
274 CHECK((rgba == ref));
275 }
276 vpImage<vpRGBa> I_rgba(I.getHeight(), I.getWidth());
277 BENCHMARK("Benchmark bgra to rgba (ViSP)") {
278 vpImageConvert::BGRaToRGBa(bgra.data(), reinterpret_cast<unsigned char *>(I_rgba.bitmap),
279 I.getWidth(), I.getHeight(), false);
280 return I_rgba;
281 };
282}
283
284int main(int argc, char *argv[])
285{
286 Catch::Session session; // There must be exactly one instance
287
288 bool runBenchmark = false;
289 // Build a new parser on top of Catch's
290 using namespace Catch::clara;
291 auto cli = session.cli() // Get Catch's composite command line parser
292 | Opt(runBenchmark) // bind variable to a new option, with a hint string
293 ["--benchmark"] // the option names it will respond to
294 ("run benchmark?") // description string for the help output
295 | Opt(imagePathColor, "imagePathColor")
296 ["--imagePathColor"]
297 ("Path to color image")
298 | Opt(imagePathGray, "imagePathColor")
299 ["--imagePathGray"]
300 ("Path to gray image")
301 | Opt(nThreads, "nThreads")
302 ["--nThreads"]
303 ("Number of threads");
304
305 // Now pass the new composite back to Catch so it uses that
306 session.cli(cli);
307
308 // Let Catch (using Clara) parse the command line
309 session.applyCommandLine(argc, argv);
310
311 if (runBenchmark) {
312 vpImage<vpRGBa> I_color;
313 vpImageIo::read(I_color, imagePathColor);
314 std::cout << "imagePathColor:\n\t" << imagePathColor << "\n\t" << I_color.getWidth() << "x" << I_color.getHeight() << std::endl;
315
317 vpImageIo::read(I_gray, imagePathGray);
318 std::cout << "imagePathGray:\n\t" << imagePathGray << "\n\t" << I_gray.getWidth() << "x" << I_gray.getHeight() << std::endl;
319 std::cout << "nThreads: " << nThreads << " / available threads: " << std::thread::hardware_concurrency() << std::endl;
320
321 int numFailed = session.run();
322
323 // numFailed is clamped to 255 as some unices only use the lower 8 bits.
324 // This clamping has already been applied, so just return it here
325 // You can also do any post run clean-up here
326 return numFailed;
327 }
328
329 return EXIT_SUCCESS;
330}
331#else
332#include <iostream>
333
334int main()
335{
336 return 0;
337}
338#endif
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:149
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getSize() const
Definition: vpImage.h:227
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
unsigned int getHeight() const
Definition: vpImage.h:188
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670