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