Visual Servoing Platform  version 3.6.1 under development (2024-10-15)
perfImageWarp.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 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 image warping.
32  */
33 
38 #include <visp3/core/vpConfig.h>
39 
40 #if defined(VISP_HAVE_CATCH2)
41 
42 #include <catch_amalgamated.hpp>
43 
44 #include <visp3/core/vpImageTools.h>
45 #include <visp3/core/vpIoTools.h>
46 #include <visp3/io/vpImageIo.h>
47 
48 #ifdef ENABLE_VISP_NAMESPACE
49 using namespace VISP_NAMESPACE_NAME;
50 #endif
51 namespace
52 {
53 static std::string ipath = vpIoTools::getViSPImagesDataPath();
54 }
55 
56 TEST_CASE("Benchmark affine warp on grayscale image", "[benchmark]")
57 {
58  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
59  REQUIRE(vpIoTools::checkFilename(imgPath));
60 
62  vpImageIo::read(I, imgPath);
63  REQUIRE(I.getSize() > 0);
64  vpImage<unsigned char> I_affine(I.getHeight(), I.getWidth());
65 
66  vpMatrix M(2, 3);
67  M.eye();
68 
69  const double theta = vpMath::rad(45);
70  M[0][0] = cos(theta);
71  M[0][1] = -sin(theta);
72  M[0][2] = I.getWidth() / 2;
73  M[1][0] = sin(theta);
74  M[1][1] = cos(theta);
75  M[1][2] = I.getHeight() / 2;
76 
77  BENCHMARK("Benchmark affine warp (ref code) (NN)")
78  {
80  return I_affine;
81  };
82 
83  BENCHMARK("Benchmark affine warp (fixed-point) (NN)")
84  {
86  return I_affine;
87  };
88 
89  BENCHMARK("Benchmark affine warp (ref code) (bilinear)")
90  {
92  return I_affine;
93  };
94 
95  BENCHMARK("Benchmark affine warp (fixed-point) (bilinear)")
96  {
98  return I_affine;
99  };
100 
101 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
102  cv::Mat img, img_affine;
103  vpImageConvert::convert(I, img);
104  vpImageConvert::convert(I, img_affine);
105 
106  cv::Mat M_cv(2, 3, CV_64FC1);
107  for (unsigned int i = 0; i < M.getRows(); i++) {
108  for (unsigned int j = 0; j < M.getCols(); j++) {
109  M_cv.at<double>(i, j) = M[i][j];
110  }
111  }
112 
113  BENCHMARK("Benchmark affine warp (OpenCV) (NN)")
114  {
115  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_NEAREST);
116  return img_affine;
117  };
118 
119  BENCHMARK("Benchmark affine warp (OpenCV) (bilinear)")
120  {
121  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_LINEAR);
122  return img_affine;
123  };
124 #endif
125 }
126 
127 TEST_CASE("Benchmark affine warp on color image", "[benchmark]")
128 {
129  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
130  REQUIRE(vpIoTools::checkFilename(imgPath));
131 
132  vpImage<vpRGBa> I;
133  vpImageIo::read(I, imgPath);
134  REQUIRE(I.getSize() > 0);
135  vpImage<vpRGBa> I_affine(I.getHeight(), I.getWidth());
136 
137  vpMatrix M(2, 3);
138  M.eye();
139 
140  const double theta = vpMath::rad(45);
141  M[0][0] = cos(theta);
142  M[0][1] = -sin(theta);
143  M[0][2] = I.getWidth() / 2;
144  M[1][0] = sin(theta);
145  M[1][1] = cos(theta);
146  M[1][2] = I.getHeight() / 2;
147 
148  BENCHMARK("Benchmark affine warp (ref code) (NN)")
149  {
151  return I_affine;
152  };
153 
154  BENCHMARK("Benchmark affine warp (fixed-point) (NN)")
155  {
157  return I_affine;
158  };
159 
160  BENCHMARK("Benchmark affine warp (ref code) (bilinear)")
161  {
163  return I_affine;
164  };
165 
166  BENCHMARK("Benchmark affine warp (fixed-point) (bilinear)")
167  {
169  return I_affine;
170  };
171 
172 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
173  cv::Mat img, img_affine;
174  vpImageConvert::convert(I, img);
175  vpImageConvert::convert(I, img_affine);
176 
177  cv::Mat M_cv(2, 3, CV_64FC1);
178  for (unsigned int i = 0; i < M.getRows(); i++) {
179  for (unsigned int j = 0; j < M.getCols(); j++) {
180  M_cv.at<double>(i, j) = M[i][j];
181  }
182  }
183 
184  BENCHMARK("Benchmark affine warp (OpenCV) (NN)")
185  {
186  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_NEAREST);
187  return img_affine;
188  };
189 
190  BENCHMARK("Benchmark affine warp (OpenCV) (bilinear)")
191  {
192  cv::warpAffine(img, img_affine, M_cv, img.size(), cv::INTER_LINEAR);
193  return img_affine;
194  };
195 #endif
196 }
197 
198 TEST_CASE("Benchmark perspective warp on grayscale image", "[benchmark]")
199 {
200  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.pgm");
201  REQUIRE(vpIoTools::checkFilename(imgPath));
202 
204  vpImageIo::read(I, imgPath);
205  REQUIRE(I.getSize() > 0);
206  vpImage<unsigned char> I_perspective(I.getHeight(), I.getWidth());
207 
208  vpMatrix M(3, 3);
209  M.eye();
210 
211  const double theta = vpMath::rad(45);
212  M[0][0] = cos(theta);
213  M[0][1] = -sin(theta);
214  M[0][2] = I.getWidth() / 2;
215  M[1][0] = sin(theta);
216  M[1][1] = cos(theta);
217  M[1][2] = I.getHeight() / 2;
218 
219  BENCHMARK("Benchmark perspective warp (ref code) (NN)")
220  {
222  return I_perspective;
223  };
224 
225  BENCHMARK("Benchmark perspective warp (fixed-point) (NN)")
226  {
228  return I_perspective;
229  };
230 
231  BENCHMARK("Benchmark perspective warp (ref code) (bilinear)")
232  {
233  vpImageTools::warpImage(I, M, I_perspective, vpImageTools::INTERPOLATION_LINEAR, false);
234  return I_perspective;
235  };
236 
237  BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)")
238  {
240  return I_perspective;
241  };
242 
243 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
244  cv::Mat img, img_perspective;
245  vpImageConvert::convert(I, img);
246  vpImageConvert::convert(I, img_perspective);
247 
248  cv::Mat M_cv(3, 3, CV_64FC1);
249  for (unsigned int i = 0; i < M.getRows(); i++) {
250  for (unsigned int j = 0; j < M.getCols(); j++) {
251  M_cv.at<double>(i, j) = M[i][j];
252  }
253  }
254 
255  BENCHMARK("Benchmark perspective warp (OpenCV) (NN)")
256  {
257  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_NEAREST);
258  return img_perspective;
259  };
260 
261  BENCHMARK("Benchmark perspective warp (OpenCV) (bilinear)")
262  {
263  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_LINEAR);
264  return img_perspective;
265  };
266 #endif
267 }
268 
269 TEST_CASE("Benchmark perspective warp on color image", "[benchmark]")
270 {
271  std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
272  REQUIRE(vpIoTools::checkFilename(imgPath));
273 
274  vpImage<vpRGBa> I;
275  vpImageIo::read(I, imgPath);
276  REQUIRE(I.getSize() > 0);
277  vpImage<vpRGBa> I_perspective(I.getHeight(), I.getWidth());
278 
279  vpMatrix M(3, 3);
280  M.eye();
281 
282  const double theta = vpMath::rad(45);
283  M[0][0] = cos(theta);
284  M[0][1] = -sin(theta);
285  M[0][2] = I.getWidth() / 2;
286  M[1][0] = sin(theta);
287  M[1][1] = cos(theta);
288  M[1][2] = I.getHeight() / 2;
289 
290  BENCHMARK("Benchmark perspective warp (ref code) (NN)")
291  {
293  return I_perspective;
294  };
295 
296  BENCHMARK("Benchmark perspective warp (fixed-point) (NN)")
297  {
299  return I_perspective;
300  };
301 
302  BENCHMARK("Benchmark perspective warp (ref code) (bilinear)")
303  {
304  vpImageTools::warpImage(I, M, I_perspective, vpImageTools::INTERPOLATION_LINEAR, false);
305  return I_perspective;
306  };
307 
308  BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)")
309  {
311  return I_perspective;
312  };
313 
314 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
315  cv::Mat img, img_perspective;
316  vpImageConvert::convert(I, img);
317  vpImageConvert::convert(I, img_perspective);
318 
319  cv::Mat M_cv(3, 3, CV_64FC1);
320  for (unsigned int i = 0; i < M.getRows(); i++) {
321  for (unsigned int j = 0; j < M.getCols(); j++) {
322  M_cv.at<double>(i, j) = M[i][j];
323  }
324  }
325 
326  BENCHMARK("Benchmark perspective warp (OpenCV) (NN)")
327  {
328  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_NEAREST);
329  return img_perspective;
330  };
331 
332  BENCHMARK("Benchmark perspective warp (OpenCV) (bilinear)")
333  {
334  cv::warpPerspective(img, img_perspective, M_cv, img.size(), cv::INTER_LINEAR);
335  return img_perspective;
336  };
337 #endif
338 }
339 
340 int main(int argc, char *argv[])
341 {
342  Catch::Session session;
343  bool runBenchmark = false;
344  auto cli = session.cli()
345  | Catch::Clara::Opt(runBenchmark)["--benchmark"]("run benchmark?");
346 
347  session.cli(cli);
348  session.applyCommandLine(argc, argv);
349 
350  if (runBenchmark) {
351  int numFailed = session.run();
352 
353  return numFailed;
354  }
355 
356  return EXIT_SUCCESS;
357 }
358 #else
359 #include <iostream>
360 
361 int main() { return EXIT_SUCCESS; }
362 #endif
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:147
static void warpImage(const vpImage< Type > &src, const vpMatrix &T, vpImage< Type > &dst, const vpImageInterpolationType &interpolation=INTERPOLATION_NEAREST, bool fixedPointArithmetic=true, bool pixelCenter=false)
@ INTERPOLATION_LINEAR
Definition: vpImageTools.h:81
@ INTERPOLATION_NEAREST
Definition: vpImageTools.h:80
unsigned int getWidth() const
Definition: vpImage.h:242
unsigned int getSize() const
Definition: vpImage.h:221
unsigned int getHeight() const
Definition: vpImage.h:181
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:786
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427
static double rad(double deg)
Definition: vpMath.h:129
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169