OptimalNewCameraMatrix.patch

Patrick Mihelich, 2011-07-07 02:21 am

Download (10.4 kB)

 
modules/calib3d/include/opencv2/calib3d/calib3d.hpp (working copy)
120 120
                                         CvSize image_size, double alpha,
121 121
                                         CvMat* new_camera_matrix,
122 122
                                         CvSize new_imag_size CV_DEFAULT(cvSize(0,0)),
123
                                         CvRect* valid_pixel_ROI CV_DEFAULT(0) );
123
                                         CvRect* valid_pixel_ROI CV_DEFAULT(0),
124
                                         int center_principal_point CV_DEFAULT(0));
124 125

  
125 126
/* Converts rotation vector to rotation matrix or vice versa */
126 127
CVAPI(int) cvRodrigues2( const CvMat* src, CvMat* dst,
......
622 623
//! returns the optimal new camera matrix
623 624
CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs,
624 625
                                            Size imageSize, double alpha, Size newImgSize=Size(),
625
                                            CV_OUT Rect* validPixROI=0);
626
                                            CV_OUT Rect* validPixROI=0, bool centerPrincipalPoint=false);
626 627

  
627 628
//! converts point coordinates from normal pixel coordinates to homogeneous coordinates ((x,y)->(x,y,1))
628 629
CV_EXPORTS_W void convertPointsToHomogeneous( InputArray src, OutputArray dst );
modules/calib3d/doc/camera_calibration_and_3d_reconstruction.rst (working copy)
779 779
-----------------------------
780 780
Returns the new camera matrix based on the free scaling parameter.
781 781

  
782
.. ocv:function:: Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, double alpha, Size newImageSize=Size(), Rect* validPixROI=0)
782
.. ocv:function:: Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, double alpha, Size newImageSize=Size(), Rect* validPixROI=0, bool centerPrincipalPoint=false)
783 783

  
784 784
.. ocv:pyfunction:: cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha[, newImgSize]) -> retval, validPixROI
785 785

  
786
.. ocv:cfunction:: void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCoeffs, CvSize imageSize, double alpha, CvMat* newCameraMatrix, CvSize newImageSize=cvSize(0, 0), CvRect* validPixROI=0 )
786
.. ocv:cfunction:: void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCoeffs, CvSize imageSize, double alpha, CvMat* newCameraMatrix, CvSize newImageSize=cvSize(0, 0), CvRect* validPixROI=0, int centerPrincipalPoint=0)
787 787
.. ocv:pyoldfunction:: cv.GetOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha, newCameraMatrix, newImageSize=(0, 0), validPixROI=0) -> None
788 788

  
789 789
    :param cameraMatrix: Input camera matrix.
......
799 799
    :param newImageSize: Image size after rectification. By default,it is set to  ``imageSize`` .
800 800

  
801 801
    :param validPixROI: Optional output rectangle that outlines all-good-pixels region in the undistorted image. See  ``roi1, roi2``  description in  :ocv:func:`StereoRectify` .
802

  
803
    :param centerPrincipalPoint: Indicates whether in the new camera matrix the principal point should be at the image center or not. By default, the principal point is chosen to best fit a subset of the source image (determined by ``alpha``) to the corrected image.
802 804
    
803 805
The function computes and returns
804 806
the optimal new camera matrix based on the free scaling parameter. By varying  this parameter, you may retrieve only sensible pixels ``alpha=0`` , keep all the original image pixels if there is valuable information in the corners ``alpha=1`` , or get something in between. When ``alpha>0`` , the undistortion result is likely to have some black pixels corresponding to "virtual" pixels outside of the captured distorted image. The original camera matrix, distortion coefficients, the computed new camera matrix, and ``newImageSize`` should be passed to
......
1409 1411

  
1410 1412
.. [Hartley99] Hartley, R.I., “Theory and Practice of Projective Rectification”. IJCV 35 2, pp 115-127 (1999)
1411 1413

  
1412
.. [Zhang2000] Z. Zhang. A Flexible New Technique for Camera Calibration. IEEE Transactions on Pattern Analysis and Machine Intelligence, 22(11):1330-1334, 2000.
1414
.. [Zhang2000] Z. Zhang. A Flexible New Technique for Camera Calibration. IEEE Transactions on Pattern Analysis and Machine Intelligence, 22(11):1330-1334, 2000.
modules/calib3d/src/calibration.cpp (working copy)
2529 2529
void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCoeffs,
2530 2530
                                  CvSize imgSize, double alpha,
2531 2531
                                  CvMat* newCameraMatrix, CvSize newImgSize,
2532
                                  CvRect* validPixROI )
2532
                                  CvRect* validPixROI, int centerPrincipalPoint )
