Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
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 TEST_CASE("Benchmark bgr to grayscale (naive code)", "[benchmark]") {
129  vpImage<vpRGBa> I;
130  vpImageIo::read(I, imagePathColor);
131 
132  std::vector<unsigned char> bgr;
133  common_tools::RGBaToBGR(I, bgr);
134 
135  vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
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 
145 TEST_CASE("Benchmark bgr to grayscale (ViSP)", "[benchmark]") {
146  vpImage<vpRGBa> I;
147  vpImageIo::read(I, imagePathColor);
148 
149  std::vector<unsigned char> bgr;
150  common_tools::RGBaToBGR(I, bgr);
151 
152  vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
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;
166  vpImageConvert::convert(I, 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)
177 TEST_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 
188 TEST_CASE("Benchmark bgr to rgba (naive code)", "[benchmark]") {
189  vpImage<vpRGBa> I;
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 
203 TEST_CASE("Benchmark bgr to rgba (ViSP)", "[benchmark]") {
204  vpImage<vpRGBa> I;
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;
233  vpImageConvert::convert(I, 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 
243 TEST_CASE("Benchmark bgra to rgba (naive code)", "[benchmark]") {
244  vpImage<vpRGBa> I;
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 
258 TEST_CASE("Benchmark bgra to rgba (ViSP)", "[benchmark]") {
259  vpImage<vpRGBa> I;
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 
284 int 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 
316  vpImage<unsigned char> I_gray;
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 
334 int main()
335 {
336  return 0;
337 }
338 #endif
static void BGRToRGBa(unsigned char *bgr, 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
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
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:1670
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)
unsigned int getHeight() const
Definition: vpImage.h:188
unsigned int getSize() const
Definition: vpImage.h:227
unsigned int getWidth() const
Definition: vpImage.h:246