10 static void _cvProjectPoints2(
const CvMat* object_points,
const CvMat* rotation_vector,
11 const CvMat* translation_vector,
const CvMat* camera_matrix,
12 const CvMat* distortion_coeffs, CvMat* image_points,
13 CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL),
14 CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL),
15 CvMat* dpddist CV_DEFAULT(NULL),
16 double aspect_ratio CV_DEFAULT(0));
19 InputArray rvec, InputArray tvec,
21 OutputArray imagePoints,
22 OutputArray jacobian = noArray(),
23 double aspectRatio = 0 );
29 CV_Assert(outSize.area() > 0);
30 CV_Assert(marginSize >= 0);
32 _img.create(outSize, drawAxis ? CV_8UC3 : CV_8UC1);
33 Mat out = _img.getMat();
34 out.setTo(Scalar::all(255));
35 out.adjustROI(-marginSize, -marginSize, -marginSize, -marginSize);
39 float minX, maxX, minY, maxY;
43 for(
unsigned int i = 0; i < _board->
objPoints.size(); i++) {
44 for(
int j = 0; j < 4; j++) {
52 float sizeX = maxX - minX;
53 float sizeY = maxY - minY;
56 float xReduction = sizeX / float(out.cols);
57 float yReduction = sizeY / float(out.rows);
60 if(xReduction > yReduction) {
61 int nRows = int(sizeY / xReduction);
62 int rowsMargins = (out.rows - nRows) / 2;
63 out.adjustROI(-rowsMargins, -rowsMargins, 0, 0);
65 int nCols = int(sizeX / yReduction);
66 int colsMargins = (out.cols - nCols) / 2;
67 out.adjustROI(0, 0, -colsMargins, -colsMargins);
73 Point2f outCorners[3];
75 for(
unsigned int m = 0; m < _board->
objPoints.size(); m++) {
77 for(
int j = 0; j < 3; j++) {
80 pf -= Point2f(minX, minY);
81 pf.x = pf.x / sizeX * float(out.cols);
82 pf.y = (1.0f - pf.y / sizeY) *
float(out.rows);
87 Size dst_sz(outCorners[2] - outCorners[0]);
89 double diag = std::round(std::hypot(dst_sz.width, dst_sz.height));
90 int side = std::round(diag / std::sqrt(2));
91 side = std::max(side, 10);
93 dictionary.
drawMarker(_board->
ids[m], side, marker, borderBits);
95 cvtColor(marker, marker, COLOR_GRAY2RGB);
99 inCorners[0] = Point2f(-0.5
f, -0.5
f);
100 inCorners[1] = Point2f(marker.cols - 0.5f, -0.5f);
101 inCorners[2] = Point2f(marker.cols - 0.5f, marker.rows - 0.5f);
104 Mat transformation = getAffineTransform(inCorners, outCorners);
105 warpAffine(marker, out, transformation, out.size(), INTER_LINEAR,
111 Size wholeSize;
Point ofs;
112 out.locateROI(wholeSize, ofs);
113 auto out_copy = _img.getMat();
115 cv::Point center(ofs.x - minX / sizeX *
float(out.cols), ofs.y + out.rows + minY / sizeY *
float(out.rows));
117 int axis_points[3][2] = {{300, 0}, {0, -300}, {-150, 150}};
119 Scalar colors[] = {Scalar(255, 0, 0), Scalar(0, 255, 0), Scalar(0, 0, 255)};
120 String names[] = {
"X",
"Y",
"Z"};
125 for(
int poly = 2; poly >= 0; poly--){
126 double alpha =
atan2(0 - axis_points[poly][0], 0 - axis_points[poly][1]);
127 float x_delta = r_half *
cos(alpha);
128 float y_delta = r_half *
sin(alpha);
130 Point polygon_vertices[1][3];
131 polygon_vertices[0][0] = center +
Point(axis_points[poly][0] + x_delta, axis_points[poly][1] - y_delta);
132 polygon_vertices[0][1] = center + Point(axis_points[poly][0] - x_delta, axis_points[poly][1] + y_delta);
133 polygon_vertices[0][2] = center + Point(axis_points[poly][0] - sin(alpha) * height, axis_points[poly][1] - cos(alpha) * height);
135 const Point* ppt[1] = {polygon_vertices[0]};
138 fillPoly(out_copy, ppt, npt, 1, colors[poly]);
139 putText(out_copy, names[poly], center + axis_names[poly], FONT_HERSHEY_SIMPLEX, 1.2, colors[poly], 7);
140 line(out_copy, center, center + Point(axis_points[poly][0], axis_points[poly][1]), colors[poly], 10);
146 static void linePartial(InputOutputArray image, Point3f p1, Point3f p2,
const Scalar& color,
147 int thickness = 1,
int lineType = LINE_8,
int shift = 0)
150 if (p1.z <= 0 && p2.z <= 0) {
153 Point2f p1p{p1.x, p1.y};
154 Point2f p2p{p2.x, p2.y};
156 if (p1.z * p2.z < 0) {
164 float alpha = p1.z / (p1.z - p2.z);
165 Point2f pi{(1 - alpha) * p1.x + alpha * p2.x, (1 - alpha) * p1.y + alpha * p2.y};
173 line(image, p1p, p2p, color, thickness, lineType, shift);
176 void _drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _distCoeffs,
177 InputArray _rvec, InputArray _tvec,
float length) {
179 CV_Assert(_image.getMat().total() != 0 &&
180 (_image.getMat().channels() == 1 || _image.getMat().channels() == 3));
181 CV_Assert(length > 0);
184 std::vector<Point3f> axisPoints;
185 axisPoints.push_back(Point3f(0, 0, 0));
186 axisPoints.push_back(Point3f(length, 0, 0));
187 axisPoints.push_back(Point3f(0, length, 0));
188 axisPoints.push_back(Point3f(0, 0, length));
189 std::vector<Point3f> imagePointsZ;
190 _projectPoints(axisPoints, _rvec, _tvec, _cameraMatrix, _distCoeffs, imagePointsZ);
193 linePartial(_image, imagePointsZ[0], imagePointsZ[1], Scalar(0, 0, 255), 3);
194 linePartial(_image, imagePointsZ[0], imagePointsZ[2], Scalar(0, 255, 0), 3);
195 linePartial(_image, imagePointsZ[0], imagePointsZ[3], Scalar(255, 0, 0), 3);
201 CV_DbgAssert(m.dims <= 2);
202 self = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data);
203 self.step = (int)m.step[0];
204 self.type = (
self.type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG);
211 InputArray _cameraMatrix,
212 InputArray _distCoeffs,
213 OutputArray _ipoints,
214 OutputArray _jacobian,
217 Mat opoints = _opoints.getMat();
218 int npoints = opoints.checkVector(3), depth = opoints.depth();
219 CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_64F));
221 CvMat dpdrot, dpdt, dpdf, dpdc, dpddist;
222 CvMat *pdpdrot = 0, *pdpdt = 0, *pdpdf = 0, *pdpdc = 0, *pdpddist = 0;
224 CV_Assert(_ipoints.needed());
226 _ipoints.create(npoints, 1, CV_MAKETYPE(depth, 3), -1,
true);
227 Mat imagePoints = _ipoints.getMat();
228 CvMat c_imagePoints =
_cvMat(imagePoints);
229 CvMat c_objectPoints =
_cvMat(opoints);
230 Mat cameraMatrix = _cameraMatrix.getMat();
232 Mat rvec = _rvec.getMat(), tvec = _tvec.getMat();
233 CvMat c_cameraMatrix =
_cvMat(cameraMatrix);
236 double dc0buf[5] = {0};
237 Mat dc0(5, 1, CV_64F, dc0buf);
238 Mat distCoeffs = _distCoeffs.getMat();
239 if (distCoeffs.empty())
241 CvMat c_distCoeffs =
_cvMat(distCoeffs);
242 int ndistCoeffs = distCoeffs.rows + distCoeffs.cols - 1;
245 if (_jacobian.needed())
247 _jacobian.create(npoints * 2, 3 + 3 + 2 + 2 + ndistCoeffs, CV_64F);
248 jacobian = _jacobian.getMat();
249 pdpdrot = &(dpdrot =
_cvMat(jacobian.colRange(0, 3)));
250 pdpdt = &(dpdt =
_cvMat(jacobian.colRange(3, 6)));
251 pdpdf = &(dpdf =
_cvMat(jacobian.colRange(6, 8)));
252 pdpdc = &(dpdc =
_cvMat(jacobian.colRange(8, 10)));
253 pdpddist = &(dpddist =
_cvMat(jacobian.colRange(10, 10 + ndistCoeffs)));
256 _cvProjectPoints2(&c_objectPoints, &c_rvec, &c_tvec, &c_cameraMatrix, &c_distCoeffs,
257 &c_imagePoints, pdpdrot, pdpdt, pdpdf, pdpdc, pdpddist, aspectRatio);
262 template <
typename FLOAT>
265 Matx<FLOAT, 3, 3>* matTilt = 0,
266 Matx<FLOAT, 3, 3>* dMatTiltdTauX = 0,
267 Matx<FLOAT, 3, 3>* dMatTiltdTauY = 0,
268 Matx<FLOAT, 3, 3>* invMatTilt = 0)
270 FLOAT cTauX =
cos(tauX);
271 FLOAT sTauX =
sin(tauX);
272 FLOAT cTauY =
cos(tauY);
273 FLOAT sTauY =
sin(tauY);
274 Matx<FLOAT, 3, 3> matRotX = Matx<FLOAT, 3, 3>(1,0,0,0,cTauX,sTauX,0,-sTauX,cTauX);
275 Matx<FLOAT, 3, 3> matRotY = Matx<FLOAT, 3, 3>(cTauY,0,-sTauY,0,1,0,sTauY,0,cTauY);
276 Matx<FLOAT, 3, 3> matRotXY = matRotY * matRotX;
277 Matx<FLOAT, 3, 3> matProjZ = Matx<FLOAT, 3, 3>(matRotXY(2,2),0,-matRotXY(0,2),0,matRotXY(2,2),-matRotXY(1,2),0,0,1);
281 *matTilt = matProjZ * matRotXY;
286 Matx<FLOAT, 3, 3> dMatRotXYdTauX = matRotY * Matx<FLOAT, 3, 3>(0,0,0,0,-sTauX,cTauX,0,-cTauX,-sTauX);
287 Matx<FLOAT, 3, 3> dMatProjZdTauX = Matx<FLOAT, 3, 3>(dMatRotXYdTauX(2,2),0,-dMatRotXYdTauX(0,2),
288 0,dMatRotXYdTauX(2,2),-dMatRotXYdTauX(1,2),0,0,0);
289 *dMatTiltdTauX = (matProjZ * dMatRotXYdTauX) + (dMatProjZdTauX * matRotXY);
294 Matx<FLOAT, 3, 3> dMatRotXYdTauY = Matx<FLOAT, 3, 3>(-sTauY,0,-cTauY,0,0,0,cTauY,0,-sTauY) * matRotX;
295 Matx<FLOAT, 3, 3> dMatProjZdTauY = Matx<FLOAT, 3, 3>(dMatRotXYdTauY(2,2),0,-dMatRotXYdTauY(0,2),
296 0,dMatRotXYdTauY(2,2),-dMatRotXYdTauY(1,2),0,0,0);
297 *dMatTiltdTauY = (matProjZ * dMatRotXYdTauY) + (dMatProjZdTauY * matRotXY);
301 FLOAT inv = 1./matRotXY(2,2);
302 Matx<FLOAT, 3, 3> invMatProjZ = Matx<FLOAT, 3, 3>(inv,0,inv*matRotXY(0,2),0,inv,inv*matRotXY(1,2),0,0,1);
303 *invMatTilt = matRotXY.t()*invMatProjZ;
308 static const char*
cvDistCoeffErr =
"Distortion coefficients must be 1x4, 4x1, 1x5, 5x1, 1x8, 8x1, 1x12, 12x1, 1x14 or 14x1 floating-point vector";
314 const CvMat* distCoeffs,
315 CvMat* imagePoints, CvMat* dpdr CV_DEFAULT(NULL),
316 CvMat* dpdt CV_DEFAULT(NULL), CvMat* dpdf CV_DEFAULT(NULL),
317 CvMat* dpdc CV_DEFAULT(NULL), CvMat* dpdk CV_DEFAULT(NULL),
318 CvMat* dpdo CV_DEFAULT(NULL),
319 double aspectRatio CV_DEFAULT(0) )
322 Ptr<CvMat> _dpdr, _dpdt, _dpdc, _dpdf, _dpdk;
326 int calc_derivatives;
327 const CvPoint3D64f* M;
329 double r[3], R[9], dRdr[27],
t[3], a[9], k[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, fx, fy, cx, cy;
330 Matx33d matTilt = Matx33d::eye();
331 Matx33d dMatTiltdTauX(0,0,0,0,0,0,0,-1,0);
332 Matx33d dMatTiltdTauY(0,0,0,0,0,0,1,0,0);
333 CvMat _r, _t, _a = cvMat( 3, 3, CV_64F, a ), _k;
334 CvMat matR = cvMat( 3, 3, CV_64F, R ), _dRdr = cvMat( 3, 9, CV_64F, dRdr );
335 double *dpdr_p = 0, *dpdt_p = 0, *dpdk_p = 0, *dpdf_p = 0, *dpdc_p = 0;
337 int dpdr_step = 0, dpdt_step = 0, dpdk_step = 0, dpdf_step = 0, dpdc_step = 0;
339 bool fixedAspectRatio = aspectRatio > FLT_EPSILON;
341 if( !CV_IS_MAT(objectPoints) || !CV_IS_MAT(r_vec) ||
342 !CV_IS_MAT(t_vec) || !CV_IS_MAT(A) || !CV_IS_MAT(imagePoints) )
344 CV_Error( CV_StsBadArg,
"One of required arguments is not a valid matrix" );
346 int total = objectPoints->rows * objectPoints->cols * CV_MAT_CN(objectPoints->type);
350 CV_Error( CV_StsBadArg,
"Homogeneous coordinates are not supported" );
354 if( CV_IS_CONT_MAT(objectPoints->type) &&
355 (CV_MAT_DEPTH(objectPoints->type) == CV_32F || CV_MAT_DEPTH(objectPoints->type) == CV_64F)&&
356 ((objectPoints->rows == 1 && CV_MAT_CN(objectPoints->type) == 3) ||
357 (objectPoints->rows == count && CV_MAT_CN(objectPoints->type)*objectPoints->cols == 3) ||
358 (objectPoints->rows == 3 && CV_MAT_CN(objectPoints->type) == 1 && objectPoints->cols == count)))
360 matM.reset(cvCreateMat( objectPoints->rows, objectPoints->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(objectPoints->type)) ));
361 cvConvert(objectPoints, matM);
367 CV_Error( CV_StsBadArg,
"Homogeneous coordinates are not supported" );
370 if( CV_IS_CONT_MAT(imagePoints->type) &&
371 (CV_MAT_DEPTH(imagePoints->type) == CV_32F || CV_MAT_DEPTH(imagePoints->type) == CV_64F) &&
372 ((imagePoints->rows == 1 && CV_MAT_CN(imagePoints->type) == 3) ||
373 (imagePoints->rows == count && CV_MAT_CN(imagePoints->type)*imagePoints->cols == 3) ||
374 (imagePoints->rows == 3 && CV_MAT_CN(imagePoints->type) == 1 && imagePoints->cols == count)))
376 _m.reset(cvCreateMat( imagePoints->rows, imagePoints->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(imagePoints->type)) ));
377 cvConvert(imagePoints, _m);
382 CV_Error( CV_StsBadArg,
"Homogeneous coordinates are not supported" );
385 M = (CvPoint3D64f*)matM->data.db;
386 m = (CvPoint3D64f*)_m->data.db;
388 if( (CV_MAT_DEPTH(r_vec->type) != CV_64F && CV_MAT_DEPTH(r_vec->type) != CV_32F) ||
389 (((r_vec->rows != 1 && r_vec->cols != 1) ||
390 r_vec->rows*r_vec->cols*CV_MAT_CN(r_vec->type) != 3) &&
391 ((r_vec->rows != 3 && r_vec->cols != 3) || CV_MAT_CN(r_vec->type) != 1)))
392 CV_Error( CV_StsBadArg,
"Rotation must be represented by 1x3 or 3x1 " 393 "floating-point rotation vector, or 3x3 rotation matrix" );
395 if( r_vec->rows == 3 && r_vec->cols == 3 )
397 _r = cvMat( 3, 1, CV_64FC1, r );
398 cvRodrigues2( r_vec, &_r );
399 cvRodrigues2( &_r, &matR, &_dRdr );
400 cvCopy( r_vec, &matR );
404 _r = cvMat( r_vec->rows, r_vec->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(r_vec->type)), r );
405 cvConvert( r_vec, &_r );
406 cvRodrigues2( &_r, &matR, &_dRdr );
409 if( (CV_MAT_DEPTH(t_vec->type) != CV_64F && CV_MAT_DEPTH(t_vec->type) != CV_32F) ||
410 (t_vec->rows != 1 && t_vec->cols != 1) ||
411 t_vec->rows*t_vec->cols*CV_MAT_CN(t_vec->type) != 3 )
412 CV_Error( CV_StsBadArg,
413 "Translation vector must be 1x3 or 3x1 floating-point vector" );
415 _t = cvMat( t_vec->rows, t_vec->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(t_vec->type)), t );
416 cvConvert( t_vec, &_t );
418 if( (CV_MAT_TYPE(A->type) != CV_64FC1 && CV_MAT_TYPE(A->type) != CV_32FC1) ||
419 A->rows != 3 || A->cols != 3 )
420 CV_Error( CV_StsBadArg,
"Instrinsic parameters must be 3x3 floating-point matrix" );
423 fx = a[0]; fy = a[4];
424 cx = a[2]; cy = a[5];
426 if( fixedAspectRatio )
431 if( !CV_IS_MAT(distCoeffs) ||
432 (CV_MAT_DEPTH(distCoeffs->type) != CV_64F &&
433 CV_MAT_DEPTH(distCoeffs->type) != CV_32F) ||
434 (distCoeffs->rows != 1 && distCoeffs->cols != 1) ||
435 (distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 4 &&
436 distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 5 &&
437 distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 8 &&
438 distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 12 &&
439 distCoeffs->rows*distCoeffs->cols*CV_MAT_CN(distCoeffs->type) != 14) )
440 CV_Error( CV_StsBadArg, cvDistCoeffErr );
442 _k = cvMat( distCoeffs->rows, distCoeffs->cols,
443 CV_MAKETYPE(CV_64F,CV_MAT_CN(distCoeffs->type)), k );
444 cvConvert( distCoeffs, &_k );
445 if(k[12] != 0 || k[13] != 0)
448 &matTilt, &dMatTiltdTauX, &dMatTiltdTauY);
454 if( !CV_IS_MAT(dpdr) ||
455 (CV_MAT_TYPE(dpdr->type) != CV_32FC1 &&
456 CV_MAT_TYPE(dpdr->type) != CV_64FC1) ||
457 dpdr->rows != count*2 || dpdr->cols != 3 )
458 CV_Error( CV_StsBadArg,
"dp/drot must be 2Nx3 floating-point matrix" );
460 if( CV_MAT_TYPE(dpdr->type) == CV_64FC1 )
462 _dpdr.reset(cvCloneMat(dpdr));
465 _dpdr.reset(cvCreateMat( 2*count, 3, CV_64FC1 ));
466 dpdr_p = _dpdr->data.db;
467 dpdr_step = _dpdr->step/
sizeof(dpdr_p[0]);
472 if( !CV_IS_MAT(dpdt) ||
473 (CV_MAT_TYPE(dpdt->type) != CV_32FC1 &&
474 CV_MAT_TYPE(dpdt->type) != CV_64FC1) ||
475 dpdt->rows != count*2 || dpdt->cols != 3 )
476 CV_Error( CV_StsBadArg,
"dp/dT must be 2Nx3 floating-point matrix" );
478 if( CV_MAT_TYPE(dpdt->type) == CV_64FC1 )
480 _dpdt.reset(cvCloneMat(dpdt));
483 _dpdt.reset(cvCreateMat( 2*count, 3, CV_64FC1 ));
484 dpdt_p = _dpdt->data.db;
485 dpdt_step = _dpdt->step/
sizeof(dpdt_p[0]);
490 if( !CV_IS_MAT(dpdf) ||
491 (CV_MAT_TYPE(dpdf->type) != CV_32FC1 && CV_MAT_TYPE(dpdf->type) != CV_64FC1) ||
492 dpdf->rows != count*2 || dpdf->cols != 2 )
493 CV_Error( CV_StsBadArg,
"dp/df must be 2Nx2 floating-point matrix" );
495 if( CV_MAT_TYPE(dpdf->type) == CV_64FC1 )
497 _dpdf.reset(cvCloneMat(dpdf));
500 _dpdf.reset(cvCreateMat( 2*count, 2, CV_64FC1 ));
501 dpdf_p = _dpdf->data.db;
502 dpdf_step = _dpdf->step/
sizeof(dpdf_p[0]);
507 if( !CV_IS_MAT(dpdc) ||
508 (CV_MAT_TYPE(dpdc->type) != CV_32FC1 && CV_MAT_TYPE(dpdc->type) != CV_64FC1) ||
509 dpdc->rows != count*2 || dpdc->cols != 2 )
510 CV_Error( CV_StsBadArg,
"dp/dc must be 2Nx2 floating-point matrix" );
512 if( CV_MAT_TYPE(dpdc->type) == CV_64FC1 )
514 _dpdc.reset(cvCloneMat(dpdc));
517 _dpdc.reset(cvCreateMat( 2*count, 2, CV_64FC1 ));
518 dpdc_p = _dpdc->data.db;
519 dpdc_step = _dpdc->step/
sizeof(dpdc_p[0]);
524 if( !CV_IS_MAT(dpdk) ||
525 (CV_MAT_TYPE(dpdk->type) != CV_32FC1 && CV_MAT_TYPE(dpdk->type) != CV_64FC1) ||
526 dpdk->rows != count*2 || (dpdk->cols != 14 && dpdk->cols != 12 && dpdk->cols != 8 && dpdk->cols != 5 && dpdk->cols != 4 && dpdk->cols != 2) )
527 CV_Error( CV_StsBadArg,
"dp/df must be 2Nx14, 2Nx12, 2Nx8, 2Nx5, 2Nx4 or 2Nx2 floating-point matrix" );
530 CV_Error( CV_StsNullPtr,
"distCoeffs is NULL while dpdk is not" );
532 if( CV_MAT_TYPE(dpdk->type) == CV_64FC1 )
534 _dpdk.reset(cvCloneMat(dpdk));
537 _dpdk.reset(cvCreateMat( dpdk->rows, dpdk->cols, CV_64FC1 ));
538 dpdk_p = _dpdk->data.db;
539 dpdk_step = _dpdk->step/
sizeof(dpdk_p[0]);
544 if( !CV_IS_MAT( dpdo ) || ( CV_MAT_TYPE( dpdo->type ) != CV_32FC1
545 && CV_MAT_TYPE( dpdo->type ) != CV_64FC1 )
546 || dpdo->rows != count * 2 || dpdo->cols != count * 3 )
547 CV_Error( CV_StsBadArg,
"dp/do must be 2Nx3N floating-point matrix" );
549 if( CV_MAT_TYPE( dpdo->type ) == CV_64FC1 )
551 _dpdo.reset( cvCloneMat( dpdo ) );
554 _dpdo.reset( cvCreateMat( 2 * count, 3 * count, CV_64FC1 ) );
556 dpdo_p = _dpdo->data.db;
557 dpdo_step = _dpdo->step /
sizeof( dpdo_p[0] );
560 calc_derivatives = dpdr || dpdt || dpdf || dpdc || dpdk || dpdo;
562 for( i = 0; i < count; i++ )
564 double X = M[i].x, Y = M[i].y, Z = M[i].z;
565 double x = R[0]*X + R[1]*Y + R[2]*Z + t[0];
566 double y = R[3]*X + R[4]*Y + R[5]*Z + t[1];
567 double z = R[6]*X + R[7]*Y + R[8]*Z + t[2];
568 double r2, r4, r6, a1, a2, a3, cdist, icdist2;
569 double xd, yd, xd0, yd0, invProj;
585 cdist = 1 + k[0]*r2 + k[1]*r4 + k[4]*r6;
586 icdist2 = 1./(1 + k[5]*r2 + k[6]*r4 + k[7]*r6);
587 xd0 = x*cdist*icdist2 + k[2]*a1 + k[3]*a2 + k[8]*r2+k[9]*r4;
588 yd0 = y*cdist*icdist2 + k[2]*a3 + k[3]*a1 + k[10]*r2+k[11]*r4;
591 vecTilt = matTilt*Vec3d(xd0, yd0, 1);
592 invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
593 xd = invProj * vecTilt(0);
594 yd = invProj * vecTilt(1);
600 if( calc_derivatives )
604 dpdc_p[0] = 1; dpdc_p[1] = 0;
605 dpdc_p[dpdc_step] = 0;
606 dpdc_p[dpdc_step+1] = 1;
607 dpdc_p += dpdc_step*2;
612 if( fixedAspectRatio )
614 dpdf_p[0] = 0; dpdf_p[1] = xd*aspectRatio;
615 dpdf_p[dpdf_step] = 0;
616 dpdf_p[dpdf_step+1] = yd;
620 dpdf_p[0] = xd; dpdf_p[1] = 0;
621 dpdf_p[dpdf_step] = 0;
622 dpdf_p[dpdf_step+1] = yd;
624 dpdf_p += dpdf_step*2;
626 for (
int row = 0; row < 2; ++row)
627 for (
int col = 0; col < 2; ++col)
628 dMatTilt(row,col) = matTilt(row,col)*vecTilt(2)
629 - matTilt(2,col)*vecTilt(row);
630 double invProjSquare = (invProj*invProj);
631 dMatTilt *= invProjSquare;
634 dXdYd = dMatTilt*Vec2d(x*icdist2*r2, y*icdist2*r2);
635 dpdk_p[0] = fx*dXdYd(0);
636 dpdk_p[dpdk_step] = fy*dXdYd(1);
637 dXdYd = dMatTilt*Vec2d(x*icdist2*r4, y*icdist2*r4);
638 dpdk_p[1] = fx*dXdYd(0);
639 dpdk_p[dpdk_step+1] = fy*dXdYd(1);
640 if( _dpdk->cols > 2 )
642 dXdYd = dMatTilt*Vec2d(a1, a3);
643 dpdk_p[2] = fx*dXdYd(0);
644 dpdk_p[dpdk_step+2] = fy*dXdYd(1);
645 dXdYd = dMatTilt*Vec2d(a2, a1);
646 dpdk_p[3] = fx*dXdYd(0);
647 dpdk_p[dpdk_step+3] = fy*dXdYd(1);
648 if( _dpdk->cols > 4 )
650 dXdYd = dMatTilt*Vec2d(x*icdist2*r6, y*icdist2*r6);
651 dpdk_p[4] = fx*dXdYd(0);
652 dpdk_p[dpdk_step+4] = fy*dXdYd(1);
654 if( _dpdk->cols > 5 )
656 dXdYd = dMatTilt*Vec2d(
657 x*cdist*(-icdist2)*icdist2*r2, y*cdist*(-icdist2)*icdist2*r2);
658 dpdk_p[5] = fx*dXdYd(0);
659 dpdk_p[dpdk_step+5] = fy*dXdYd(1);
660 dXdYd = dMatTilt*Vec2d(
661 x*cdist*(-icdist2)*icdist2*r4, y*cdist*(-icdist2)*icdist2*r4);
662 dpdk_p[6] = fx*dXdYd(0);
663 dpdk_p[dpdk_step+6] = fy*dXdYd(1);
664 dXdYd = dMatTilt*Vec2d(
665 x*cdist*(-icdist2)*icdist2*r6, y*cdist*(-icdist2)*icdist2*r6);
666 dpdk_p[7] = fx*dXdYd(0);
667 dpdk_p[dpdk_step+7] = fy*dXdYd(1);
668 if( _dpdk->cols > 8 )
670 dXdYd = dMatTilt*Vec2d(r2, 0);
671 dpdk_p[8] = fx*dXdYd(0);
672 dpdk_p[dpdk_step+8] = fy*dXdYd(1);
673 dXdYd = dMatTilt*Vec2d(r4, 0);
674 dpdk_p[9] = fx*dXdYd(0);
675 dpdk_p[dpdk_step+9] = fy*dXdYd(1);
676 dXdYd = dMatTilt*Vec2d(0, r2);
677 dpdk_p[10] = fx*dXdYd(0);
678 dpdk_p[dpdk_step+10] = fy*dXdYd(1);
679 dXdYd = dMatTilt*Vec2d(0, r4);
680 dpdk_p[11] = fx*dXdYd(0);
681 dpdk_p[dpdk_step+11] = fy*dXdYd(1);
682 if( _dpdk->cols > 12 )
684 dVecTilt = dMatTiltdTauX * Vec3d(xd0, yd0, 1);
685 dpdk_p[12] = fx * invProjSquare * (
686 dVecTilt(0) * vecTilt(2) - dVecTilt(2) * vecTilt(0));
687 dpdk_p[dpdk_step+12] = fy*invProjSquare * (
688 dVecTilt(1) * vecTilt(2) - dVecTilt(2) * vecTilt(1));
689 dVecTilt = dMatTiltdTauY * Vec3d(xd0, yd0, 1);
690 dpdk_p[13] = fx * invProjSquare * (
691 dVecTilt(0) * vecTilt(2) - dVecTilt(2) * vecTilt(0));
692 dpdk_p[dpdk_step+13] = fy * invProjSquare * (
693 dVecTilt(1) * vecTilt(2) - dVecTilt(2) * vecTilt(1));
699 dpdk_p += dpdk_step*2;
704 double dxdt[] = { z, 0, -x*z }, dydt[] = { 0, z, -y*z };
705 for( j = 0; j < 3; j++ )
707 double dr2dt = 2*x*dxdt[j] + 2*y*dydt[j];
708 double dcdist_dt = k[0]*dr2dt + 2*k[1]*r2*dr2dt + 3*k[4]*r4*dr2dt;
709 double dicdist2_dt = -icdist2*icdist2*(k[5]*dr2dt + 2*k[6]*r2*dr2dt + 3*k[7]*r4*dr2dt);
710 double da1dt = 2*(x*dydt[j] + y*dxdt[j]);
711 double dmxdt = (dxdt[j]*cdist*icdist2 + x*dcdist_dt*icdist2 + x*cdist*dicdist2_dt +
712 k[2]*da1dt + k[3]*(dr2dt + 4*x*dxdt[j]) + k[8]*dr2dt + 2*r2*k[9]*dr2dt);
713 double dmydt = (dydt[j]*cdist*icdist2 + y*dcdist_dt*icdist2 + y*cdist*dicdist2_dt +
714 k[2]*(dr2dt + 4*y*dydt[j]) + k[3]*da1dt + k[10]*dr2dt + 2*r2*k[11]*dr2dt);
715 dXdYd = dMatTilt*Vec2d(dmxdt, dmydt);
716 dpdt_p[j] = fx*dXdYd(0);
717 dpdt_p[dpdt_step+j] = fy*dXdYd(1);
719 dpdt_p += dpdt_step*2;
726 X*dRdr[0] + Y*dRdr[1] + Z*dRdr[2],
727 X*dRdr[9] + Y*dRdr[10] + Z*dRdr[11],
728 X*dRdr[18] + Y*dRdr[19] + Z*dRdr[20]
732 X*dRdr[3] + Y*dRdr[4] + Z*dRdr[5],
733 X*dRdr[12] + Y*dRdr[13] + Z*dRdr[14],
734 X*dRdr[21] + Y*dRdr[22] + Z*dRdr[23]
738 X*dRdr[6] + Y*dRdr[7] + Z*dRdr[8],
739 X*dRdr[15] + Y*dRdr[16] + Z*dRdr[17],
740 X*dRdr[24] + Y*dRdr[25] + Z*dRdr[26]
742 for( j = 0; j < 3; j++ )
744 double dxdr = z*(dx0dr[j] - x*dz0dr[j]);
745 double dydr = z*(dy0dr[j] - y*dz0dr[j]);
746 double dr2dr = 2*x*dxdr + 2*y*dydr;
747 double dcdist_dr = (k[0] + 2*k[1]*r2 + 3*k[4]*r4)*dr2dr;
748 double dicdist2_dr = -icdist2*icdist2*(k[5] + 2*k[6]*r2 + 3*k[7]*r4)*dr2dr;
749 double da1dr = 2*(x*dydr + y*dxdr);
750 double dmxdr = (dxdr*cdist*icdist2 + x*dcdist_dr*icdist2 + x*cdist*dicdist2_dr +
751 k[2]*da1dr + k[3]*(dr2dr + 4*x*dxdr) + (k[8] + 2*r2*k[9])*dr2dr);
752 double dmydr = (dydr*cdist*icdist2 + y*dcdist_dr*icdist2 + y*cdist*dicdist2_dr +
753 k[2]*(dr2dr + 4*y*dydr) + k[3]*da1dr + (k[10] + 2*r2*k[11])*dr2dr);
754 dXdYd = dMatTilt*Vec2d(dmxdr, dmydr);
755 dpdr_p[j] = fx*dXdYd(0);
756 dpdr_p[dpdr_step+j] = fy*dXdYd(1);
758 dpdr_p += dpdr_step*2;
763 double dxdo[] = { z * ( R[0] - x * z * z0 * R[6] ),
764 z * ( R[1] - x * z * z0 * R[7] ),
765 z * ( R[2] - x * z * z0 * R[8] ) };
766 double dydo[] = { z * ( R[3] - y * z * z0 * R[6] ),
767 z * ( R[4] - y * z * z0 * R[7] ),
768 z * ( R[5] - y * z * z0 * R[8] ) };
769 for( j = 0; j < 3; j++ )
771 double dr2do = 2 * x * dxdo[j] + 2 * y * dydo[j];
772 double dr4do = 2 * r2 * dr2do;
773 double dr6do = 3 * r4 * dr2do;
774 double da1do = 2 * y * dxdo[j] + 2 * x * dydo[j];
775 double da2do = dr2do + 4 * x * dxdo[j];
776 double da3do = dr2do + 4 * y * dydo[j];
778 = k[0] * dr2do + k[1] * dr4do + k[4] * dr6do;
779 double dicdist2_do = -icdist2 * icdist2
780 * ( k[5] * dr2do + k[6] * dr4do + k[7] * dr6do );
781 double dxd0_do = cdist * icdist2 * dxdo[j]
782 + x * icdist2 * dcdist_do + x * cdist * dicdist2_do
783 + k[2] * da1do + k[3] * da2do + k[8] * dr2do
785 double dyd0_do = cdist * icdist2 * dydo[j]
786 + y * icdist2 * dcdist_do + y * cdist * dicdist2_do
787 + k[2] * da3do + k[3] * da1do + k[10] * dr2do
789 dXdYd = dMatTilt * Vec2d( dxd0_do, dyd0_do );
790 dpdo_p[i * 3 + j] = fx * dXdYd( 0 );
791 dpdo_p[dpdo_step + i * 3 + j] = fy * dXdYd( 1 );
793 dpdo_p += dpdo_step * 2;
798 if( _m != imagePoints )
799 cvConvert( _m, imagePoints );
802 cvConvert( _dpdr, dpdr );
805 cvConvert( _dpdt, dpdt );
808 cvConvert( _dpdf, dpdf );
811 cvConvert( _dpdc, dpdc );
814 cvConvert( _dpdk, dpdk );
817 cvConvert( _dpdo, dpdo );
824 const CvMat* distCoeffs,
825 CvMat* imagePoints, CvMat* dpdr,
826 CvMat* dpdt, CvMat* dpdf,
827 CvMat* dpdc, CvMat* dpdk,
831 dpdf, dpdc, dpdk, NULL, aspectRatio );
static const char * cvDistCoeffErr
InputArrayOfArrays const Ptr< CharucoBoard > Size InputOutputArray cameraMatrix
CV_WRAP void drawMarker(int id, int sidePixels, OutputArray _img, int borderBits=1) const
Draw a canonical marker image.
InputArrayOfArrays const Ptr< CharucoBoard > Size InputOutputArray InputOutputArray distCoeffs
geometry_msgs::TransformStamped t
CV_PROP Ptr< Dictionary > dictionary
the dictionary of markers employed for this board
static void _projectPoints(InputArray objectPoints, InputArray rvec, InputArray tvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray imagePoints, OutputArray jacobian=noArray(), double aspectRatio=0)
static CvMat _cvMat(const cv::Mat &m)
void _drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _distCoeffs, InputArray _rvec, InputArray _tvec, float length)
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
double min(double a, double b)
CV_PROP std::vector< std::vector< Point3f > > objPoints
static void linePartial(InputOutputArray image, Point3f p1, Point3f p2, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
void computeTiltProjectionMatrix(FLOAT tauX, FLOAT tauY, Matx< FLOAT, 3, 3 > *matTilt=0, Matx< FLOAT, 3, 3 > *dMatTiltdTauX=0, Matx< FLOAT, 3, 3 > *dMatTiltdTauY=0, Matx< FLOAT, 3, 3 > *invMatTilt=0)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void _drawPlanarBoard(Board *_board, Size outSize, OutputArray _img, int marginSize, int borderBits, bool drawAxis)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
CV_PROP std::vector< int > ids
static void _cvProjectPoints2Internal(const CvMat *objectPoints, const CvMat *r_vec, const CvMat *t_vec, const CvMat *A, const CvMat *distCoeffs, CvMat *imagePoints, CvMat *dpdr CV_DEFAULT(NULL), CvMat *dpdt CV_DEFAULT(NULL), CvMat *dpdf CV_DEFAULT(NULL), CvMat *dpdc CV_DEFAULT(NULL), CvMat *dpdk CV_DEFAULT(NULL), CvMat *dpdo CV_DEFAULT(NULL), double aspectRatio CV_DEFAULT(0))
static void _cvProjectPoints2(const CvMat *object_points, const CvMat *rotation_vector, const CvMat *translation_vector, const CvMat *camera_matrix, const CvMat *distortion_coeffs, CvMat *image_points, CvMat *dpdrot CV_DEFAULT(NULL), CvMat *dpdt CV_DEFAULT(NULL), CvMat *dpdf CV_DEFAULT(NULL), CvMat *dpdc CV_DEFAULT(NULL), CvMat *dpddist CV_DEFAULT(NULL), double aspect_ratio CV_DEFAULT(0))
double max(double a, double b)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Dictionary/Set of markers. It contains the inner codification.
CV_EXPORTS_W void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs, InputArray rvec, InputArray tvec, float length)
Draw coordinate system axis from pose estimation.