cvcalibration.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 2,039 行 · 第 1/5 页

SVN-BASE
2,039
字号
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"

/****************************************************************************************/
/****************************************************************************************/
/****************************************************************************************/
/* TYPES AND DEFINITIONS */

#include <stdio.h>

#define icvCvt_32f_64d  icvCvt_32f64f
#define icvCvt_64d_32f  icvCvt_64f32f

CvStatus icvFindHomography( int numPoints,
                            CvSize imageSize,
                            CvPoint2D64d * imagePoints,

                            CvPoint2D64d * objectPoints, CvMatr64d Homography );

CvStatus icvInitIntrinsicParams( int numImages,
                                 int *numPoints,
                                 CvSize imageSize,
                                 CvPoint2D64d * imagePoints,
                                 CvPoint2D64d * objectPoints,
                                 CvVect64d focalLength,
                                 CvPoint2D64d * principalPoint,

                                 CvVect64d distortion, CvMatr64d cameraMatrix );

CvStatus icvNormalizeImagePoints( int numPoints,
                                  CvPoint2D64d * ImagePoints,
                                  CvVect64d focalLength,
                                  CvPoint2D64d principalPoint,
                                  CvVect64d distortion, CvPoint3D64d * resImagePoints );

CvStatus icvRigidMotionTransform( int numPoints,
                                  CvPoint3D64d * objectPoints,
                                  CvVect64d rotVect, CvVect64d transVect,
                                  CvPoint3D64d * rigidMotionTrans,/* Output points */
                                  CvMatr64d derivMotionRot, CvMatr64d derivMotionTrans );

CvStatus icvSVDSym_64d( CvMatr64d LtL, CvVect64d resV, int num );

