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