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