@@ -294,15 +294,15 @@ cvInitUndistortRectifyMap( const CvMat* Aarr, const CvMat* dist_coeffs,
294
294
CV_Assert ( mapx0.data == mapx.data && mapy0.data == mapy.data );
295
295
}
296
296
297
-
298
- void cvUndistortPoints ( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
297
+ static void cvUndistortPointsInternal ( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
299
298
const CvMat* _distCoeffs,
300
- const CvMat* matR, const CvMat* matP )
299
+ const CvMat* matR, const CvMat* matP, cv::TermCriteria criteria )
301
300
{
302
301
double A[3 ][3 ], RR[3 ][3 ], k[14 ]={0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 };
303
302
CvMat matA=cvMat (3 , 3 , CV_64F, A), _Dk;
304
303
CvMat _RR=cvMat (3 , 3 , CV_64F, RR);
305
304
cv::Matx33d invMatTilt = cv::Matx33d::eye ();
305
+ cv::Matx33d matTilt = cv::Matx33d::eye ();
306
306
307
307
CV_Assert ( CV_IS_MAT (_src) && CV_IS_MAT (_dst) &&
308
308
(_src->rows == 1 || _src->cols == 1 ) &&
@@ -316,7 +316,6 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
316
316
317
317
cvConvert ( _cameraMatrix, &matA );
318
318
319
- int iters = 0 ;
320
319
321
320
if ( _distCoeffs )
322
321
{
@@ -332,9 +331,11 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
332
331
CV_MAKETYPE (CV_64F,CV_MAT_CN (_distCoeffs->type )), k);
333
332
334
333
cvConvert ( _distCoeffs, &_Dk );
335
- iters = 5 ;
336
334
if (k[12 ] != 0 || k[13 ] != 0 )
335
+ {
337
336
cv::detail::computeTiltProjectionMatrix<double >(k[12 ], k[13 ], NULL , NULL , NULL , &invMatTilt);
337
+ cv::detail::computeTiltProjectionMatrix<double >(k[12 ], k[13 ], &matTilt, NULL , NULL );
338
+ }
338
339
}
339
340
340
341
if ( matR )
@@ -373,7 +374,7 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
373
374
int n = _src->rows + _src->cols - 1 ;
374
375
for ( int i = 0 ; i < n; i++ )
375
376
{
376
- double x, y, x0 = 0 , y0 = 0 ;
377
+ double x, y, x0 = 0 , y0 = 0 , u, v ;
377
378
if ( stype == CV_32FC2 )
378
379
{
379
380
x = srcf[i*sstep].x ;
@@ -384,27 +385,61 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
384
385
x = srcd[i*sstep].x ;
385
386
y = srcd[i*sstep].y ;
386
387
}
387
-
388
+ u = x; v = y;
388
389
x = (x - cx)*ifx;
389
390
y = (y - cy)*ify;
390
391
391
- if ( iters ) {
392
+ if ( _distCoeffs ) {
392
393
// compensate tilt distortion
393
394
cv::Vec3d vecUntilt = invMatTilt * cv::Vec3d (x, y, 1 );
394
395
double invProj = vecUntilt (2 ) ? 1 ./vecUntilt (2 ) : 1 ;
395
396
x0 = x = invProj * vecUntilt (0 );
396
397
y0 = y = invProj * vecUntilt (1 );
397
- }
398
398
399
- // compensate distortion iteratively
400
- for ( int j = 0 ; j < iters; j++ )
401
- {
402
- double r2 = x*x + y*y;
403
- double icdist = (1 + ((k[7 ]*r2 + k[6 ])*r2 + k[5 ])*r2)/(1 + ((k[4 ]*r2 + k[1 ])*r2 + k[0 ])*r2);
404
- double deltaX = 2 *k[2 ]*x*y + k[3 ]*(r2 + 2 *x*x)+ k[8 ]*r2+k[9 ]*r2*r2;
405
- double deltaY = k[2 ]*(r2 + 2 *y*y) + 2 *k[3 ]*x*y+ k[10 ]*r2+k[11 ]*r2*r2;
406
- x = (x0 - deltaX)*icdist;
407
- y = (y0 - deltaY)*icdist;
399
+ double error = std::numeric_limits<double >::max ();
400
+ // compensate distortion iteratively
401
+
402
+ for ( int j = 0 ; ; j++ )
403
+ {
404
+ if ((criteria.type & cv::TermCriteria::COUNT) && j >= criteria.maxCount )
405
+ break ;
406
+ if ((criteria.type & cv::TermCriteria::EPS) && error < criteria.epsilon )
407
+ break ;
408
+ double r2 = x*x + y*y;
409
+ double icdist = (1 + ((k[7 ]*r2 + k[6 ])*r2 + k[5 ])*r2)/(1 + ((k[4 ]*r2 + k[1 ])*r2 + k[0 ])*r2);
410
+ double deltaX = 2 *k[2 ]*x*y + k[3 ]*(r2 + 2 *x*x)+ k[8 ]*r2+k[9 ]*r2*r2;
411
+ double deltaY = k[2 ]*(r2 + 2 *y*y) + 2 *k[3 ]*x*y+ k[10 ]*r2+k[11 ]*r2*r2;
412
+ x = (x0 - deltaX)*icdist;
413
+ y = (y0 - deltaY)*icdist;
414
+
415
+ if (criteria.type & cv::TermCriteria::EPS)
416
+ {
417
+ double r4, r6, a1, a2, a3, cdist, icdist2;
418
+ double xd, yd, xd0, yd0;
419
+ cv::Vec3d vecTilt;
420
+
421
+ r2 = x*x + y*y;
422
+ r4 = r2*r2;
423
+ r6 = r4*r2;
424
+ a1 = 2 *x*y;
425
+ a2 = r2 + 2 *x*x;
426
+ a3 = r2 + 2 *y*y;
427
+ cdist = 1 + k[0 ]*r2 + k[1 ]*r4 + k[4 ]*r6;
428
+ icdist2 = 1 ./(1 + k[5 ]*r2 + k[6 ]*r4 + k[7 ]*r6);
429
+ xd0 = x*cdist*icdist2 + k[2 ]*a1 + k[3 ]*a2 + k[8 ]*r2+k[9 ]*r4;
430
+ yd0 = y*cdist*icdist2 + k[2 ]*a3 + k[3 ]*a1 + k[10 ]*r2+k[11 ]*r4;
431
+
432
+ vecTilt = matTilt*cv::Vec3d (xd0, yd0, 1 );
433
+ invProj = vecTilt (2 ) ? 1 ./vecTilt (2 ) : 1 ;
434
+ xd = invProj * vecTilt (0 );
435
+ yd = invProj * vecTilt (1 );
436
+
437
+ double x_proj = xd*fx + cx;
438
+ double y_proj = yd*fy + cy;
439
+
440
+ error = sqrt ( pow (x_proj - u, 2 ) + pow (y_proj - v, 2 ) );
441
+ }
442
+ }
408
443
}
409
444
410
445
double xx = RR[0 ][0 ]*x + RR[0 ][1 ]*y + RR[0 ][2 ];
@@ -426,10 +461,27 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
426
461
}
427
462
}
428
463
464
+ void cvUndistortPoints ( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
465
+ const CvMat* _distCoeffs,
466
+ const CvMat* matR, const CvMat* matP )
467
+ {
468
+ cvUndistortPointsInternal (_src, _dst, _cameraMatrix, _distCoeffs, matR, matP,
469
+ cv::TermCriteria (cv::TermCriteria::COUNT, 5 , 0.01 ));
470
+ }
471
+
472
+ void cv::undistortPoints ( InputArray _src, OutputArray _dst,
473
+ InputArray _cameraMatrix,
474
+ InputArray _distCoeffs,
475
+ InputArray _Rmat,
476
+ InputArray _Pmat )
477
+ {
478
+ undistortPoints (_src, _dst, _cameraMatrix, _distCoeffs, TermCriteria (TermCriteria::MAX_ITER, 5 , 0.01 ), _Rmat, _Pmat);
479
+ }
429
480
430
481
void cv::undistortPoints ( InputArray _src, OutputArray _dst,
431
482
InputArray _cameraMatrix,
432
483
InputArray _distCoeffs,
484
+ TermCriteria criteria,
433
485
InputArray _Rmat,
434
486
InputArray _Pmat )
435
487
{
@@ -450,7 +502,7 @@ void cv::undistortPoints( InputArray _src, OutputArray _dst,
450
502
pP = &(matP = P);
451
503
if ( !distCoeffs.empty () )
452
504
pD = &(_cdistCoeffs = distCoeffs);
453
- cvUndistortPoints (&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP);
505
+ cvUndistortPointsInternal (&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP, criteria );
454
506
}
455
507
456
508
namespace cv
0 commit comments