⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvmoments.cpp

📁 opencv库在TI DM6437上的移植,目前包括两个库cv.lib和cxcore.lib的工程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#define icvMomentsInTile_8s_CnCR  0
#define icvMomentsInTile_32s_CnCR  0
#define icvMomentsInTileBin_8s_CnCR   icvMomentsInTileBin_8u_CnCR
#define icvMomentsInTileBin_16u_CnCR   icvMomentsInTileBin_16s_CnCR
#define icvMomentsInTileBin_32s_CnCR  0

CV_DEF_INIT_FUNC_TAB_2D( MomentsInTile, CnCR )
CV_DEF_INIT_FUNC_TAB_2D( MomentsInTileBin, CnCR )

////////////////////////////////// IPP moment functions //////////////////////////////////

icvMoments_8u_C1R_t icvMoments_8u_C1R_p = 0;
icvMoments_32f_C1R_t icvMoments_32f_C1R_p = 0;
icvMomentInitAlloc_64f_t icvMomentInitAlloc_64f_p = 0;
icvMomentFree_64f_t icvMomentFree_64f_p = 0;
icvGetSpatialMoment_64f_t icvGetSpatialMoment_64f_p = 0;

typedef CvStatus (CV_STDCALL * CvMomentIPPFunc)
    ( const void* img, int step, CvSize size, void* momentstate );

CV_IMPL void
cvMoments( const void* array, CvMoments* moments, int binary )
{
    static CvFuncTable mom_tab;
    static CvFuncTable mombin_tab;
    static int inittab = 0;
    double* tiles = 0;
    void* ippmomentstate = 0;

    CV_FUNCNAME("cvMoments");

    __BEGIN__;

    int type = 0, depth, cn, pix_size;
    int coi = 0;
    int x, y, k, tile_num = 1;
    CvSize size, tile_size = { 32, 32 };
    CvMat stub, *mat = (CvMat*)array;
    CvFunc2DnC_1A1P func = 0;
    CvMomentIPPFunc ipp_func = 0;
    CvContour contour_header;
    CvSeq* contour = 0;
    CvSeqBlock block;

    if( CV_IS_SEQ( array ))
    {
        contour = (CvSeq*)array;
        if( !CV_IS_SEQ_POLYGON( contour ))
            CV_ERROR( CV_StsBadArg, "The passed sequence is not a valid contour" );
    }

    if( !inittab )
    {
        icvInitMomentsInTileCnCRTable( &mom_tab );
        icvInitMomentsInTileBinCnCRTable( &mombin_tab );
        inittab = 1;
    }
    
    if( !moments )
        CV_ERROR( CV_StsNullPtr, "" );

    memset( moments, 0, sizeof(*moments));

    if( !contour )
    {
        CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
        type = CV_MAT_TYPE( mat->type );

        if( type == CV_32SC2 || type == CV_32FC2 )
        {
            CV_CALL( contour = cvPointSeqFromMat(
                CV_SEQ_KIND_CURVE | CV_SEQ_FLAG_CLOSED,
                mat, &contour_header, &block ));
        }
    }

    if( contour )
    {
        icvContourMoments( contour, moments );
        EXIT;
    }

    type = CV_MAT_TYPE( mat->type );
    depth = CV_MAT_DEPTH( type );
    cn = CV_MAT_CN( type );
    pix_size = CV_ELEM_SIZE(type);
    size = cvGetMatSize( mat );

    if( cn > 1 && coi == 0 )
        CV_ERROR( CV_StsBadArg, "Invalid image type" );

    if( size.width <= 0 || size.height <= 0 )
    {
        EXIT;
    }

    if( type == CV_8UC1 )
        ipp_func = (CvMomentIPPFunc)icvMoments_8u_C1R_p;
    else if( type == CV_32FC1 )
        ipp_func = (CvMomentIPPFunc)icvMoments_32f_C1R_p;

    if( ipp_func && !binary )
    {
        int matstep = mat->step ? mat->step : CV_STUB_STEP;
        IPPI_CALL( icvMomentInitAlloc_64f_p( &ippmomentstate, cvAlgHintAccurate ));
        IPPI_CALL( ipp_func( mat->data.ptr, matstep, size, ippmomentstate ));
        icvGetSpatialMoment_64f_p( ippmomentstate, 0, 0, 0, cvPoint(0,0), &moments->m00 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 1, 0, 0, cvPoint(0,0), &moments->m10 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 0, 1, 0, cvPoint(0,0), &moments->m01 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 2, 0, 0, cvPoint(0,0), &moments->m20 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 1, 1, 0, cvPoint(0,0), &moments->m11 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 0, 2, 0, cvPoint(0,0), &moments->m02 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 3, 0, 0, cvPoint(0,0), &moments->m30 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 2, 1, 0, cvPoint(0,0), &moments->m21 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 1, 2, 0, cvPoint(0,0), &moments->m12 );
        icvGetSpatialMoment_64f_p( ippmomentstate, 0, 3, 0, cvPoint(0,0), &moments->m03 );
        icvCompleteMomentState( moments );
        EXIT;
    }

    func = (CvFunc2DnC_1A1P)(!binary ? mom_tab.fn_2d[depth] : mombin_tab.fn_2d[depth]);

    if( !func )
        CV_ERROR( CV_StsBadArg, cvUnsupportedFormat );

    if( depth >= CV_32S && !binary )
        tile_size = size;
    else
        tile_num = ((size.width + tile_size.width - 1)/tile_size.width)*
                   ((size.height + tile_size.height - 1)/tile_size.height);

    CV_CALL( tiles = (double*)cvAlloc( tile_num*10*sizeof(double)));

    for( y = 0, k = 0; y < size.height; y += tile_size.height )
    {
        CvSize cur_tile_size = tile_size;
        if( y + cur_tile_size.height > size.height )
            cur_tile_size.height = size.height - y;
        
        for( x = 0; x < size.width; x += tile_size.width, k++ )
        {
            if( x + cur_tile_size.width > size.width )
                cur_tile_size.width = size.width - x;

            assert( k < tile_num );

            IPPI_CALL( func( mat->data.ptr + y*mat->step + x*pix_size,
                             mat->step, cur_tile_size, cn, coi, tiles + k*10 ));
        }
    }

    icvAccumulateMoments( tiles, size, tile_size, moments );

    __END__;

    if( ippmomentstate )
        icvMomentFree_64f_p( ippmomentstate );

    cvFree( &tiles );
}

