cvmatmul.cpp.svn-base

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

SVN-BASE
1,586
字号
            src1->height != dst->height ||
            src2->width != dst->width )
            CV_ERROR( CV_StsUnmatchedSizes, "" );
        break;
    case 1:
        if( src1->height != src2->height ||
            src1->width != dst->height ||
            src2->width != dst->width )
            CV_ERROR( CV_StsUnmatchedSizes, "" );
        break;
    case 2:
        if( src1->width != src2->width ||
            src1->height != dst->height ||
            src2->height != dst->width )
            CV_ERROR( CV_StsUnmatchedSizes, "" );
        break;
    case 3:
        if( src1->height != src2->width ||
            src1->width != dst->height ||
            src2->height != dst->width )
            CV_ERROR( CV_StsUnmatchedSizes, "" );
        break;
    }
    
    type = CV_MAT_TYPE( src1->type );

    // general case
    {
        CvGEMMFunc func;
        CvSize size = icvGetMatSize( src1 );
        CvSize dstsize = icvGetMatSize( dst );
        int buf_size = dstsize.width*dstsize.height*icvPixSize[type];
        CvMat tmat, *tdst = dst;
        
        if( !inittab )
        {
            icvInitGEMMTable( &gemm_tab );
            inittab = 1;
        }

        if( dst->data.ptr == src1->data.ptr || dst->data.ptr == src2->data.ptr ||
            (tABC & 4) != 0 && src3 != 0 && dst->data.ptr == src3->data.ptr )
        {
            if( size.width <= CV_MAX_LOCAL_MAT_SIZE )
            {
                buffer = (uchar*)alloca( buf_size + 8 );
                buffer = (uchar*)icvAlignPtr( buffer, 8 );
                local_alloc = 1;
            }
            else
            {
                CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
            }

            CV_CALL( cvInitMatHeader( &tmat, dstsize.height,
                                      dstsize.width, type, buffer ));
            tdst = &tmat;
        }

        func = (CvGEMMFunc)(gemm_tab.fn_2d[CV_MAT_DEPTH(type)]);
        if( !func )
            CV_ERROR( CV_StsUnsupportedFormat, "" );

        IPPI_CALL( func( src1->data.ptr, src1->step, src2->data.ptr, src2->step, alpha,
                         src3->data.ptr, src3->step, beta, tdst->data.ptr, tdst->step,
                         size, dstsize, tABC ));

        if( tdst != dst )
        {
            CV_CALL( cvCopy( tdst, dst ));
        }
    }

    CV_CHECK_NANS( dst );

    __END__;

    if( buffer && !local_alloc )
        cvFree( (void**)&buffer );
}


/****************************************************************************************\
*                                        cvMatMulAddS                                    *
\****************************************************************************************/


#define  ICV_DEF_MMULADDC_CASE_C2( arrtype, temptype, src, dst, mat,        \
                                  _cast_macro1_, _cast_macro2_ )            \
{                                                                           \
    temptype t0, t1;                                                        \
                                                                            \
    t0 = _cast_macro1_((mat)[0]*(src)[0] + (mat)[1]*(src)[1] + (mat)[2]);   \
    t1 = _cast_macro1_((mat)[3]*(src)[0] + (mat)[4]*(src)[1] + (mat)[5]);   \
                                                                            \
    (dst)[0] = _cast_macro2_(t0);                                           \
    (dst)[1] = _cast_macro2_(t1);                                           \
}


#define  ICV_DEF_MMULADDC_CASE_C3( arrtype, temptype, src, dst, mat,        \
                                  _cast_macro1_, _cast_macro2_ )            \
{                                                                           \
    temptype t0, t1, t2;                                                    \
                                                                            \
    t0 = _cast_macro1_((mat)[0]*(src)[0] + (mat)[1]*(src)[1] +              \
                       (mat)[2]*(src)[2] + (mat)[3]);                       \
    t1 = _cast_macro1_((mat)[4]*(src)[0] + (mat)[5]*(src)[1] +              \
                       (mat)[6]*(src)[2] + (mat)[7]);                       \
    t2 = _cast_macro1_((mat)[8]*(src)[0] + (mat)[9]*(src)[1] +              \
                       (mat)[10]*(src)[2] + (mat)[11]);                     \
                                                                            \
    (dst)[0] = _cast_macro2_(t0);                                           \
    (dst)[1] = _cast_macro2_(t1);                                           \
    (dst)[2] = _cast_macro2_(t2);                                           \
}


