cvcolor.cpp.svn-base

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

SVN-BASE
920
字号
ICV_COLORCVT_FUNC( BGRA2GRAY, 8u_C4C1R, uchar, 4, 1 )
ICV_COLORCVT_FUNC( RGBA2GRAY, 8u_C4C1R, uchar, 4, 1 )
ICV_COLORCVT_FUNC( GRAY2BGR, 8u_C1C3R, uchar, 1, 3 )
ICV_COLORCVT_FUNC( GRAY2BGRA, 8u_C1C4R, uchar, 1, 4 )
ICV_COLORCVT_FUNC( GRAY2BGR565, 8u_C1C2R, uchar, 1, 2 )
ICV_COLORCVT_FUNC( BGR5652GRAY, 8u_C2C1R, uchar, 2, 1 )
ICV_COLORCVT_FUNC( BGR2BGR565, 8u_C3C2R, uchar, 3, 2 )
ICV_COLORCVT_FUNC( RGB2BGR565, 8u_C3C2R, uchar, 3, 2 )
ICV_COLORCVT_FUNC( BGRA2BGR565, 8u_C4C2R, uchar, 4, 2 )
ICV_COLORCVT_FUNC( RGBA2BGR565, 8u_C4C2R, uchar, 4, 2 )
ICV_COLORCVT_FUNC( BGR5652BGR, 8u_C2C3R, uchar, 2, 3 )
ICV_COLORCVT_FUNC( BGR5652RGB, 8u_C2C3R, uchar, 2, 3 )
ICV_COLORCVT_FUNC( BGR5652BGRA, 8u_C2C4R, uchar, 2, 4 )
ICV_COLORCVT_FUNC( BGR5652RGBA, 8u_C2C4R, uchar, 2, 4 )

