Visual Servoing Platform version 3.5.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
47namespace {
48static std::string ipath = vpIoTools::getViSPImagesDataPath();
49}
50
51TEST_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
111TEST_CASE("Benchmark affine warp on color image", "[benchmark]") {
112 std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
113 REQUIRE(vpIoTools::checkFilename(imgPath));
114
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;
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
171TEST_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)") {
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;
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
231TEST_CASE("Benchmark perspective warp on color image", "[benchmark]") {
232 std::string imgPath = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
233 REQUIRE(vpIoTools::checkFilename(imgPath));
234
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)") {
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;
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
291int 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
323int main()
324{
325 return 0;
326}
327#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:149
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:83
@ INTERPOLATION_NEAREST
Definition: vpImageTools.h:82
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getSize() const
Definition: vpImage.h:227
unsigned int getHeight() const
Definition: vpImage.h:188
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:802
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
static double rad(double deg)
Definition: vpMath.h:110
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:154