#define  ICV_DEF_MMULADDC_CASE_C4( arrtype, temptype, src, dst, mat,        \
                                  _cast_macro1_, _cast_macro2_ )            \
{                                                                           \
    temptype t0, t1, t2, t3;                                                \
                                                                            \
    t0 = _cast_macro1_((mat)[0]*(src)[0] + (mat)[1]*(src)[1] +              \
                       (mat)[2]*(src)[2] + (mat)[3]*(src)[3] + (mat)[4]);   \
    t1 = _cast_macro1_((mat)[5]*(src)[0] + (mat)[6]*(src)[1] +              \
                       (mat)[7]*(src)[2] + (mat)[8]*(src)[3] + (mat)[9]);   \
    t2 = _cast_macro1_((mat)[10]*(src)[0] + (mat)[11]*(src)[1] +            \
                       (mat)[12]*(src)[2] + (mat)[13]*(src)[3] + (mat)[14]);\
    t3 = _cast_macro1_((mat)[15]*(src)[0] + (mat)[16]*(src)[1] +            \
                       (mat)[17]*(src)[2] + (mat)[18]*(src)[3] + (mat)[19]);\
                                                                            \
    (dst)[0] = _cast_macro2_(t0);                                           \
    (dst)[1] = _cast_macro2_(t1);                                           \
    (dst)[2] = _cast_macro2_(t2);                                           \
    (dst)[3] = _cast_macro2_(t3);                                           \
}



#define  ICV_DEF_MATMULADDS_FUNC( flavor, arrtype, scalartype, temptype,    \
                                  _cast_macro1_, _cast_macro2_, cn  )       \
IPCVAPI_IMPL( CvStatus,                                                     \
icvMatMulAddC_##flavor,( const arrtype* src, int srcstep,                   \
                         arrtype* dst, int dststep, CvSize size,            \
                         const scalartype* mat ))                           \
{                                                                           \
    size.width *= (cn);                                                     \
                                                                            \
    for( ; size.height--; (char*&)src += srcstep, (char*&)dst += dststep )  \
    {                                                                       \
        int i;                                                              \
        for( i = 0; i < size.width; i += (cn) )                             \
        {                                                                   \
            ICV_DEF_MMULADDC_CASE_C##cn( arrtype, temptype, src + i,        \
                         dst + i, mat, _cast_macro1_, _cast_macro2_ )       \
        }                                                                   \
    }                                                                       \
                                                                            \
    return CV_OK;                                                           \
}


ICV_DEF_MATMULADDS_FUNC( 8u_C2R, uchar, double, int, cvRound, CV_CAST_8U, 2 )
ICV_DEF_MATMULADDS_FUNC( 8u_C3R, uchar, double, int, cvRound, CV_CAST_8U, 3 )
ICV_DEF_MATMULADDS_FUNC( 8u_C4R, uchar, double, int, cvRound, CV_CAST_8U, 4 )

ICV_DEF_MATMULADDS_FUNC( 32s_C2R, int, double, int, cvRound, CV_NOP, 2 )
ICV_DEF_MATMULADDS_FUNC( 32s_C3R, int, double, int, cvRound, CV_NOP, 3 )
ICV_DEF_MATMULADDS_FUNC( 32s_C4R, int, double, int, cvRound, CV_NOP, 4 )

ICV_DEF_MATMULADDS_FUNC( 32f_C2R, float, double, double, CV_NOP, CV_CAST_32F, 2 )
ICV_DEF_MATMULADDS_FUNC( 32f_C3R, float, double, double, CV_NOP, CV_CAST_32F, 3 )
ICV_DEF_MATMULADDS_FUNC( 32f_C4R, float, double, double, CV_NOP, CV_CAST_32F, 4 )

ICV_DEF_MATMULADDS_FUNC( 64f_C2R, double, double, double, CV_NOP, CV_CAST_64F, 2 )
ICV_DEF_MATMULADDS_FUNC( 64f_C3R, double, double, double, CV_NOP, CV_CAST_64F, 3 )
ICV_DEF_MATMULADDS_FUNC( 64f_C4R, double, double, double, CV_NOP, CV_CAST_64F, 4 )