2533 2533
{
2534 2534
    cv::Rect_<float> inner, outer;
2535
    icvGetRectangles( cameraMatrix, distCoeffs, 0, cameraMatrix, imgSize, inner, outer );
2536

  
2537 2535
    newImgSize = newImgSize.width*newImgSize.height != 0 ? newImgSize : imgSize;
2538 2536

  
2539 2537
    double M[3][3];
2540 2538
    CvMat matM = cvMat(3, 3, CV_64F, M);
2541 2539
    cvConvert(cameraMatrix, &matM);
2542 2540

  
2543
    double cx0 = M[0][2];
2544
    double cy0 = M[1][2];
2545
    double cx = (newImgSize.width-1)*0.5;
2546
    double cy = (newImgSize.height-1)*0.5;
2541
    if( centerPrincipalPoint )
2542
    {
2543
        double cx0 = M[0][2];
2544
        double cy0 = M[1][2];
2545
        double cx = (newImgSize.width-1)*0.5;
2546
        double cy = (newImgSize.height-1)*0.5;
2547 2547

  
2548
    double s0 = std::max(std::max(std::max((double)cx/(cx0 - inner.x), (double)cy/(cy0 - inner.y)),
2549
                        (double)cx/(inner.x + inner.width - cx0)),
2550
                    (double)cy/(inner.y + inner.height - cy0));
2551
    double s1 = std::min(std::min(std::min((double)cx/(cx0 - outer.x), (double)cy/(cy0 - outer.y)),
2552
                        (double)cx/(outer.x + outer.width - cx0)),
2553
                    (double)cy/(outer.y + outer.height - cy0));
2554
    double s = s0*(1 - alpha) + s1*alpha;
2548
        icvGetRectangles( cameraMatrix, distCoeffs, 0, cameraMatrix, imgSize, inner, outer );
2549
        double s0 = std::max(std::max(std::max((double)cx/(cx0 - inner.x), (double)cy/(cy0 - inner.y)),
2550
                                      (double)cx/(inner.x + inner.width - cx0)),
2551
                             (double)cy/(inner.y + inner.height - cy0));
2552
        double s1 = std::min(std::min(std::min((double)cx/(cx0 - outer.x), (double)cy/(cy0 - outer.y)),
2553
                                      (double)cx/(outer.x + outer.width - cx0)),
2554
                             (double)cy/(outer.y + outer.height - cy0));
2555
        double s = s0*(1 - alpha) + s1*alpha;
2555 2556

  
2556
    M[0][0] *= s;
2557
    M[1][1] *= s;
2558
    M[0][2] = cx;
2559
    M[1][2] = cy;
2560
    cvConvert(&matM, newCameraMatrix);
2557
        M[0][0] *= s;
2558
        M[1][1] *= s;
2559
        M[0][2] = cx;
2560
        M[1][2] = cy;
2561 2561

  
2562
    if( validPixROI )
2562
        if( validPixROI )
2563
        {
2564
            inner = cv::Rect_<float>((float)((inner.x - cx0)*s + cx),
2565
                                     (float)((inner.y - cy0)*s + cy),
2566
                                     (float)(inner.width*s),
2567
                                     (float)(inner.height*s));
2568
            cv::Rect r(cvCeil(inner.x), cvCeil(inner.y), cvFloor(inner.width), cvFloor(inner.height));
2569
            r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height);
2570
            *validPixROI = r;
2571
        }
2572
    }
2573
    else
2563 2574
    {
2564
        inner = cv::Rect_<float>((float)((inner.x - cx0)*s + cx),
2565
                             (float)((inner.y - cy0)*s + cy),
2566
                             (float)(inner.width*s),
2567
                             (float)(inner.height*s));
2568
        cv::Rect r(cvCeil(inner.x), cvCeil(inner.y), cvFloor(inner.width), cvFloor(inner.height));
2569
        r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height);
2570
        *validPixROI = r;
2575
        // Get inscribed and circumscribed rectangles in normalized
2576
        // (independent of camera matrix) coordinates
2577
        icvGetRectangles( cameraMatrix, distCoeffs, 0, 0, imgSize, inner, outer );
2578

  
2579
        // Projection mapping inner rectangle to viewport
2580
        double fx0 = (newImgSize.width  - 1) / inner.width;
2581
        double fy0 = (newImgSize.height - 1) / inner.height;
2582
        double cx0 = -fx0 * inner.x;
2583
        double cy0 = -fy0 * inner.y;
2584

  
2585
        // Projection mapping outer rectangle to viewport
2586
        double fx1 = (newImgSize.width  - 1) / outer.width;
2587
        double fy1 = (newImgSize.height - 1) / outer.height;
2588
        double cx1 = -fx1 * outer.x;
2589
        double cy1 = -fy1 * outer.y;
2590

  
2591
        // Interpolate between the two optimal projections
2592
        M[0][0] = fx0*(1 - alpha) + fx1*alpha;
2593
        M[1][1] = fy0*(1 - alpha) + fy1*alpha;
2594
        M[0][2] = cx0*(1 - alpha) + cx1*alpha;
2595
        M[1][2] = cy0*(1 - alpha) + cy1*alpha;
2596

  
2597
        if( validPixROI )
2598
        {
2599
            icvGetRectangles( cameraMatrix, distCoeffs, 0, newCameraMatrix, imgSize, inner, outer );
2600
            cv::Rect r = inner;
2601
            r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height);
2602
            *validPixROI = r;
2603
        }
2571 2604
    }
2605

  
2606
    cvConvert(&matM, newCameraMatrix);
2572 2607
}
2573 2608

  
2574 2609

  
......
3520 3555
cv::Mat cv::getOptimalNewCameraMatrix( InputArray _cameraMatrix,
3521 3556
                                       InputArray _distCoeffs,
3522 3557
                                       Size imgSize, double alpha, Size newImgSize,
3523
                                       Rect* validPixROI )
3558
                                       Rect* validPixROI, bool centerPrincipalPoint )
3524 3559
{
3525 3560
    Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
3526 3561
    CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
......
3530 3565
    
3531 3566
    cvGetOptimalNewCameraMatrix(&c_cameraMatrix, &c_distCoeffs, imgSize,
3532 3567
                                alpha, &c_newCameraMatrix,
3533
                                newImgSize, (CvRect*)validPixROI);
3568
                                newImgSize, (CvRect*)validPixROI, (int)centerPrincipalPoint);
3534 3569
    return newCameraMatrix;
3535 3570
}
3536 3571