Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
perfColorConversion.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Benchmark color image conversion.
32 */
33
37#include <visp3/core/vpConfig.h>
38
39#if defined(VISP_HAVE_CATCH2) && defined(VISP_HAVE_THREADS)
40
41#include <catch_amalgamated.hpp>
42
43#include "common.hpp"
44#include <thread>
45#include <visp3/core/vpIoTools.h>
46#include <visp3/io/vpImageIo.h>
47
48#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_IMGPROC)
49#include <opencv2/imgcodecs.hpp>
50#include <opencv2/imgproc/imgproc.hpp>
51#endif
52
53#ifdef ENABLE_VISP_NAMESPACE
54using namespace VISP_NAMESPACE_NAME;
55#endif
56VP_ATTRIBUTE_NO_DESTROY static std::string ipath = vpIoTools::getViSPImagesDataPath();
57VP_ATTRIBUTE_NO_DESTROY static std::string imagePathColor = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
58VP_ATTRIBUTE_NO_DESTROY static std::string imagePathGray = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
59static int nThreads = 0;
60
61TEST_CASE("Benchmark rgba to grayscale (naive code)", "[benchmark]")
62{
64 vpImageIo::read(I, imagePathColor);
65
66 vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
67
68 BENCHMARK("Benchmark rgba to grayscale (naive code)")
69 {
70 common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(I.bitmap), I_gray.bitmap, I.getSize());
71 return I_gray;
72 };
73}
74
75TEST_CASE("Benchmark rgba to grayscale (ViSP)", "[benchmark]")
76{
78 vpImageIo::read(I, imagePathColor);
79
80 vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
81
82 BENCHMARK("Benchmark rgba to grayscale (ViSP)")
83 {
84 vpImageConvert::convert(I, I_gray, nThreads);
85 return I_gray;
86 };
87}
88
89TEST_CASE("Benchmark grayscale to rgba (naive code)", "[benchmark]")
90{
92 vpImageIo::read(I, imagePathGray);
93
94 vpImage<vpRGBa> I_color(I.getHeight(), I.getWidth());
95
96 BENCHMARK("Benchmark grayscale to rgba (naive code)")
97 {
98 common_tools::grayToRGBaRef(I.bitmap, reinterpret_cast<unsigned char *>(I_color.bitmap), I.getSize());
99 return I_color;
100 };
101}
102
103TEST_CASE("Benchmark grayscale to rgba (ViSP)", "[benchmark]")
104{
106 vpImageIo::read(I, imagePathGray);
107
108 vpImage<vpRGBa> I_color(I.getHeight(), I.getWidth());
109
110 BENCHMARK("Benchmark grayscale to rgba (ViSP)")
111 {
112 vpImageConvert::convert(I, I_color);
113 return I_color;
114 };
115}
116
117TEST_CASE("Benchmark split RGBa (ViSP)", "[benchmark]")
118{
120 vpImageIo::read(I, imagePathColor);
121
122 vpImage<unsigned char> R, G, B, A;
123 BENCHMARK("Benchmark split RGBa (ViSP)")
124 {
125 vpImageConvert::split(I, &R, &G, &B, &A);
126 return R;
127 };
128}
129
130TEST_CASE("Benchmark merge to RGBa (ViSP)", "[benchmark]")
131{
133 vpImageIo::read(I, imagePathColor);
134
135 vpImage<unsigned char> R, G, B, A;
136 vpImageConvert::split(I, &R, &G, &B, &A);
137
138 vpImage<vpRGBa> I_merge(I.getHeight(), I.getWidth());
139 BENCHMARK("Benchmark merge to RGBa (ViSP)")
140 {
141 vpImageConvert::merge(&R, &G, &B, &A, I_merge);
142 return I_merge;
143 };
144}
145
146TEST_CASE("Benchmark bgr to grayscale (naive code)", "[benchmark]")
147{
149 vpImageIo::read(I, imagePathColor);
150
151 std::vector<unsigned char> bgr;
152 common_tools::RGBaToBGR(I, bgr);
153
154 vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
155
156 BENCHMARK("Benchmark bgr to grayscale (naive code)")
157 {
158 common_tools::BGRToGrayRef(bgr.data(), reinterpret_cast<unsigned char *>(I_gray.bitmap), I_gray.getWidth(),
159 I_gray.getHeight(), false);
160 return I_gray;
161 };
162}
163
164TEST_CASE("Benchmark bgr to grayscale (ViSP)", "[benchmark]")
165{
167 vpImageIo::read(I, imagePathColor);
168
169 std::vector<unsigned char> bgr;
170 common_tools::RGBaToBGR(I, bgr);
171
172 vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
173
174 BENCHMARK("Benchmark bgr to grayscale (ViSP)")
175 {
176 vpImageConvert::BGRToGrey(bgr.data(), I_gray.bitmap, I.getWidth(), I.getHeight(), false, nThreads);
177 return I_gray;
178 };
179
180#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
181
182 SECTION("OpenCV Mat type")
183 {
184 cv::Mat img;
186
187 BENCHMARK("Benchmark bgr to grayscale (ViSP + OpenCV Mat type)")
188 {
189 vpImageConvert::convert(img, I_gray, false, nThreads);
190 return I_gray;
191 };
192 }
193#endif
194}
195
196#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS) && defined(HAVE_OPENCV_IMGPROC)
197TEST_CASE("Benchmark bgr to grayscale (OpenCV)", "[benchmark]")
198{
199 cv::Mat img = cv::imread(imagePathColor);
200 cv::Mat img_gray(img.size(), CV_8UC1);
201
202 BENCHMARK("Benchmark bgr to grayscale (OpenCV)")
203 {
204 cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
205 return img_gray;
206 };
207}
208#endif
209
210TEST_CASE("Benchmark bgr to rgba (naive code)", "[benchmark]")
211{
213 vpImageIo::read(I, imagePathColor);
214
215 std::vector<unsigned char> bgr;
216 common_tools::RGBaToBGR(I, bgr);
217
218 vpImage<vpRGBa> I_bench(I.getHeight(), I.getWidth());
219 BENCHMARK("Benchmark bgr to rgba (naive code)")
220 {
221 common_tools::BGRToRGBaRef(bgr.data(), reinterpret_cast<unsigned char *>(I_bench.bitmap), I.getWidth(),
222 I.getHeight(), false);
223 return I_bench;
224 };
225}
226
227TEST_CASE("Benchmark bgr to rgba (ViSP)", "[benchmark]")
228{
230 vpImageIo::read(I, imagePathColor);
231
232 std::vector<unsigned char> bgr;
233 common_tools::RGBaToBGR(I, bgr);
234
235 SECTION("Check BGR to RGBa conversion")
236 {
237 vpImage<vpRGBa> ref(I.getHeight(), I.getWidth());
238 common_tools::BGRToRGBaRef(bgr.data(), reinterpret_cast<unsigned char *>(ref.bitmap), I.getWidth(), I.getHeight(),
239 false);
240 vpImage<vpRGBa> rgba(I.getHeight(), I.getWidth());
241 vpImageConvert::BGRToRGBa(bgr.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), I.getWidth(), I.getHeight(),
242 false);
243
244 CHECK((rgba == ref));
245 }
246
247 vpImage<vpRGBa> I_rgba(I.getHeight(), I.getWidth());
248 BENCHMARK("Benchmark bgr to rgba (ViSP)")
249 {
250 vpImageConvert::BGRToRGBa(bgr.data(), reinterpret_cast<unsigned char *>(I_rgba.bitmap), I.getWidth(), I.getHeight(),
251 false);
252 return I_rgba;
253 };
254
255#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC)
256 SECTION("OpenCV Mat type")
257 {
258 cv::Mat img;
260
261 BENCHMARK("Benchmark bgr to rgba (ViSP + OpenCV Mat type)")
262 {
263 vpImageConvert::convert(img, I_rgba);
264 return I_rgba;
265 };
266 }
267#endif
268}
269
270TEST_CASE("Benchmark bgra to rgba (naive code)", "[benchmark]")
271{
273 vpImageIo::read(I, imagePathColor);
274
275 std::vector<unsigned char> bgra;
276 common_tools::RGBaToBGRa(I, bgra);
277
278 vpImage<vpRGBa> I_bench(I.getHeight(), I.getWidth());
279 BENCHMARK("Benchmark bgra to rgba (naive code)")
280 {
281 common_tools::BGRaToRGBaRef(bgra.data(), reinterpret_cast<unsigned char *>(I_bench.bitmap), I.getWidth(),
282 I.getHeight(), false);
283 return I_bench;
284 };
285}
286
287TEST_CASE("Benchmark bgra to rgba (ViSP)", "[benchmark]")
288{
290 vpImageIo::read(I, imagePathColor);
291
292 std::vector<unsigned char> bgra;
293 common_tools::RGBaToBGRa(I, bgra);
294
295 SECTION("Check BGRa to RGBa conversion")
296 {
297 vpImage<vpRGBa> ref(I.getHeight(), I.getWidth());
298 common_tools::BGRaToRGBaRef(bgra.data(), reinterpret_cast<unsigned char *>(ref.bitmap), I.getWidth(), I.getHeight(),
299 false);
300 vpImage<vpRGBa> rgba(I.getHeight(), I.getWidth());
301 vpImageConvert::BGRaToRGBa(bgra.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), I.getWidth(), I.getHeight(),
302 false);
303
304 CHECK((rgba == ref));
305 }
306 vpImage<vpRGBa> I_rgba(I.getHeight(), I.getWidth());
307 BENCHMARK("Benchmark bgra to rgba (ViSP)")
308 {
309 vpImageConvert::BGRaToRGBa(bgra.data(), reinterpret_cast<unsigned char *>(I_rgba.bitmap), I.getWidth(),
310 I.getHeight(), false);
311 return I_rgba;
312 };
313}
314
315int main(int argc, char *argv[])
316{
317 Catch::Session session;
318
319 bool runBenchmark = false;
320 auto cli = session.cli()
321 | Catch::Clara::Opt(runBenchmark)["--benchmark"]("run benchmark?")
322 | Catch::Clara::Opt(imagePathColor, "imagePathColor")["--imagePathColor"]("Path to color image")
323 | Catch::Clara::Opt(imagePathGray, "imagePathColor")["--imagePathGray"]("Path to gray image")
324 | Catch::Clara::Opt(nThreads, "nThreads")["--nThreads"]("Number of threads");
325
326 session.cli(cli);
327
328 session.applyCommandLine(argc, argv);
329
330 if (runBenchmark) {
331 vpImage<vpRGBa> I_color;
332 vpImageIo::read(I_color, imagePathColor);
333 std::cout << "imagePathColor:\n\t" << imagePathColor << "\n\t" << I_color.getWidth() << "x" << I_color.getHeight()
334 << std::endl;
335
337 vpImageIo::read(I_gray, imagePathGray);
338 std::cout << "imagePathGray:\n\t" << imagePathGray << "\n\t" << I_gray.getWidth() << "x" << I_gray.getHeight()
339 << std::endl;
340 std::cout << "nThreads: " << nThreads << " / available threads: " << std::thread::hardware_concurrency()
341 << std::endl;
342
343 int numFailed = session.run();
344
345 return numFailed;
346 }
347
348 return EXIT_SUCCESS;
349}
350#else
351#include <iostream>
352
353int main() { return EXIT_SUCCESS; }
354#endif
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 split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=nullptr)
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:131
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:181
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)