cvfloodfill.cpp.svn-base

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

SVN-BASE
1,138
字号
        region->value = newVal;
    }

    return CV_NO_ERR;
}

/****************************************************************************************\
*                                   Gradient Floodfill                                   *
\****************************************************************************************/

#define DIFF_INT_C1(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw)<= interval)

#define DIFF_INT_C3(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw[0])<= interval[0] && \
                            (unsigned)((p1)[1] - (p2)[1] + d_lw[1])<= interval[1] && \
                            (unsigned)((p1)[2] - (p2)[2] + d_lw[2])<= interval[2])

#define DIFF_FLT_C1(p1,p2) (fabs((p1)[0] - (p2)[0] + d_lw)<= interval)

static CvStatus
icvFloodFill_Grad_8u_C1IR( uchar* pImage, int step, uchar* pMask, int maskStep,
                           CvSize /*roi*/, CvPoint seed, uchar* _newVal, uchar* _d_lw,
                           uchar* _d_up, CvConnectedComp* region, int flags,
                           CvFFillSegment* buffer, int buffersize )
{
    const int cn = 1;
    uchar* img = pImage + step*seed.y;
    uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y;
    int i, L, R;
    int area = 0;
    int sum = 0, val0[1] = {0};
    uchar newVal = _newVal[0];
    int d_lw = _d_lw[0];
    int d_up = _d_up[0];
    unsigned interval = (unsigned) (d_up + d_lw);
    int XMin, XMax, YMin = seed.y, YMax = seed.y;
    int _8_connectivity = (flags & 255) == 8;
    int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE;
    int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0;
    uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1);
    CvFFillSegment* buffer_end = buffer + buffersize, *head = buffer, *tail = buffer;

    L = R = seed.x;
    if( mask[L] )
        return CV_OK;

    mask[L] = newMaskVal;

    if( fixedRange )
    {
        val0[0] = img[seed.x];

        while( !mask[R + 1] && DIFF_INT_C1( img + (R+1)*cn, val0 ))
            mask[++R] = newMaskVal;

        while( !mask[L - 1] && DIFF_INT_C1( img + (L-1)*cn, val0 ))
            mask[--L] = newMaskVal;
    }
    else
    {
        while( !mask[R + 1] && DIFF_INT_C1( img + (R+1)*cn, img + R*cn ))
            mask[++R] = newMaskVal;

        while( !mask[L - 1] && DIFF_INT_C1( img + (L-1)*cn, img + L*cn ))
            mask[--L] = newMaskVal;
    }

    XMax = R;
    XMin = L;
    ICV_PUSH( seed.y, L, R, R + 1, R, UP );

    while( head != tail )
    {
        int k, YC, PL, PR, dir, curstep;
        ICV_POP( YC, L, R, PL, PR, dir );

        int data[][3] =
        {
            {-dir, L - _8_connectivity, R + _8_connectivity},
            {dir, L - _8_connectivity, PL - 1},
            {dir, PR + 1, R + _8_connectivity}
        };

        unsigned length = (unsigned)(R-L);

        if( region )
        {
            area += (int)length + 1;

            if( XMax < R ) XMax = R;
            if( XMin > L ) XMin = L;
            if( YMax < YC ) YMax = YC;
            if( YMin > YC ) YMin = YC;
        }

        for( k = 0; k < 3; k++ )
        {
            dir = data[k][0];
            curstep = dir * step;
            img = pImage + (YC + dir) * step;
            mask = pMask + (YC + dir) * maskStep;
            int left = data[k][1];
            int right = data[k][2];

            if( fixedRange )
            {
                for( i = left; i <= right; i++ )
                {
                    if( !mask[i] && DIFF_INT_C1( img + i*cn, val0 ))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C1( img + j*cn, val0 ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] && DIFF_INT_C1( img + i*cn, val0 ))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
            else if( !_8_connectivity )
            {
                for( i = left; i <= right; i++ )
                {
                    if( !mask[i] && DIFF_INT_C1( img + i*cn, img - curstep + i*cn ))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C1( img + j*cn, img + (j+1)*cn ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] &&
                               (DIFF_INT_C1( img + i*cn, img + (i-1)*cn ) ||
                               (DIFF_INT_C1( img + i*cn, img + i*cn - curstep) && i <= R)))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
            else
            {
                for( i = left; i <= right; i++ )
                {
                    int idx, val[1];
                    
                    if( !mask[i] &&
                        ((val[0] = img[i*cn],
                        (unsigned)(idx = i-L-1) <= length) &&
                        DIFF_INT_C1( val, img - curstep + (i-1)*cn ) ||
                        (unsigned)(++idx) <= length &&
                        DIFF_INT_C1( val, img - curstep + i*cn ) ||
                        (unsigned)(++idx) <= length &&
                        DIFF_INT_C1( val, img - curstep + (i+1)*cn )))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C1( img + j*cn, img + (j+1)*cn ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] &&
                               ((val[0] = img[i*cn],
                               DIFF_INT_C1( val, img + (i-1)*cn )) ||
                               ((unsigned)(idx = i-L-1) <= length &&
                               DIFF_INT_C1( val, img - curstep + (i-1)*cn )) ||
                               (unsigned)(++idx) <= length &&
                               DIFF_INT_C1( val, img - curstep + i*cn ) ||
                               (unsigned)(++idx) <= length &&
                               DIFF_INT_C1( val, img - curstep + (i+1)*cn )))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
        }

        img = pImage + YC * step;
        if( fillImage )
            for( i = L; i <= R; i++ )
                img[i] = newVal;
        else if( region )
            for( i = L; i <= R; i++ )
                sum += img[i];
    }
    
    if( region )
    {
        region->area = area;
        region->rect.x = XMin;
        region->rect.y = YMin;
        region->rect.width = XMax - XMin + 1;
        region->rect.height = YMax - YMin + 1;
    
        if( fillImage )
            region->value = newVal;
        else
            region->value = area ? ((double)sum)/area : 0;
    }

    return CV_NO_ERR;
}


static CvStatus
icvFloodFill_Grad_8u_C3IR( uchar* pImage, int step, uchar* pMask, int maskStep,
                           CvSize /*roi*/, CvPoint seed, uchar* _newVal, uchar* _d_lw,
                           uchar* _d_up, CvConnectedComp* region, int flags,
                           CvFFillSegment* buffer, int buffersize )
{
    const int cn = 3;
    uchar* img = pImage + step*seed.y;
    uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y;
    int i, L, R;
    int area = 0;
    int sum[3] = { 0, 0, 0 }, val0[3] = { 0, 0, 0 };
    uchar newVal[3] = {_newVal[0], _newVal[1], _newVal[2]};
    int d_lw[3] = {_d_lw[0], _d_lw[1], _d_lw[2]};
    int d_up[3] = {_d_up[0], _d_up[1], _d_up[2]};
    unsigned interval[3] =
    { (unsigned) (d_up[0] + d_lw[0]),
      (unsigned) (d_up[1] + d_lw[1]),
      (unsigned) (d_up[2] + d_lw[2])};
    int XMin, XMax, YMin = seed.y, YMax = seed.y;
    int _8_connectivity = (flags & 255) == 8;
    int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE;
    int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0;
    uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1);
    CvFFillSegment* buffer_end = buffer + buffersize, *head = buffer, *tail = buffer;

    L = R = seed.x;
    if( mask[L] )
        return CV_OK;

    mask[L] = newMaskVal;

    if( fixedRange )
    {
        val0[0] = img[seed.x*cn];
        val0[1] = img[seed.x*cn+1];
        val0[2] = img[seed.x*cn+2];

        while( DIFF_INT_C3( img + (R+1)*cn, val0 ) && !mask[R + 1] )
            mask[++R] = newMaskVal;

        while( DIFF_INT_C3( img + (L-1)*cn, val0 ) && !mask[L - 1] )
            mask[--L] = newMaskVal;
    }
    else
    {
        while( DIFF_INT_C3( img + (R+1)*cn, img + R*cn ) && !mask[R + 1] )
            mask[++R] = newMaskVal;

        while( DIFF_INT_C3( img + (L-1)*cn, img + L*cn ) && !mask[L - 1] )
            mask[--L] = newMaskVal;
    }

    XMax = R;
    XMin = L;
    ICV_PUSH( seed.y, L, R, R + 1, R, UP );

    while( head != tail )
    {
        int k, YC, PL, PR, dir, curstep;
        ICV_POP( YC, L, R, PL, PR, dir );

        int data[][3] =
        {
            {-dir, L - _8_connectivity, R + _8_connectivity},
            {dir, L - _8_connectivity, PL - 1},
            {dir, PR + 1, R + _8_connectivity}
        };

        unsigned length = (unsigned)(R-L);

        if( region )
        {
            area += (int)length + 1;

            if( XMax < R ) XMax = R;
            if( XMin > L ) XMin = L;
            if( YMax < YC ) YMax = YC;
            if( YMin > YC ) YMin = YC;
        }

        for( k = 0; k < 3; k++ )
        {
            dir = data[k][0];
            curstep = dir * step;
            img = pImage + (YC + dir) * step;
            mask = pMask + (YC + dir) * maskStep;
            int left = data[k][1];
            int right = data[k][2];

            if( fixedRange )
            {
                for( i = left; i <= right; i++ )
                {
                    if( !mask[i] && DIFF_INT_C3( img + i*cn, val0 ))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C3( img + j*cn, val0 ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] && DIFF_INT_C3( img + i*cn, val0 ))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
            else if( !_8_connectivity )
            {
                for( i = left; i <= right; i++ )
                {
                    if( !mask[i] && DIFF_INT_C3( img + i*cn, img - curstep + i*cn ))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C3( img + j*cn, img + (j+1)*cn ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] &&
                               (DIFF_INT_C3( img + i*cn, img + (i-1)*cn ) ||
                               (DIFF_INT_C3( img + i*cn, img + i*cn - curstep) && i <= R)))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
            else
            {
                for( i = left; i <= right; i++ )
                {
                    int idx, val[3];
                    
                    if( !mask[i] &&
                        ((val[0] = img[i*cn],
                          val[1] = img[i*cn+1],
                          val[2] = img[i*cn+2],
                        (unsigned)(idx = i-L-1) <= length) &&
                        DIFF_INT_C3( val, img - curstep + (i-1)*cn ) ||
                        (unsigned)(++idx) <= length &&
                        DIFF_INT_C3( val, img - curstep + i*cn ) ||
                        (unsigned)(++idx) <= length &&
                        DIFF_INT_C3( val, img - curstep + (i+1)*cn )))
                    {
                        int j = i;
                        mask[i] = newMaskVal;
                        while( !mask[--j] && DIFF_INT_C3( img + j*cn, img + (j+1)*cn ))
                            mask[j] = newMaskVal;

                        while( !mask[++i] &&
                               ((val[0] = img[i*cn],
                                 val[1] = img[i*cn+1],
                                 val[2] = img[i*cn+2],
                               DIFF_INT_C3( val, img + (i-1)*cn )) ||
                               ((unsigned)(idx = i-L-1) <= length &&
                               DIFF_INT_C3( val, img - curstep + (i-1)*cn )) ||
                               (unsigned)(++idx) <= length &&
                               DIFF_INT_C3( val, img - curstep + i*cn ) ||
                               (unsigned)(++idx) <= length &&
                               DIFF_INT_C3( val, img - curstep + (i+1)*cn )))
                            mask[i] = newMaskVal;

                        ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
                    }
                }
            }
        }

        img = pImage + YC * step;
        if( fillImage )
            for( i = L; i <= R; i++ )
            {
                img[i*3] = newVal[0];
                img[i*3+1] = newVal[1];

⌨️ 快捷键说明

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