15 #include <Eigen/Dense>
23 "BrownConrady: fx, fy, cx, cy, k1, k2, p1, p2, k3, k4, k5, k6";
25 template <
class TScalar>
27 template <
class TScalar>
29 template <
class TScalar>
30 using Params = Eigen::Matrix<TScalar, kNumParams, 1>;
31 template <
class TScalar>
34 template <
class TParamScalarT,
class TPo
intScalarT>
38 ->
PixelImage<
typename Eigen::ScalarBinaryOpTraits<
40 TPointScalarT>::ReturnType> {
41 using ReturnScalar =
typename Eigen::
42 ScalarBinaryOpTraits<TParamScalarT, TPointScalarT>::ReturnType;
45 auto x = point_normalized[0];
46 auto y = point_normalized[1];
47 auto const& k = distortion;
52 auto r2 = x * x + y * y;
56 auto a2 = r2 + 2 * x * x;
57 auto a3 = r2 + 2 * y * y;
58 auto cdist = 1 + k[0] * r2 + k[1] * r4 + k[4] * r6;
59 auto icdist2 = 1. / (1 + k[5] * r2 + k[6] * r4 + k[7] * r6);
60 auto xd0 = x * cdist * icdist2 + k[2] * a1 + k[3] * a2;
61 auto yd0 = y * cdist * icdist2 + k[2] * a3 + k[3] * a1;
66 template <
class TScalar>
92 for (
int i = 0; i < 50; ++i) {
97 projImpl(distortion, Eigen::Matrix<TScalar, 2, 1>(x, y)) -
111 TScalar
const c0 = a * a;
112 TScalar
const c1 = b * b;
113 TScalar
const c2 = c0 + c1;
114 TScalar
const c3 = c2 * c2;
115 TScalar
const c4 = c3 * c2;
116 TScalar
const c5 = c2 * d[5] + c3 * d[6] + c4 * d[7] + 1.0;
117 TScalar
const c6 = c5 * c5;
118 TScalar
const c7 = 1.0 / c6;
119 TScalar
const c8 = a * d[3];
120 TScalar
const c9 = 2.0 * d[2];
121 TScalar
const c10 = 2 * c2;
122 TScalar
const c11 = 3 * c3;
123 TScalar
const c12 = c2 * d[0];
124 TScalar
const c13 = c3 * d[1];
125 TScalar
const c14 = c4 * d[4];
127 2.0 * (c10 * d[6] + c11 * d[7] + d[5]) * (c12 + c13 + c14 + 1.0);
128 TScalar
const c16 = 2.0 * c10 * d[1] + 2.0 * c11 * d[4] + 2.0 * d[0];
129 TScalar
const c17 = 1.0 * c12 + 1.0 * c13 + 1.0 * c14 + 1.0;
130 TScalar
const c18 = b * d[3];
131 TScalar
const c19 = a * b;
132 TScalar
const c20 = -c15 * c19 + c16 * c19 * c5;
134 c7 * (-c0 * c15 + c5 * (c0 * c16 + c17) + c6 * (b * c9 + 6.0 * c8));
135 du_dy = c7 * (c20 + c6 * (a * c9 + 2 * c18));
136 dv_dx = c7 * (c20 + c6 * (2 * a * d[2] + 2.0 * c18));
137 dv_dy = c7 * (-c1 * c15 + c5 * (c1 * c16 + c17) +
138 c6 * (6.0 * b * d[2] + 2.0 * c8));
154 Eigen::Matrix<TScalar, 2, 2> m;
160 Eigen::Matrix<TScalar, 2, 2> j_inv = TScalar(1) / (a * d - b * c) * m;
164 sophus::kEpsilon<TScalar> * sophus::kEpsilon<TScalar>) {
173 template <
class TParamsTypeT,
class TPo
intTypeT>
175 Eigen::MatrixBase<TParamsTypeT>
const& params,
176 Eigen::MatrixBase<TPointTypeT>
const& proj_point_in_camera_z1_plane)
178 using ParamScalar =
typename TParamsTypeT::Scalar;
181 TParamsTypeT::ColsAtCompileTime == 1,
"params must be a column-vector");
183 TParamsTypeT::RowsAtCompileTime ==
kNumParams,
184 "params must have exactly kNumParams rows");
186 TPointTypeT::ColsAtCompileTime == 1,
187 "point_camera must be a column-vector");
189 TPointTypeT::RowsAtCompileTime == 2,
190 "point_camera must have exactly 2 columns");
192 Eigen::Matrix<ParamScalar, kNumDistortionParams, 1> distortion =
193 params.template tail<kNumDistortionParams>();
196 distorted_point_in_camera_z1_plane =
197 projImpl(distortion, proj_point_in_camera_z1_plane.eval());
200 params.template head<4>(), distorted_point_in_camera_z1_plane);
203 template <
class TScalar>
208 params.template tail<kNumDistortionParams>().eval(),
210 params.template head<4>().eval(), pixel_image));
213 proj_point_in_camera_z1_plane[0], proj_point_in_camera_z1_plane[1]);
216 template <
class TParamsTypeT,
class TPo
intTypeT>
218 Eigen::MatrixBase<TParamsTypeT>
const& params,
219 Eigen::MatrixBase<TPointTypeT>
const& proj_point_in_camera_z1_plane)
220 -> Eigen::Matrix<typename TPointTypeT::Scalar, 2, 2> {
222 TParamsTypeT::ColsAtCompileTime == 1,
"params must be a column-vector");
224 TParamsTypeT::RowsAtCompileTime ==
kNumParams,
225 "params must have exactly kNumParams rows");
227 TPointTypeT::ColsAtCompileTime == 1,
228 "point_camera must be a column-vector");
230 TPointTypeT::RowsAtCompileTime == 2,
231 "point_camera must have exactly 2 columns");
232 using Scalar =
typename TPointTypeT::Scalar;
234 Eigen::Matrix<Scalar, kNumDistortionParams, 1> d =
235 params.template tail<kNumDistortionParams>();
237 Scalar a = proj_point_in_camera_z1_plane[0];
238 Scalar b = proj_point_in_camera_z1_plane[1];
240 Eigen::Matrix<typename TPointTypeT::Scalar, 2, 2> dx;
241 Scalar
const fx = params[0];
242 Scalar
const fy = params[1];
245 Scalar
const c0 = a * d[3];
246 Scalar
const c1 = 2.0 * d[2];
247 Scalar
const c2 = a * a;
248 Scalar
const c3 = b * b;
249 Scalar
const c4 = c2 + c3;
250 Scalar
const c5 = c4 * c4;
251 Scalar
const c6 = c5 * c4;
252 Scalar
const c7 = c4 * d[5] + c5 * d[6] + c6 * d[7] + 1.0;
253 Scalar
const c8 = c7 * c7;
254 Scalar
const c9 = 2 * c4;
255 Scalar
const c10 = 3 * c5;
256 Scalar
const c11 = c4 * d[0];
257 Scalar
const c12 = c5 * d[1];
258 Scalar
const c13 = c6 * d[4];
260 2.0 * (c10 * d[7] + c9 * d[6] + d[5]) * (c11 + c12 + c13 + 1.0);
261 Scalar
const c15 = 2.0 * c10 * d[4] + 2.0 * c9 * d[1] + 2.0 * d[0];
262 Scalar
const c16 = 1.0 * c11 + 1.0 * c12 + 1.0 * c13 + 1.0;
263 Scalar
const c17 = 1.0 / c8;
264 Scalar
const c18 = c17 * fx;
265 Scalar
const c19 = b * d[3];
266 Scalar
const c20 = a * b;
267 Scalar
const c21 = -c14 * c20 + c15 * c20 * c7;
268 Scalar
const c22 = c17 * fy;
270 c18 * (-c14 * c2 + c7 * (c15 * c2 + c16) + c8 * (b * c1 + 6.0 * c0));
271 dx(0, 1) = c22 * (c21 + c8 * (2 * a * d[2] + 2.0 * c19));
272 dx(1, 0) = c18 * (c21 + c8 * (a * c1 + 2 * c19));
273 dx(1, 1) = c22 * (-c14 * c3 + c7 * (c15 * c3 + c16) +
274 c8 * (6.0 * b * d[2] + 2.0 * c0));