ICV_COLORCVT_FUNC( BGR2XYZ, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( RGB2XYZ, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( XYZ2BGR, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( XYZ2RGB, 8u_C3R, uchar, 3, 3 )

ICV_COLORCVT_FUNC( BGR2YCrCb, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( RGB2YCrCb, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( YCrCb2BGR, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( YCrCb2RGB, 8u_C3R, uchar, 3, 3 )

ICV_COLORCVT_FUNC( BGR2HSV, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( RGB2HSV, 8u_C3R, uchar, 3, 3 )

ICV_COLORCVT_FUNC( BGR2Lab, 8u_C3R, uchar, 3, 3 )
ICV_COLORCVT_FUNC( RGB2Lab, 8u_C3R, uchar, 3, 3 )


static CvStatus
icvBayer2BGR_8u_C1C3R( const uchar* bayer, int bayerStep,
                       uchar *dst, int dstStep,
                       CvSize size, int code )
{
    int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1;
    int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR;

    if( size.width < 2 || size.height < 2 )
        return CV_BADSIZE_ERR;

    dst += dstStep + 3 + 1;
    size.height -= 2;
    size.width -= 2;

    for( ; size.height--; bayer += bayerStep, dst += dstStep )
    {
        int t0, t1;
        const uchar* bayerEnd = bayer + size.width;

        if( start_with_green )
        {
            t0 = (bayer[0] + bayer[bayerStep*2] + 1) >> 1;
            t1 = (bayer[bayerStep] + bayer[bayerStep+2] + 1) >> 1;
            dst[-blue] = (uchar)t0;
            dst[0] = bayer[bayerStep+1];
            dst[blue] = (uchar)t1;
            bayer++;
            dst += 3;
        }

        if( blue > 0 )
        {
            for( ; bayer <= bayerEnd - 2; bayer += 2, dst += 6 )
            {
                t0 = (bayer[0] + bayer[2] + bayer[bayerStep*2] +
                      bayer[bayerStep*2+2] + 2) >> 2;
                t1 = (bayer[1] + bayer[bayerStep] +
                      bayer[bayerStep+2] + bayer[bayerStep*2+1]+2) >> 2;
                dst[-1] = (uchar)t0;
                dst[0] = (uchar)t1;
                dst[1] = bayer[bayerStep+1];

                t0 = (bayer[2] + bayer[bayerStep*2+2] + 1) >> 1;
                t1 = (bayer[bayerStep+1] + bayer[bayerStep+3] + 1) >> 1;
                dst[2] = (uchar)t0;
                dst[3] = bayer[bayerStep+2];
                dst[4] = (uchar)t1;
            }
        }
        else
        {
            for( ; bayer <= bayerEnd - 2; bayer += 2, dst += 6 )
            {
                t0 = (bayer[0] + bayer[2] + bayer[bayerStep*2] +
                      bayer[bayerStep*2+2] + 2) >> 2;
                t1 = (bayer[1] + bayer[bayerStep] +
                      bayer[bayerStep+2] + bayer[bayerStep*2+1]+2) >> 2;
                dst[1] = (uchar)t0;
                dst[0] = (uchar)t1;
                dst[-1] = bayer[bayerStep+1];

                t0 = (bayer[2] + bayer[bayerStep*2+2] + 1) >> 1;
                t1 = (bayer[bayerStep+1] + bayer[bayerStep+3] + 1) >> 1;
                dst[4] = (uchar)t0;
                dst[3] = bayer[bayerStep+2];
                dst[2] = (uchar)t1;
            }
        }

        if( bayer < bayerEnd )
        {
            t0 = (bayer[0] + bayer[2] + bayer[bayerStep*2] +
                  bayer[bayerStep*2+2] + 2) >> 2;
            t1 = (bayer[1] + bayer[bayerStep] +
                  bayer[bayerStep+2] + bayer[bayerStep*2+1]+2) >> 2;
            dst[-blue] = (uchar)t0;
            dst[0] = (uchar)t1;
            dst[blue] = bayer[bayerStep+1];
            bayer++;
            dst += 3;
        }

        bayer -= size.width;
        dst -= size.width*3;

        blue = -blue;
        start_with_green = !start_with_green;
    }

    return CV_OK;
}


#define  ICV_BAYER_FUNC( cvt_case )                                 \
static CvStatus CV_STDCALL                                          \
icvCvt_##cvt_case##_8u_C1C3R( const uchar* src, int srcstep,        \
                             uchar* dst, int dststep, CvSize size ) \
{                                                                   \
    return icvBayer2BGR_8u_C1C3R( src, srcstep, dst, dststep,       \
                                  size, CV_##cvt_case );            \
}


ICV_BAYER_FUNC( BayerBG2BGR )
ICV_BAYER_FUNC( BayerGB2BGR )
ICV_BAYER_FUNC( BayerRG2BGR )
ICV_BAYER_FUNC( BayerGR2BGR )


typedef struct CvColorCvtFuncEntry
{
    void* func;
    char  src_cn;
    char  dst_cn;
    char  pixel_wise;
}
CvColorCvtFuncEntry;


static void icvInitColorCvtTable( CvColorCvtFuncEntry* tab )
{
    #define ICV_ADD_CVT_FUNC( cvt_case, scn, dcn )                                \
        tab[CV_##cvt_case].func = (void*)icvCvt_##cvt_case##_8u_C##scn##C##dcn##R;\
        tab[CV_##cvt_case].src_cn = scn; tab[CV_##cvt_case].dst_cn = dcn;         \
        tab[CV_##cvt_case].pixel_wise = 1;

    #define ICV_ADD_CVT_FUNC_C3( cvt_case )                                     \
        tab[CV_##cvt_case].func = (void*)icvCvt_##cvt_case##_8u_C3R;            \
        tab[CV_##cvt_case].src_cn = tab[CV_##cvt_case].dst_cn = 3;              \
        tab[CV_##cvt_case].pixel_wise = 1;

    #define ICV_ADD_BAYER_FUNC( cvt_case )                                      \
        tab[CV_##cvt_case].func = (void*)icvCvt_##cvt_case##_8u_C1C3R;          \
        tab[CV_##cvt_case].src_cn = 1; tab[CV_##cvt_case].dst_cn = 3;           \
        tab[CV_##cvt_case].pixel_wise = 0;


    ICV_ADD_CVT_FUNC( BGR2BGRA, 3, 4 )
    ICV_ADD_CVT_FUNC( BGRA2BGR, 4, 3 )
    ICV_ADD_CVT_FUNC( BGR2RGBA, 3, 4 )
    ICV_ADD_CVT_FUNC( BGRA2RGBA, 4, 4 )
    ICV_ADD_CVT_FUNC( RGBA2BGR, 4, 3 )
    ICV_ADD_CVT_FUNC( BGR5652GRAY, 2, 1 )
    ICV_ADD_CVT_FUNC( BGR2GRAY, 3, 1 )
    ICV_ADD_CVT_FUNC( RGB2GRAY, 3, 1 )
    ICV_ADD_CVT_FUNC( BGRA2GRAY, 4, 1 )
    ICV_ADD_CVT_FUNC( RGBA2GRAY, 4, 1 )
    ICV_ADD_CVT_FUNC( GRAY2BGR565, 1, 2 )
    ICV_ADD_CVT_FUNC( GRAY2BGR, 1, 3 )
    ICV_ADD_CVT_FUNC( GRAY2BGRA, 1, 4 )
    ICV_ADD_CVT_FUNC( BGR2BGR565, 3, 2 )
    ICV_ADD_CVT_FUNC( RGB2BGR565, 3, 2 )
    ICV_ADD_CVT_FUNC( BGRA2BGR565, 4, 2 )
    ICV_ADD_CVT_FUNC( RGBA2BGR565, 4, 2 )
    ICV_ADD_CVT_FUNC( BGR5652BGR, 2, 3 )
    ICV_ADD_CVT_FUNC( BGR5652RGB, 2, 3 )
    ICV_ADD_CVT_FUNC( BGR5652BGRA, 2, 4 )
    ICV_ADD_CVT_FUNC( BGR5652RGBA, 2, 4 )
    

    ICV_ADD_CVT_FUNC_C3( BGR2RGB )    
    ICV_ADD_CVT_FUNC_C3( BGR2XYZ )
    ICV_ADD_CVT_FUNC_C3( RGB2XYZ )
    ICV_ADD_CVT_FUNC_C3( XYZ2BGR )
    ICV_ADD_CVT_FUNC_C3( XYZ2RGB )

    ICV_ADD_CVT_FUNC_C3( BGR2YCrCb )
    ICV_ADD_CVT_FUNC_C3( RGB2YCrCb )
    ICV_ADD_CVT_FUNC_C3( YCrCb2BGR )
    ICV_ADD_CVT_FUNC_C3( YCrCb2RGB )

    ICV_ADD_CVT_FUNC_C3( BGR2HSV )
    ICV_ADD_CVT_FUNC_C3( RGB2HSV )

    ICV_ADD_CVT_FUNC_C3( BGR2Lab )
    ICV_ADD_CVT_FUNC_C3( RGB2Lab )

    ICV_ADD_BAYER_FUNC( BayerBG2BGR )
    ICV_ADD_BAYER_FUNC( BayerGB2BGR )
    ICV_ADD_BAYER_FUNC( BayerRG2BGR )
    ICV_ADD_BAYER_FUNC( BayerGR2BGR )
}


/* dst(idx) = Conversin(src(idx)) */
CV_IMPL void
cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int colorcvt_code )
{
    static CvColorCvtFuncEntry cvttab[CV_COLORCVT_MAX];
    static int inittab = 0;

    CV_FUNCNAME( "cvCvtColor" );

    __BEGIN__;
    
    CvMat srcstub, *src = (CvMat*)srcarr;
    CvMat dststub, *dst = (CvMat*)dstarr;
    CvSize size;
    CvFunc2D_2A func;
    int src_step, dst_step;
    int src_cn, dst_cn;
    
    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
    
    if( !inittab )
    {
        icvInitColorCvtTable( cvttab );
        inittab = 1;
    }

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

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

    if( CV_MAT_DEPTH( src->type ) != CV_8U )
        CV_ERROR( CV_StsUnsupportedFormat, "" );

    if( (unsigned)colorcvt_code >= CV_COLORCVT_MAX )
        CV_ERROR( CV_StsBadFlag, "" );

    src_cn = CV_MAT_CN( src->type );
    dst_cn = CV_MAT_CN( dst->type );

    // check colorcvt_code correctness in some typical cases and fix if neccessary
    switch( colorcvt_code )
    {
    case CV_GRAY2BGR:
        colorcvt_code = dst_cn == 3 ? CV_GRAY2BGR :
                        dst_cn == 4 ? CV_GRAY2BGRA : CV_GRAY2BGR565;
        break;
    case CV_BGR2GRAY:
        colorcvt_code = src_cn == 3 ? CV_BGR2GRAY :
                        src_cn == 4 ? CV_BGRA2GRAY : CV_BGR5652GRAY;
        break;
    case CV_RGB2GRAY:
        colorcvt_code = src_cn == 3 ? CV_RGB2GRAY :
                        src_cn == 4 ? CV_RGBA2GRAY : CV_BGR5652GRAY;
        break;
    }

    func = (CvFunc2D_2A)cvttab[colorcvt_code].func;

    if( !func )
        CV_ERROR( CV_StsBadFlag, "" );

    if( src_cn != cvttab[colorcvt_code].src_cn ||
        dst_cn != cvttab[colorcvt_code].dst_cn )
        CV_ERROR( CV_BadNumChannels, "" );

    size = icvGetMatSize( src );
    src_step = src->step;
    dst_step = dst->step;

    if( cvttab[colorcvt_code].pixel_wise &&
        CV_IS_MAT_CONT( src->type & dst->type ))
    {
        size.width *= size.height;
        src_step = dst_step = CV_STUB_STEP;
        size.height = 1;
    }

    IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, dst_step, size ));

    __END__;
}

/* End of file. */


⌨️ 快捷键说明

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