Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
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 rgba to grayscale 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 <visp3/core/vpIoTools.h>
44 #include <visp3/io/vpImageIo.h>
45 
46 namespace {
47 static std::string ipath = vpIoTools::getViSPImagesDataPath();
48 
49 void computeRegularRGBaToGrayscale(const unsigned char * rgba, unsigned char *grey, unsigned int size)
50 {
51  const unsigned char *pt_input = rgba;
52  const unsigned char *pt_end = rgba + size * 4;
53  unsigned char *pt_output = grey;
54 
55  while (pt_input != pt_end) {
56  *pt_output = (unsigned char)(0.2126 * (*pt_input) + 0.7152 * (*(pt_input + 1)) + 0.0722 * (*(pt_input + 2)));
57  pt_input += 4;
58  pt_output++;
59  }
60 }
61 
62 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
63 void computeRegularBGRToGrayscale(unsigned char *bgr, unsigned char *grey, unsigned int width,
64  unsigned int height, bool flip=false)
65 {
66  // if we have to flip the image, we start from the end last scanline so the
67  // step is negative
68  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
69 
70  // starting source address = last line if we need to flip the image
71  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
72 
73  unsigned int j = 0;
74  unsigned int i = 0;
75 
76  for (i = 0; i < height; i++) {
77  unsigned char *line = src;
78  for (j = 0; j < width; j++) {
79  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
80  line += 3;
81  }
82 
83  // go to the next line
84  src += lineStep;
85  }
86 }
87 #endif
88 }
89 
90 TEST_CASE("Benchmark rgba to grayscale (naive code)", "[benchmark]") {
91  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
93  vpImageIo::read(I, imagePath);
94 
95  vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
96 
97  BENCHMARK("Benchmark rgba to grayscale Klimt (naive code)") {
98  computeRegularRGBaToGrayscale(reinterpret_cast<unsigned char *>(I.bitmap),
99  I_gray.bitmap, I.getSize());
100  return I_gray;
101  };
102 }
103 
104 TEST_CASE("Benchmark rgba to grayscale (ViSP)", "[benchmark]") {
105  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
106  vpImage<vpRGBa> I;
107  vpImageIo::read(I, imagePath);
108 
109  vpImage<unsigned char> I_gray(I.getHeight(), I.getWidth());
110 
111  BENCHMARK("Benchmark rgba to grayscale Klimt (ViSP)") {
112  vpImageConvert::convert(I, I_gray);
113  return I_gray;
114  };
115 }
116 
117 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
118 TEST_CASE("Benchmark bgr to grayscale (naive code)", "[benchmark]") {
119  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
120  cv::Mat img = cv::imread(imagePath);
121 
122  vpImage<unsigned char> I_gray(img.rows, img.cols);
123 
124  BENCHMARK("Benchmark bgr to grayscale (naive code)") {
125  computeRegularBGRToGrayscale(reinterpret_cast<unsigned char*>(img.ptr<uchar>()),
126  reinterpret_cast<unsigned char *>(I_gray.bitmap),
127  I_gray.getWidth(), I_gray.getHeight());
128  return I_gray;
129  };
130 }
131 
132 TEST_CASE("Benchmark bgr to grayscale (ViSP)", "[benchmark]") {
133  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
134  cv::Mat img = cv::imread(imagePath);
135 
136  std::vector<unsigned char> grayscale(img.rows*img.cols);
137 
138  BENCHMARK("Benchmark bgr to grayscale (ViSP)") {
139  vpImageConvert::BGRToGrey(reinterpret_cast<unsigned char *>(img.ptr<uchar>()),
140  grayscale.data(), img.cols, img.rows);
141  return grayscale;
142  };
143 }
144 
145 TEST_CASE("Benchmark bgr to grayscale (OpenCV)", "[benchmark]") {
146  std::string imagePath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
147  cv::Mat img = cv::imread(imagePath);
148  cv::Mat img_gray(img.size(), CV_8UC1);
149 
150  BENCHMARK("Benchmark bgr to grayscale (OpenCV)") {
151  cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
152  return img_gray;
153  };
154 }
155 #endif
156 
157 int main(int argc, char *argv[])
158 {
159  Catch::Session session; // There must be exactly one instance
160 
161  bool runBenchmark = false;
162  // Build a new parser on top of Catch's
163  using namespace Catch::clara;
164  auto cli = session.cli() // Get Catch's composite command line parser
165  | Opt(runBenchmark) // bind variable to a new option, with a hint string
166  ["--benchmark"] // the option names it will respond to
167  ("run benchmark?"); // description string for the help output
168 
169  // Now pass the new composite back to Catch so it uses that
170  session.cli(cli);
171 
172  // Let Catch (using Clara) parse the command line
173  session.applyCommandLine(argc, argv);
174 
175  if (runBenchmark) {
176  int numFailed = session.run();
177 
178  // numFailed is clamped to 255 as some unices only use the lower 8 bits.
179  // This clamping has already been applied, so just return it here
180  // You can also do any post run clean-up here
181  return numFailed;
182  }
183 
184  return EXIT_SUCCESS;
185 }
186 #else
187 #include <iostream>
188 
189 int main()
190 {
191  return 0;
192 }
193 #endif
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1292
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)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:141
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1537
unsigned int getHeight() const
Definition: vpImage.h:186
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:243
unsigned int getSize() const
Definition: vpImage.h:225
unsigned int getWidth() const
Definition: vpImage.h:244