/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: cvGetHuMoments
//    Purpose: Returns Hu moments
//    Context:
//    Parameters:
//      mState  - moment structure filled by one of the icvMoments[Binary]*** function
//      HuState - pointer to output structure containing seven Hu moments
//    Returns:
//      CV_NO_ERR if success or error code
//    Notes:
//F*/
CV_IMPL void
cvGetHuMoments( CvMoments * mState, CvHuMoments * HuState )
{
    CV_FUNCNAME( "cvGetHuMoments" );

    __BEGIN__;

    if( !mState || !HuState )
        CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );

    {
        double m00s = mState->inv_sqrt_m00, m00 = m00s * m00s, s2 = m00 * m00, s3 = s2 * m00s;

        double nu20 = mState->mu20 * s2,
            nu11 = mState->mu11 * s2,
            nu02 = mState->mu02 * s2,
            nu30 = mState->mu30 * s3,
            nu21 = mState->mu21 * s3, nu12 = mState->mu12 * s3, nu03 = mState->mu03 * s3;

        double t0 = nu30 + nu12;
        double t1 = nu21 + nu03;

        double q0 = t0 * t0, q1 = t1 * t1;

        double n4 = 4 * nu11;
        double s = nu20 + nu02;
        double d = nu20 - nu02;

        HuState->hu1 = s;
        HuState->hu2 = d * d + n4 * nu11;
        HuState->hu4 = q0 + q1;
        HuState->hu6 = d * (q0 - q1) + n4 * t0 * t1;

        t0 *= q0 - 3 * q1;
        t1 *= 3 * q0 - q1;

        q0 = nu30 - 3 * nu12;
        q1 = 3 * nu21 - nu03;

        HuState->hu3 = q0 * q0 + q1 * q1;
        HuState->hu5 = q0 * t0 + q1 * t1;
        HuState->hu7 = q1 * t0 - q0 * t1;
    }

    __END__;
}