static void
icvInitMatMulAddCTable( CvBigFuncTable* tab )
{
    tab->fn_2d[CV_8UC2] = (void*)icvMatMulAddC_8u_C2R;
    tab->fn_2d[CV_8UC3] = (void*)icvMatMulAddC_8u_C3R;
    tab->fn_2d[CV_8UC4] = (void*)icvMatMulAddC_8u_C4R;

    tab->fn_2d[CV_32SC2] = (void*)icvMatMulAddC_32s_C2R;
    tab->fn_2d[CV_32SC3] = (void*)icvMatMulAddC_32s_C3R;
    tab->fn_2d[CV_32SC4] = (void*)icvMatMulAddC_32s_C4R;

    tab->fn_2d[CV_32FC2] = (void*)icvMatMulAddC_32f_C2R;
    tab->fn_2d[CV_32FC3] = (void*)icvMatMulAddC_32f_C3R;
    tab->fn_2d[CV_32FC4] = (void*)icvMatMulAddC_32f_C4R;

    tab->fn_2d[CV_64FC2] = (void*)icvMatMulAddC_64f_C2R;
    tab->fn_2d[CV_64FC3] = (void*)icvMatMulAddC_64f_C3R;
    tab->fn_2d[CV_64FC4] = (void*)icvMatMulAddC_64f_C4R;
}


CV_IMPL void
cvMatMulAddS( const CvArr* srcarr, CvArr* dstarr,
              const CvMat* transform, const CvMat* shiftvec )
{
    static CvBigFuncTable mmuladds_tab;
    static int inittab = 0;
    
    double buffer[20];
    
    CV_FUNCNAME( "cvMatMulAddS" );

    __BEGIN__;

    CvMat stub1, *src = (CvMat*)srcarr;
    CvMat stub, *dst = (CvMat*)dstarr;
    CvMat rstub, *rot = (CvMat*)transform;
    CvMat sstub, *shift = (CvMat*)shiftvec;
    CvSeq* seq = 0;
    int i, j, type, cn;

    if( !inittab )
    {
        icvInitMatMulAddCTable( &mmuladds_tab );
        inittab = 1;
    }

    if( !CV_IS_MAT( src ))
    {
        if( CV_IS_SEQ( src ))
        {
            seq = (CvSeq*)src;
            if( icvPixSize[CV_SEQ_ELTYPE(seq)] != seq->elem_size )
                CV_ERROR( CV_StsUnsupportedFormat,
                "Unsupported type of sequence elements" );
            if( dst != src && dst != 0 )
                CV_ERROR( CV_StsBadArg,
                "For sequences only inplace mode is supported" );
        }
        else
        {
            int coi = 0;
            CV_CALL( src = cvGetMat( src, &stub1, &coi ));

            if( coi != 0 )
                CV_ERROR( CV_BadCOI, "" );
        }
    }

    if( dst == 0 )
        dst = src;

    if( dst != src )
    {
        if( !CV_IS_MAT( dst ))
        {
            int coi = 0;
            CV_CALL( dst = cvGetMat( dst, &stub, &coi ));

            if( coi != 0 )
                CV_ERROR( CV_BadCOI, "" );
        }

        if( !CV_ARE_TYPES_EQ( src, dst ))
            CV_ERROR( CV_StsUnmatchedFormats, "" );

        if( !CV_ARE_SIZES_EQ( src, dst ))
            CV_ERROR( CV_StsUnmatchedSizes, "" );
    }

    type = CV_MAT_TYPE( src->type );
    cn = CV_MAT_CN( type );

    if( !CV_IS_MAT( rot ))
    {
        int coi = 0;
        CV_CALL( rot = cvGetMat( rot, &rstub, &coi ));

        if( coi != 0 )
            CV_ERROR( CV_BadCOI, "" );
    }

    if( rot->height != cn )
        CV_ERROR( CV_StsBadSize,
        "The height of transform matrix must be equal to number of channels" );

    if( rot->width == cn + 1 || rot->width == cn )
    {
        if( CV_MAT_TYPE( rot->type ) == CV_64FC1 )
        {
            for( i = 0; i < cn; i++ )
            {
                buffer[i*cn + cn-1] = 0;

                for( j = 0; j < rot->width; j++ )
                    buffer[i*cn + j] = ((double*)(rot->data.ptr + rot->step*i))[j];
            }
        }
        else if( CV_MAT_TYPE( rot->type ) == CV_32FC1 )
        {
            for( i = 0; i < cn; i++ )
            {
                buffer[i*cn + cn-1] = 0;

                for( j = 0; j < rot->width; j++ )
                    buffer[i*cn + j] = ((float*)(rot->data.ptr + rot->step*i))[j];
            }
        }
        else
        {
            CV_ERROR( CV_StsUnsupportedFormat, "Rotation matrix must be 32fC1 or 64fC1" );
        }
    }
    else
    {
        CV_ERROR( CV_StsUnmatchedSizes, "If the source array has <cn> channels, "
           "the transformation matrix must have <cn> x <cn>+1 or <cn> x <cn> size" );
    }

⌨️ 快捷键说明

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