/****************************************************************************************/
/*F//////////////////////////////////////////////////////////////////////////////////////
//    Name: icvFindHomography
//    Purpose: Finds homography for image points and it's projection on image
//    Context:
//    Parameters:  numPoints    - number of points
//                 imageSize    - size of image
//                 imagePoints  - vector of image points coordinates
//                 objectPoints - vector of object points coordinates on 2D etalon
//                 Homography   - found homography matrix 3x3
//
//F*/
CvStatus
icvFindHomography( int numPoints,
                   CvSize imageSize,
                   CvPoint2D64d * imagePoints,
                   CvPoint2D64d * objectPoints, CvMatr64d Homography )
{                               /* Find homography for one image */

    CvPoint2D64d *normPoints;
    CvPoint3D64d *mPoints;
    CvPoint3D64d *mNormPoints;
    CvMatr64d L;
    double mxx, myy;
    double scxx, scyy;
    int t;
    int base1, base2;
    int iter;

    /* Optimization */
    CvMatr64d mrep;
    CvMatr64d J;
    CvMatr64d Jtran;

    CvMatr64d MMM;
    CvMatr64d M;
    CvVect64d m_err;
    double m1, m2, m3;
    double mm2_1, mm2_2;
    double mm3_1, mm3_2;
    double coef;
    double Hnorm[9];
    double Hrem[9];
    double H[9];
    double invHnorm[9];
    double LtL[9 * 9];
    double JtJ[8 * 8];
    double invJtJ[8 * 8];
    double tmp8[8];
    double hh_innov[8];
    double hhv[8];
    double hhv_up[8];

    imageSize = imageSize;

    /* Test right parameters */
    if( numPoints <= 0 ||       /* !!! Need to know minimal number of points */
        imagePoints == 0 || objectPoints == 0 )
    {
        return CV_BADPOINT_ERR;
    }

    /* Create matrix for homography */
    normPoints = (CvPoint2D64d *) icvCreateVector_64d( numPoints * 2 );

    mrep = icvCreateMatrix_64d( numPoints, 3 );
    J = icvCreateMatrix_64d( 8, 2 * numPoints );
    Jtran = icvCreateMatrix_64d( 2 * numPoints, 8 );
    MMM = icvCreateMatrix_64d( numPoints, 3 );
    M = icvCreateMatrix_64d( numPoints, 3 );
    m_err = icvCreateVector_64d( 2 * numPoints );
    mPoints = (CvPoint3D64d *) icvCreateVector_64d( numPoints * 3 );
    mNormPoints = (CvPoint3D64d *) icvCreateVector_64d( numPoints * 3 );
    L = icvCreateMatrix_64d( 9, 2 * numPoints );

    /* Prenormalixation of point coordinates */
    mxx = 0;
    myy = 0;
    for( t = 0; t < numPoints; t++ )
    {
        mxx += imagePoints[t].x;
        myy += imagePoints[t].y;
    }

    mxx /= numPoints;
    myy /= numPoints;

    for( t = 0; t < numPoints; t++ )
    {
        normPoints[t].x = imagePoints[t].x - mxx;
        normPoints[t].y = imagePoints[t].y - myy;
    }

    scxx = 0;
    scyy = 0;

    for( t = 0; t < numPoints; t++ )
    {
        scxx += fabs( normPoints[t].x );
        scyy += fabs( normPoints[t].y );
    }
    scxx /= numPoints;
    scyy /= numPoints;

    /* Create matrix M from points */

    for( t = 0; t < numPoints; t++ )
    {
        M[numPoints * 0 + t] = objectPoints[t].x;
        M[numPoints * 1 + t] = objectPoints[t].y;
        M[numPoints * 2 + t] = 1.0f;
    }

    /* Create initial homography matrix */

    Hnorm[0] = 1.0f / scxx;
    Hnorm[1] = 0.0f;
    Hnorm[2] = -mxx / scxx;

    Hnorm[3] = 0.0;
    Hnorm[4] = 1.0f / scyy;
    Hnorm[5] = -myy / scyy;

    Hnorm[6] = 0.0f;
    Hnorm[7] = 0.0f;
    Hnorm[8] = 1.0f;

    invHnorm[0] = scxx;
    invHnorm[1] = 0.0f;
    invHnorm[2] = mxx;

    invHnorm[3] = 0.0f;
    invHnorm[4] = scyy;
    invHnorm[5] = myy;

    invHnorm[6] = 0.0f;
    invHnorm[7] = 0.0f;
    invHnorm[8] = 1.0f;

    /* Create matrix with 1 */
    /* Test memory allocation */

    for( t = 0; t < numPoints; t++ )
    {
        mPoints[t].x = imagePoints[t].x;
        mPoints[t].y = imagePoints[t].y;
        mPoints[t].z = 1.0f;
    }

    /* Apply this initial homography */
    /* mn = H * m */

    for( t = 0; t < numPoints; t++ )
    {
        icvTransformVector_64d( Hnorm,
                                 (double *) &(mPoints[t]),
                                 (double *) &(mNormPoints[t]), 3, 3 );
    }

    /* Compute homography between m and mn */
    /* Build the matrix L */

    /* Fill matrix by values */

    for( t = 0; t < numPoints; t++ )
    {
        base1 = t * 18;
        base2 = t * 18 + 9;

        L[base1] = objectPoints[t].x;
        L[base1 + 1] = objectPoints[t].y;
        L[base1 + 2] = 1.0f;
        L[base1 + 3] = 0.0f;
        L[base1 + 4] = 0.0f;
        L[base1 + 5] = 0.0f;
        L[base1 + 6] = -mNormPoints[t].x * objectPoints[t].x;
        L[base1 + 7] = -mNormPoints[t].x * objectPoints[t].y;
        L[base1 + 8] = -mNormPoints[t].x;

        L[base2] = 0.0f;
        L[base2 + 1] = 0.0f;
        L[base2 + 2] = 0.0f;
        L[base2 + 3] = objectPoints[t].x;
        L[base2 + 4] = objectPoints[t].y;
        L[base2 + 5] = 1.0f;
        L[base2 + 6] = -mNormPoints[t].y * objectPoints[t].x;
        L[base2 + 7] = -mNormPoints[t].y * objectPoints[t].y;
        L[base2 + 8] = -mNormPoints[t].y;

    }

    if( numPoints > 4 )
    {
        icvMulTransMatrixR_64d( L, 9, 2 * numPoints, LtL );
    }

    /*   SVD   */
    icvSVDSym_64d( LtL, Hrem, 9 );

    icvScaleVector_64d( Hrem, Hrem, 9, 1.0f / Hrem[8] );

    icvMulMatrix_64d( invHnorm, 3, 3, Hrem, 3, 3, H );

    icvCopyVector_64d( H, 9, Homography );

    icvCopyVector_64d( Homography, 8, hhv );

    if( numPoints > 4 )
    {
        /* Optimization */
        for( iter = 0; iter < 10; iter++ )
        {
            icvMulMatrix_64d( H, 3, 3, M, numPoints, 3, mrep );

            /* Fill matrix J using temp MMM */
            for( t = 0; t < numPoints; t++ )
            {
                coef = mrep[numPoints * 2 + t];

                m1 = -M[numPoints * 0 + t] / coef;
                m2 = -M[numPoints * 1 + t] / coef;
                m3 = -M[numPoints * 2 + t] / coef;

                mm2_1 = (mrep[numPoints * 0 + t] / coef) * (-m1);
                mm2_2 = (mrep[numPoints * 0 + t] / coef) * (-m2);

                mm3_1 = (mrep[numPoints * 1 + t] / coef) * (-m1);
                mm3_2 = (mrep[numPoints * 1 + t] / coef) * (-m2);

                base1 = 16 * t;
                base2 = 16 * t + 8;

                J[base1 + 0] = m1;
                J[base1 + 1] = m2;
                J[base1 + 2] = m3;
                J[base1 + 3] = 0.0f;
                J[base1 + 4] = 0.0f;
                J[base1 + 5] = 0.0f;
                J[base1 + 6] = mm2_1;
                J[base1 + 7] = mm2_2;

                J[base2 + 0] = 0.0f;
                J[base2 + 1] = 0.0f;
                J[base2 + 2] = 0.0f;
                J[base2 + 3] = m1;
                J[base2 + 4] = m2;
                J[base2 + 5] = m3;
                J[base2 + 6] = mm3_1;
                J[base2 + 7] = mm3_2;

                /* Compute error */
                m_err[t * 2] = imagePoints[t].x - mrep[numPoints * 0 + t] / coef;
                m_err[t * 2 + 1] = imagePoints[t].y - mrep[numPoints * 1 + t] / coef;

            }

            /* Compute JtJ */
            icvMulTransMatrixR_64d( J, 8, 2 * numPoints, JtJ );
            /* Compute trans J */
            icvTransposeMatrix_64d( J, 8, 2 * numPoints, Jtran );

            /* Compute inv(Jtj) matrix */
            icvInvertMatrix_64d( JtJ, 8, invJtJ );

            /* Compute hh_innov */
            icvTransformVector_64d( Jtran, m_err, tmp8, 2 * numPoints, 8 );

            icvTransformVector_64d( invJtJ, tmp8, hh_innov, 8, 8 );

            icvSubVector_64d( hhv, hh_innov, hhv_up, 8 );

            /* Create new H matrix */
            icvCopyVector_64d( hhv_up, 8, hhv );

            icvCopyVector_64d( hhv_up, 8, H );

            H[8] = 1.0f;
        }
    }

    icvCopyVector_64d( H, 9, Homography );

    /* Free allocated memory */
    icvDeleteMatrix( mrep );
    icvDeleteMatrix( J );
    icvDeleteMatrix( Jtran );
    icvDeleteMatrix( MMM );
    icvDeleteMatrix( M );
    icvDeleteVector( normPoints );
    icvDeleteVector( m_err );
    icvDeleteVector( mPoints );
    icvDeleteVector( mNormPoints );
    icvDeleteMatrix( L );

    return CV_NO_ERR;
}

/*======================================================================================*/
/*F//////////////////////////////////////////////////////////////////////////////////////
//    Name: icvSVDSym_64d
//    Purpose: Singular Value Decomposition for symmetric matrix
//    Context:
//    Parameters:  LtL - sourece simmetric matrix
//                 reV - resulting vector of eigen values
//                 num - size of matrix
//
//F*/
CvStatus
icvSVDSym_64d( CvMatr64d LtL, CvVect64d resV, int num )
{
    CvMatr64d V;
    CvVect64d E;
    int haveFound;
    int t;

    V = icvCreateMatrix_64d( num, num );
    E = icvCreateVector_64d( num );

    icvJacobiEigens_64d( LtL, V, E, num, 0.0 );

    /* Find first minimul eigen value != 0 */
    haveFound = 0;
    for( t = num - 1; t >= 0; t++ )
    {
        if( E[t] != 0.0 )
        {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?