/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: cvGetSpatialMoment
//    Purpose:  Returns spatial moment(x_order, y_order) which is determined as:
//              m(x_o,y_o) = sum (x ^ x_o)*(y ^ y_o)*I(x,y)
//              0 <= x_o, y_o; x_o + y_o <= 3
//    Context:
//    Parameters:
//      mom  - moment structure filled by one of the icvMoments[Binary]*** function
//      x_order - x order of the moment
//      y_order - y order of the moment
//    Returns:
//      moment value or large negative number (-DBL_MAX) if error
//    Notes:
//F*/
CV_IMPL double
cvGetSpatialMoment( CvMoments * moments, int x_order, int y_order )
{
    int order = x_order + y_order;
    double moment = -DBL_MAX;

    CV_FUNCNAME( "cvGetSpatialMoment" );

    __BEGIN__;

    if( !moments )
        CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );
    if( (x_order | y_order) < 0 || order > 3 )
        CV_ERROR_FROM_STATUS( CV_BADRANGE_ERR );

    moment = (&(moments->m00))[order + (order >> 1) + (order > 2) * 2 + y_order];

    __END__;

    return moment;
}


/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: cvGetCentralMoment
//    Purpose:  Returns central moment(x_order, y_order) which is determined as:
//              mu(x_o,y_o) = sum ((x - xc)^ x_o)*((y - yc) ^ y_o)*I(x,y)
//              0 <= x_o, y_o; x_o + y_o <= 3,
//              (xc, yc) = (m10/m00,m01/m00) - center of gravity 
//    Context:
//    Parameters:
//      mom  - moment structure filled by one of the icvMoments[Binary]*** function
//      x_order - x order of the moment
//      y_order - y order of the moment
//    Returns:
//      moment value or large negative number (-DBL_MAX) if error
//    Notes:
//F*/
CV_IMPL double
cvGetCentralMoment( CvMoments * moments, int x_order, int y_order )
{
    int order = x_order + y_order;
    double mu = 0;

    CV_FUNCNAME( "cvGetCentralMoment" );

    __BEGIN__;

    if( !moments )
        CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );
    if( (x_order | y_order) < 0 || order > 3 )
        CV_ERROR_FROM_STATUS( CV_BADRANGE_ERR );

    if( order >= 2 )
    {
        mu = (&(moments->m00))[4 + order * 3 + y_order];
    }
    else if( order == 0 )
        mu = moments->m00;

    __END__;

    return mu;
}


/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: cvGetNormalizedCentralMoment
//    Purpose: Returns normalized central moment(x_order,y_order) which is determined as:
//             nu(x_o,y_o) = mu(x_o, y_o)/(m00 ^ (((x_o + y_o)/2) + 1))
//             0 <= x_o, y_o; x_o + y_o <= 3,
//             (xc, yc) = (m10/m00,m01/m00) - center of gravity 
//    Context:
//    Parameters:
//      mom  - moment structure filled by one of the icvMoments[Binary]*** function
//      x_order - x order of the moment
//      y_order - y order of the moment
//    Returns:
//      moment value or large negative number (-DBL_MAX) if error
//    Notes:
//F*/
CV_IMPL double
cvGetNormalizedCentralMoment( CvMoments * moments, int x_order, int y_order )
{
    int order = x_order + y_order;
    double mu = 0;
    double m00s, m00;

    CV_FUNCNAME( "cvGetCentralNormalizedMoment" );

    __BEGIN__;

    mu = cvGetCentralMoment( moments, x_order, y_order );
    CV_CHECK();

    m00s = moments->inv_sqrt_m00;
    m00 = m00s * m00s;

    while( --order >= 0 )
        m00 *= m00s;
    mu *= m00;

    __END__;

    return mu;
}


/* End of file. */

⌨️ 快捷键说明

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