Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpPixelMeterConversion.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 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 * Pixel to meter conversion.
32 */
33
34#ifndef _vpPixelMeterConversion_h_
35#define _vpPixelMeterConversion_h_
36
42#include <visp3/core/vpCameraParameters.h>
43#include <visp3/core/vpDebug.h>
44#include <visp3/core/vpException.h>
45#include <visp3/core/vpImagePoint.h>
46#include <visp3/core/vpMath.h>
47
48#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_CALIB3D) && defined(HAVE_OPENCV_IMGPROC)
49#include <opencv2/calib3d/calib3d.hpp>
50#include <opencv2/imgproc/imgproc.hpp>
51#endif
52
65class VISP_EXPORT vpPixelMeterConversion
66{
67public:
70 static void convertEllipse(const vpCameraParameters &cam, const vpImagePoint &center_p, double n20_p, double n11_p,
71 double n02_p, double &xc_m, double &yc_m, double &n20_m, double &n11_m, double &n02_m);
72 static void convertLine(const vpCameraParameters &cam, const double &rho_p, const double &theta_p, double &rho_m,
73 double &theta_m);
74
75 static void convertMoment(const vpCameraParameters &cam, unsigned int order, const vpMatrix &moment_pixel,
76 vpMatrix &moment_meter);
102 inline static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
103 {
104 switch (cam.projModel) {
106 convertPointWithoutDistortion(cam, u, v, x, y);
107 break;
109 convertPointWithDistortion(cam, u, v, x, y);
110 break;
112 convertPointWithKannalaBrandtDistortion(cam, u, v, x, y);
113 break;
114 }
115 }
116
144 inline static void convertPoint(const vpCameraParameters &cam, const vpImagePoint &iP, double &x, double &y)
145 {
146 switch (cam.projModel) {
148 convertPointWithoutDistortion(cam, iP, x, y);
149 break;
151 convertPointWithDistortion(cam, iP, x, y);
152 break;
154 convertPointWithKannalaBrandtDistortion(cam, iP, x, y);
155 break;
156 }
157 }
158
159#ifndef DOXYGEN_SHOULD_SKIP_THIS
172 inline static void convertPointWithoutDistortion(const vpCameraParameters &cam, const double &u, const double &v,
173 double &x, double &y)
174 {
175 x = (u - cam.u0) * cam.inv_px;
176 y = (v - cam.v0) * cam.inv_py;
177 }
178
194 inline static void convertPointWithoutDistortion(const vpCameraParameters &cam, const vpImagePoint &iP, double &x,
195 double &y)
196 {
197 x = (iP.get_u() - cam.u0) * cam.inv_px;
198 y = (iP.get_v() - cam.v0) * cam.inv_py;
199 }
200
215 inline static void convertPointWithDistortion(const vpCameraParameters &cam, const double &u, const double &v,
216 double &x, double &y)
217 {
218 double r2 = 1. + cam.kdu * (vpMath::sqr((u - cam.u0) * cam.inv_px) + vpMath::sqr((v - cam.v0) * cam.inv_py));
219 x = (u - cam.u0) * r2 * cam.inv_px;
220 y = (v - cam.v0) * r2 * cam.inv_py;
221 }
222
239 inline static void convertPointWithDistortion(const vpCameraParameters &cam, const vpImagePoint &iP, double &x,
240 double &y)
241 {
242 double r2 = 1. + cam.kdu * (vpMath::sqr((iP.get_u() - cam.u0) * cam.inv_px) +
243 vpMath::sqr((iP.get_v() - cam.v0) * cam.inv_py));
244 x = (iP.get_u() - cam.u0) * r2 * cam.inv_px;
245 y = (iP.get_v() - cam.v0) * r2 * cam.inv_py;
246 }
247
268 inline static void convertPointWithKannalaBrandtDistortion(const vpCameraParameters &cam, const double &u,
269 const double &v, double &x, double &y)
270 {
271 double x_d = (u - cam.u0) / cam.px, y_d = (v - cam.v0) / cam.py;
272 double scale = 1.0;
273 double r_d = sqrt(vpMath::sqr(x_d) + vpMath::sqr(y_d));
274
275 r_d = std::min(std::max(-M_PI, r_d), M_PI); // FOV restricted to 180degrees.
276
277 std::vector<double> k = cam.getKannalaBrandtDistortionCoefficients();
278
279 const double EPS = 1e-8;
280 // Use Newton-Raphson method to solve for the angle theta
281 if (r_d > EPS) {
282 // compensate distortion iteratively
283 double theta = r_d;
284
285 for (int j = 0; j < 10; j++) {
286 double theta2 = theta * theta, theta4 = theta2 * theta2, theta6 = theta4 * theta2, theta8 = theta6 * theta2;
287 double k0_theta2 = k[0] * theta2, k1_theta4 = k[1] * theta4, k2_theta6 = k[2] * theta6,
288 k3_theta8 = k[3] * theta8;
289 /* new_theta = theta - theta_fix, theta_fix = f0(theta) / f0'(theta) */
290 double theta_fix = (theta * (1 + k0_theta2 + k1_theta4 + k2_theta6 + k3_theta8) - r_d) /
291 (1 + 3 * k0_theta2 + 5 * k1_theta4 + 7 * k2_theta6 + 9 * k3_theta8);
292 theta = theta - theta_fix;
293 if (fabs(theta_fix) < EPS)
294 break;
295 }
296
297 scale = std::tan(theta) / r_d; // Scale of norm of (x,y) and (x_d, y_d)
298 }
299
300 x = x_d * scale;
301 y = y_d * scale;
302 }
303
323 inline static void convertPointWithKannalaBrandtDistortion(const vpCameraParameters &cam, const vpImagePoint &iP,
324 double &x, double &y)
325 {
326 double x_d = (iP.get_u() - cam.u0) / cam.px, y_d = (iP.get_v() - cam.v0) / cam.py;
327 double scale = 1.0;
328 double r_d = sqrt(vpMath::sqr(x_d) + vpMath::sqr(y_d));
329
330 r_d = std::min(std::max(-M_PI, r_d), M_PI); // FOV restricted to 180degrees.
331
332 std::vector<double> k = cam.getKannalaBrandtDistortionCoefficients();
333
334 const double EPS = 1e-8;
335 // Use Newton-Raphson method to solve for the angle theta
336 if (r_d > EPS) {
337 // compensate distortion iteratively
338 double theta = r_d;
339
340 for (int j = 0; j < 10; j++) {
341 double theta2 = theta * theta, theta4 = theta2 * theta2, theta6 = theta4 * theta2, theta8 = theta6 * theta2;
342 double k0_theta2 = k[0] * theta2, k1_theta4 = k[1] * theta4, k2_theta6 = k[2] * theta6,
343 k3_theta8 = k[3] * theta8;
344 /* new_theta = theta - theta_fix, theta_fix = f0(theta) / f0'(theta) */
345 double theta_fix = (theta * (1 + k0_theta2 + k1_theta4 + k2_theta6 + k3_theta8) - r_d) /
346 (1 + 3 * k0_theta2 + 5 * k1_theta4 + 7 * k2_theta6 + 9 * k3_theta8);
347 theta = theta - theta_fix;
348 if (fabs(theta_fix) < EPS)
349 break;
350 }
351
352 scale = std::tan(theta) / r_d; // Scale of norm of (x,y) and (x_d, y_d)
353 }
354
355 x = x_d * scale;
356 y = y_d * scale;
357 }
358#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
360
361#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_CALIB3D) && defined(HAVE_OPENCV_IMGPROC)
364 static void convertEllipse(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, const vpImagePoint &center_p,
365 double n20_p, double n11_p, double n02_p, double &xc_m, double &yc_m, double &n20_m,
366 double &n11_m, double &n02_m);
367 static void convertLine(const cv::Mat &cameraMatrix, const double &rho_p, const double &theta_p, double &rho_m,
368 double &theta_m);
369 static void convertMoment(const cv::Mat &cameraMatrix, unsigned int order, const vpMatrix &moment_pixel,
370 vpMatrix &moment_meter);
371 static void convertPoint(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, const double &u, const double &v,
372 double &x, double &y);
373 static void convertPoint(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, const vpImagePoint &iP, double &x,
374 double &y);
376#endif
377};
378
379#endif
Generic class defining intrinsic camera parameters.
@ perspectiveProjWithDistortion
Perspective projection with distortion model.
@ ProjWithKannalaBrandtDistortion
Projection with Kannala-Brandt distortion model.
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
std::vector< double > getKannalaBrandtDistortionCoefficients() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
double get_u() const
double get_v() const
static double sqr(double x)
Definition vpMath.h:124
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:152
static void convertPoint(const vpCameraParameters &cam, const vpImagePoint &iP, double &x, double &y)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)