Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
vpMeterPixelConversion.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  * Meter to pixel conversion.
33  *
34  * Authors:
35  * Eric Marchand
36  * Anthony Saunier
37  *
38  *****************************************************************************/
39 
45 #include <visp3/core/vpCameraParameters.h>
46 #include <visp3/core/vpDebug.h>
47 #include <visp3/core/vpException.h>
48 #include <visp3/core/vpMath.h>
49 #include <visp3/core/vpMeterPixelConversion.h>
50 
61  const double &rho_m, const double &theta_m,
62  double &rho_p, double &theta_p)
63 {
64  double co = cos(theta_m);
65  double si = sin(theta_m);
66  double d = sqrt(vpMath::sqr(cam.py * co) + vpMath::sqr(cam.px * si));
67 
68  if (fabs(d) < 1e-6) {
69  vpERROR_TRACE("division by zero");
70  throw(vpException(vpException::divideByZeroError, "division by zero"));
71  }
72 
73  theta_p = atan2(cam.px * si, cam.py * co);
74  rho_p = (cam.px * cam.py * rho_m + cam.u0 * cam.py * co + cam.v0 * cam.px * si);
75  rho_p /= d;
76 }
77 
103  const vpCircle &circle, vpImagePoint &center,
104  double &mu20_p, double &mu11_p, double &mu02_p)
105 {
106  // Get the parameters of the ellipse in the image plane
107  double xc_m = circle.p[0];
108  double yc_m = circle.p[1];
109  double mu20_m = circle.p[2];
110  double mu11_m = circle.p[3];
111  double mu02_m = circle.p[4];
112 
113  // Convert from meter to pixels
114  vpMeterPixelConversion::convertPoint(cam, xc_m, yc_m, center);
115  mu20_p = mu20_m * vpMath::sqr(cam.get_px());
116  mu11_p = mu11_m * cam.get_px() * cam.get_py();
117  mu02_p = mu02_m * vpMath::sqr(cam.get_py());
118 }
119 
145  double &mu20_p, double &mu11_p, double &mu02_p)
146 {
147  // Get the parameters of the ellipse in the image plane
148  double xc_m = sphere.p[0];
149  double yc_m = sphere.p[1];
150  double mu20_m = sphere.p[2];
151  double mu11_m = sphere.p[3];
152  double mu02_m = sphere.p[4];
153 
154  // Convert from meter to pixels
155  vpMeterPixelConversion::convertPoint(cam, xc_m, yc_m, center);
156  mu20_p = mu20_m * vpMath::sqr(cam.get_px());
157  mu11_p = mu11_m * cam.get_px() * cam.get_py();
158  mu02_p = mu02_m * vpMath::sqr(cam.get_py());
159 }
160 
161 #if VISP_HAVE_OPENCV_VERSION >= 0x020300
162 
171 void vpMeterPixelConversion::convertLine(const cv::Mat &cameraMatrix,
172  const double &rho_m, const double &theta_m,
173  double &rho_p, double &theta_p)
174 {
175  double co = cos(theta_m);
176  double si = sin(theta_m);
177  double px = cameraMatrix.at<double>(0,0);
178  double py = cameraMatrix.at<double>(1,1);
179  double u0 = cameraMatrix.at<double>(0,2);
180  double v0 = cameraMatrix.at<double>(1,2);
181  double d = sqrt(vpMath::sqr(py * co) + vpMath::sqr(px * si));
182 
183  if (fabs(d) < 1e-6) {
184  vpERROR_TRACE("division by zero");
185  throw(vpException(vpException::divideByZeroError, "division by zero"));
186  }
187 
188  theta_p = atan2(px * si, py * co);
189  rho_p = (px * py * rho_m + u0 * py * co + v0 * px * si);
190  rho_p /= d;
191 }
192 
220 void vpMeterPixelConversion::convertEllipse(const cv::Mat &cameraMatrix,
221  const vpCircle &circle, vpImagePoint &center,
222  double &mu20_p, double &mu11_p, double &mu02_p)
223 {
224  double px = cameraMatrix.at<double>(0,0);
225  double py = cameraMatrix.at<double>(1,1);
226  cv::Mat distCoeffs = cv::Mat::zeros(5,1,CV_64FC1);
227  // Get the parameters of the ellipse in the image plane
228  double xc_m = circle.p[0];
229  double yc_m = circle.p[1];
230  double mu20_m = circle.p[2];
231  double mu11_m = circle.p[3];
232  double mu02_m = circle.p[4];
233 
234  // Convert from meter to pixels
235  vpMeterPixelConversion::convertPoint(cameraMatrix, distCoeffs, xc_m, yc_m, center);
236  mu20_p = mu20_m * vpMath::sqr(px);
237  mu11_p = mu11_m * px * py;
238  mu02_p = mu02_m * vpMath::sqr(py);
239 }
240 
268 void vpMeterPixelConversion::convertEllipse(const cv::Mat &cameraMatrix,
269  const vpSphere &sphere, vpImagePoint &center,
270  double &mu20_p, double &mu11_p, double &mu02_p)
271 {
272  double px = cameraMatrix.at<double>(0,0);
273  double py = cameraMatrix.at<double>(1,1);
274  cv::Mat distCoeffs = cv::Mat::zeros(5,1,CV_64FC1);
275  // Get the parameters of the ellipse in the image plane
276  double xc_m = sphere.p[0];
277  double yc_m = sphere.p[1];
278  double mu20_m = sphere.p[2];
279  double mu11_m = sphere.p[3];
280  double mu02_m = sphere.p[4];
281 
282  // Convert from meter to pixels
283  vpMeterPixelConversion::convertPoint(cameraMatrix, distCoeffs, xc_m, yc_m, center);
284  mu20_p = mu20_m * vpMath::sqr(px);
285  mu11_p = mu11_m * px * py;
286  mu02_p = mu02_m * vpMath::sqr(py);
287 }
288 
304 void vpMeterPixelConversion::convertPoint(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs,
305  const double &x, const double &y, double &u, double &v)
306 {
307  std::vector<cv::Point3d> objectPoints_vec;
308  objectPoints_vec.push_back(cv::Point3d(x, y, 1.0));
309  std::vector<cv::Point2d> imagePoints_vec;
310  cv::projectPoints(objectPoints_vec, cv::Mat::eye(3,3,CV_64FC1), cv::Mat::zeros(3,1,CV_64FC1), cameraMatrix, distCoeffs, imagePoints_vec);
311  u = imagePoints_vec[0].x;
312  v = imagePoints_vec[0].y;
313 }
314 
329 void vpMeterPixelConversion::convertPoint(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs,
330  const double &x, const double &y, vpImagePoint &iP)
331 {
332  std::vector<cv::Point3d> objectPoints_vec;
333  objectPoints_vec.push_back(cv::Point3d(x, y, 1.0));
334  std::vector<cv::Point2d> imagePoints_vec;
335  cv::projectPoints(objectPoints_vec, cv::Mat::eye(3,3,CV_64FC1), cv::Mat::zeros(3,1,CV_64FC1), cameraMatrix, distCoeffs, imagePoints_vec);
336  iP.set_u(imagePoints_vec[0].x);
337  iP.set_v(imagePoints_vec[0].y);
338 }
339 #endif
static void convertEllipse(const vpCameraParameters &cam, const vpSphere &sphere, vpImagePoint &center, double &mu20_p, double &mu11_p, double &mu02_p)
void set_u(double u)
Definition: vpImagePoint.h:226
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
#define vpERROR_TRACE
Definition: vpDebug.h:393
error that can be emited by ViSP classes.
Definition: vpException.h:71
Class that defines what is a sphere.
Definition: vpSphere.h:60
static double sqr(double x)
Definition: vpMath.h:114
Generic class defining intrinsic camera parameters.
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
void set_v(double v)
Definition: vpImagePoint.h:237
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
Class that defines what is a circle.
Definition: vpCircle.h:58
vpColVector p
Definition: vpTracker.h:71