Visual Servoing Platform  version 3.4.0
perfImageWarp.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 image warping.
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/core/vpImageTools.h>
45 #include <visp3/io/vpImageIo.h>
46 
47 namespace {
48 static std::string ipath = vpIoTools::getViSPImagesDataPath();
49 }
50 
51 TEST_CASE("Benchmark affine warp on grayscale image", "[benchmark]") {
52  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
53  REQUIRE(vpIoTools::checkFilename(imgPath));
54 
56  vpImageIo::read(I, imgPath);
57  REQUIRE(I.getSize() > 0);
58  vpImage<unsigned char> I_affine(I.getHeight(), I.getWidth());
59 
60  vpMatrix M(2, 3);
61  M.eye();
62 
63  const double theta = vpMath::rad(45);
64  M[0][0] = cos(theta); M[0][1] = -sin(theta); M[0][2] = I.getWidth() / 2;
65  M[1][0] = sin(theta); M[1][1] = cos(theta); M[1][2] = I.getHeight() / 2;
66 
67  BENCHMARK("Benchmark affine warp (ref code) (NN)") {
69  return I_affine;
70  };
71 
72  BENCHMARK("Benchmark affine warp (fixed-point) (NN)") {
74  return I_affine;
75  };
76 
77  BENCHMARK("Benchmark affine warp (ref code) (bilinear)") {
79  return I_affine;
80  };
81 
82  BENCHMARK("Benchmark affine warp (fixed-point) (bilinear)") {
84  return I_affine;
85  };
86 
87 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
88  cv::Mat img, img_affine;
90  vpImageConvert::convert(I, img_affine);
91 
92  cv::Mat M_cv(2, 3, CV_64FC1);
93  for (unsigned int i = 0; i < M.getRows(); i++) {
94  for (unsigned int j = 0; j < M.getCols(); j++) {
95  M_cv.at<double>(i, j) = M[i][j];
96  }
97  }
98 
99  BENCHMARK("Benchmark affine warp (OpenCV) (NN)") {
100  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_NEAREST);
101  return img_affine;
102  };
103 
104  BENCHMARK("Benchmark affine warp (OpenCV) (bilinear)") {
105  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_LINEAR);
106  return img_affine;
107  };
108 #endif
109 }
110 
111 TEST_CASE("Benchmark affine warp on color image", "[benchmark]") {
112  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
113  REQUIRE(vpIoTools::checkFilename(imgPath));
114 
115  vpImage<vpRGBa> I;
116  vpImageIo::read(I, imgPath);
117  REQUIRE(I.getSize() > 0);
118  vpImage<vpRGBa> I_affine(I.getHeight(), I.getWidth());
119 
120  vpMatrix M(2, 3);
121  M.eye();
122 
123  const double theta = vpMath::rad(45);
124  M[0][0] = cos(theta); M[0][1] = -sin(theta); M[0][2] = I.getWidth() / 2;
125  M[1][0] = sin(theta); M[1][1] = cos(theta); M[1][2] = I.getHeight() / 2;
126 
127  BENCHMARK("Benchmark affine warp (ref code) (NN)") {
129  return I_affine;
130  };
131 
132  BENCHMARK("Benchmark affine warp (fixed-point) (NN)") {
134  return I_affine;
135  };
136 
137  BENCHMARK("Benchmark affine warp (ref code) (bilinear)") {
139  return I_affine;
140  };
141 
142  BENCHMARK("Benchmark affine warp (fixed-point) (bilinear)") {
144  return I_affine;
145  };
146 
147 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
148  cv::Mat img, img_affine;
149  vpImageConvert::convert(I, img);
150  vpImageConvert::convert(I, img_affine);
151 
152  cv::Mat M_cv(2, 3, CV_64FC1);
153  for (unsigned int i = 0; i < M.getRows(); i++) {
154  for (unsigned int j = 0; j < M.getCols(); j++) {
155  M_cv.at<double>(i, j) = M[i][j];
156  }
157  }
158 
159  BENCHMARK("Benchmark affine warp (OpenCV) (NN)") {
160  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_NEAREST);
161  return img_affine;
162  };
163 
164  BENCHMARK("Benchmark affine warp (OpenCV) (bilinear)") {
165  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_LINEAR);
166  return img_affine;
167  };
168 #endif
169 }
170 
171 TEST_CASE("Benchmark perspective warp on grayscale image", "[benchmark]") {
172  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
173  REQUIRE(vpIoTools::checkFilename(imgPath));
174 
176  vpImageIo::read(I, imgPath);
177  REQUIRE(I.getSize() > 0);
178  vpImage<unsigned char> I_perspective(I.getHeight(), I.getWidth());
179 
180  vpMatrix M(3, 3);
181  M.eye();
182 
183  const double theta = vpMath::rad(45);
184  M[0][0] = cos(theta); M[0][1] = -sin(theta); M[0][2] = I.getWidth() / 2;
185  M[1][0] = sin(theta); M[1][1] = cos(theta); M[1][2] = I.getHeight() / 2;
186 
187  BENCHMARK("Benchmark perspective warp (ref code) (NN)") {
189  return I_perspective;
190  };
191 
192  BENCHMARK("Benchmark perspective warp (fixed-point) (NN)") {
194  return I_perspective;
195  };
196 
197  BENCHMARK("Benchmark perspective warp (ref code) (bilinear)") {
198  vpImageTools::warpImage(I, M, I_perspective, vpImageTools::INTERPOLATION_LINEAR, false);
199  return I_perspective;
200  };
201 
202  BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)") {
204  return I_perspective;
205  };
206 
207 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
208  cv::Mat img, img_perspective;
209  vpImageConvert::convert(I, img);
210  vpImageConvert::convert(I, img_perspective);
211 
212  cv::Mat M_cv(3, 3, CV_64FC1);
213  for (unsigned int i = 0; i < M.getRows(); i++) {
214  for (unsigned int j = 0; j < M.getCols(); j++) {
215  M_cv.at<double>(i, j) = M[i][j];
216  }
217  }
218 
219  BENCHMARK("Benchmark perspective warp (OpenCV) (NN)") {
220  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_NEAREST);
221  return img_perspective;
222  };
223 
224  BENCHMARK("Benchmark perspective warp (OpenCV) (bilinear)") {
225  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_LINEAR);
226  return img_perspective;
227  };
228 #endif
229 }
230 
231 TEST_CASE("Benchmark perspective warp on color image", "[benchmark]") {
232  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
233  REQUIRE(vpIoTools::checkFilename(imgPath));
234 
235  vpImage<vpRGBa> I;
236  vpImageIo::read(I, imgPath);
237  REQUIRE(I.getSize() > 0);
238  vpImage<vpRGBa> I_perspective(I.getHeight(), I.getWidth());
239 
240  vpMatrix M(3, 3);
241  M.eye();
242 
243  const double theta = vpMath::rad(45);
244  M[0][0] = cos(theta); M[0][1] = -sin(theta); M[0][2] = I.getWidth() / 2;
245  M[1][0] = sin(theta); M[1][1] = cos(theta); M[1][2] = I.getHeight() / 2;
246 
247  BENCHMARK("Benchmark perspective warp (ref code) (NN)") {
249  return I_perspective;
250  };
251 
252  BENCHMARK("Benchmark perspective warp (fixed-point) (NN)") {
254  return I_perspective;
255  };
256 
257  BENCHMARK("Benchmark perspective warp (ref code) (bilinear)") {
258  vpImageTools::warpImage(I, M, I_perspective, vpImageTools::INTERPOLATION_LINEAR, false);
259  return I_perspective;
260  };
261 
262  BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)") {
264  return I_perspective;
265  };
266 
267 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
268  cv::Mat img, img_perspective;
269  vpImageConvert::convert(I, img);
270  vpImageConvert::convert(I, img_perspective);
271 
272  cv::Mat M_cv(3, 3, CV_64FC1);
273  for (unsigned int i = 0; i < M.getRows(); i++) {
274  for (unsigned int j = 0; j < M.getCols(); j++) {
275  M_cv.at<double>(i, j) = M[i][j];
276  }
277  }
278 
279  BENCHMARK("Benchmark perspective warp (OpenCV) (NN)") {
280  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_NEAREST);
281  return img_perspective;
282  };
283 
284  BENCHMARK("Benchmark perspective warp (OpenCV) (bilinear)") {
285  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_LINEAR);
286  return img_perspective;
287  };
288 #endif
289 }
290 
291 int main(int argc, char *argv[])
292 {
293  Catch::Session session; // There must be exactly one instance
294 
295  bool runBenchmark = false;
296  // Build a new parser on top of Catch's
297  using namespace Catch::clara;
298  auto cli = session.cli() // Get Catch's composite command line parser
299  | Opt(runBenchmark) // bind variable to a new option, with a hint string
300  ["--benchmark"] // the option names it will respond to
301  ("run benchmark?"); // description string for the help output
302 
303  // Now pass the new composite back to Catch so it uses that
304  session.cli(cli);
305 
306  // Let Catch (using Clara) parse the command line
307  session.applyCommandLine(argc, argv);
308 
309  if (runBenchmark) {
310  int numFailed = session.run();
311 
312  // numFailed is clamped to 255 as some unices only use the lower 8 bits.
313  // This clamping has already been applied, so just return it here
314  // You can also do any post run clean-up here
315  return numFailed;
316  }
317 
318  return EXIT_SUCCESS;
319 }
320 #else
321 #include <iostream>
322 
323 int main()
324 {
325  return 0;
326 }
327 #endif
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:153
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)
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 double rad(double deg)
Definition: vpMath.h:110
static void warpImage(const vpImage< Type > &src, const vpMatrix &T, vpImage< Type > &dst, const vpImageInterpolationType &interpolation=INTERPOLATION_NEAREST, bool fixedPointArithmetic=true, bool pixelCenter=false)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:244
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:640
unsigned int getHeight() const
Definition: vpImage.h:188