Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
perfImageWarp.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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
37
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
49using namespace VISP_NAMESPACE_NAME;
50#endif
51namespace
52{
53VP_ATTRIBUTE_NO_DESTROY static std::string ipath = vpIoTools::getViSPImagesDataPath();
54}
55
56TEST_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 defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
102 cv::Mat img, img_affine;
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
127TEST_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
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 defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
173 cv::Mat img, img_affine;
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
198TEST_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 {
234 return I_perspective;
235 };
236
237 BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)")
238 {
240 return I_perspective;
241 };
242
243#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
244 cv::Mat img, img_perspective;
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
269TEST_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
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 {
305 return I_perspective;
306 };
307
308 BENCHMARK("Benchmark perspective warp (fixed-point) (bilinear)")
309 {
311 return I_perspective;
312 };
313
314#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGPROC)
315 cv::Mat img, img_perspective;
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
340int 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
361int 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)
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:131
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:129
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175