cvmorph.cpp.svn-base

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

SVN-BASE
2,145
字号
        if( crows != ker_height )
        {
            if( crows < ker_height )
                break;
            /* else it is cross-shaped element: change central line */
            rows[ker_y] = tbuf;
            crows--;
        }

        tdst = (int *) dst;

        if( width_rest )
        {
            need_copy = width_n < CV_MORPH_ALIGN || y == dst_height - 1;

            if( need_copy )
                tdst = tbuf;
            else
                CV_COPY( tbuf + width_n, tdst + width_n, CV_MORPH_ALIGN, x );
        }

        for( x = 0; x < width_n; x += 4 )
        {
            int val0, val1, val2, val3;

            tsrc = rows[0];

            val0 = tsrc[x];
            val1 = tsrc[x + 1];
            val2 = tsrc[x + 2];
            val3 = tsrc[x + 3];

            for( i = 1; i < ker_height; i++ )
            {
                int s;

                tsrc = rows[i];

                s = tsrc[x + 0];
                CV_CALC_MIN( val0, s );
                s = tsrc[x + 1];
                CV_CALC_MIN( val1, s );
                s = tsrc[x + 2];
                CV_CALC_MIN( val2, s );
                s = tsrc[x + 3];
                CV_CALC_MIN( val3, s );
            }
            tdst[x + 0] = CV_TOGGLE_FLT( val0 );
            tdst[x + 1] = CV_TOGGLE_FLT( val1 );
            tdst[x + 2] = CV_TOGGLE_FLT( val2 );
            tdst[x + 3] = CV_TOGGLE_FLT( val3 );
        }

        if( width_rest )
        {
            if( need_copy )
                CV_COPY( (int *) dst, tbuf, width_n, x );
            else
                CV_COPY( tdst + width_n, tbuf + width_n, CV_MORPH_ALIGN, x );
        }

        rows[ker_y] = saved_row;

        /* rotate buffer */
        {
            int *t = rows[0];

            CV_COPY( rows, rows + 1, ker_height - 1, i );
            rows[i] = t;
            crows--;
            dst += dstStep;
        }
    }
    while( ++y < dst_height );

    roiSize->height = y;
    state->crows = crows;

    return CV_OK;
}


static CvStatus
icvErodeArb_32f( float *src, int srcStep,
                 float *dst, int dstStep, CvSize * roiSize, CvMorphState * state, int stage )
{
#define INIT_VAL  INT_MAX
    int width = roiSize->width;
    int src_height = roiSize->height;
    int dst_height = src_height;
    int x, y = 0, i;

    int ker_x = state->ker_x;
    int ker_y = state->ker_y;
    int ker_width = state->ker_width;
    int ker_height = state->ker_height;
    int ker_right = ker_width - ker_x - ((width & 1) == 0);
    char *ker_data = (char *) (state->ker1 + ker_width);

    int crows = state->crows;
    int **rows = (int **) (state->rows);
    int *tbuf = (int *) (state->tbuf);

    int channels = state->channels;
    int ker_x_n = ker_x * channels;
    int ker_width_n = ker_width * channels;
    int width_n = width * channels;

    int starting_flag = 0;
    int width_rest = width_n & (CV_MORPH_ALIGN - 1);

    /* initialize cyclic buffer when starting */
    if( stage == CV_WHOLE || stage == CV_START )
    {
        for( i = 0; i < ker_height; i++ )
        {
            rows[i] = (int *) (state->buffer + state->buffer_step * i);
        }
        crows = ker_y;
        if( stage != CV_WHOLE )
            dst_height -= ker_height - ker_y - 1;
        starting_flag = 1;
    }

    if( stage == CV_END )
        dst_height += ker_height - ker_y - 1;

    srcStep /= sizeof_float;
    dstStep /= sizeof_float;

    do
    {
        int *tsrc, *tdst;
        int need_copy = 0;

        /* fill cyclic buffer - horizontal filtering */
        for( ; crows < ker_height; crows++ )
        {
            tsrc = (int *) src;
            tdst = rows[crows];

            if( src_height-- <= 0 )
            {
                if( stage != CV_WHOLE && stage != CV_END )
                    break;
                /* duplicate last row */
                tsrc = rows[crows - 1];
                CV_COPY( tdst, tsrc, width_n + ker_width_n, x );
                continue;
            }

            src += srcStep;

            for( x = 0; x < width_n; x++ )
            {
                int t = tsrc[x];

                tdst[ker_x_n + x] = (int) CV_TOGGLE_FLT( t );
            }

            /* make replication borders */
            if( channels == 1 )
            {
                int pix = tdst[ker_x];

                CV_SET( tdst, pix, ker_x, x );

                pix = tdst[width + ker_x - 1];
                CV_SET( tdst + width + ker_x, pix, ker_right, x );
            }
            else if( channels == 3 )
            {
                CvRGB32s pix = ((CvRGB32s *) tdst)[ker_x];

                CV_SET( (CvRGB32s *) tdst, pix, ker_x, x );

                pix = ((CvRGB32s *) tdst)[width + ker_x - 1];
                CV_SET( (CvRGB32s *) tdst + width + ker_x, pix, ker_right, x );
            }
            else                /* channels == 4 */
            {
                /* make replication borders */
                CvRGBA32s pix = ((CvRGBA32s *) tdst)[ker_x];

                CV_SET( (CvRGBA32s *) tdst, pix, ker_x, x );

                pix = ((CvRGBA32s *) tdst)[width + ker_x - 1];
                CV_SET( (CvRGBA32s *) tdst + width + ker_x, pix, ker_right, x );
            }
        }

        if( starting_flag )
        {
            starting_flag = 0;
            tsrc = rows[ker_y];

            for( i = 0; i < ker_y; i++ )
            {
                tdst = rows[i];
                CV_COPY( tdst, tsrc, width_n + ker_width_n, x );
            }
        }

        /* vertical convolution */
        if( crows < ker_height )
            break;

        tdst = (int *) dst;
        if( width_rest )
        {
            need_copy = width_n < CV_MORPH_ALIGN || y == dst_height - 1;

            if( need_copy )
                tdst = tbuf;
            else
                CV_COPY( tbuf + width_n, (int *) (dst + width_n), CV_MORPH_ALIGN, x );
        }

        if( channels == 1 )
        {
            for( x = 0; x < width_n; x += 4 )
            {
                int val0 = INIT_VAL, val1 = INIT_VAL, val2 = INIT_VAL, val3 = INIT_VAL;

                char *ker = ker_data;

                for( i = 0; i < ker_height; i++, ker += ker_width )
                {
                    int j = -ker_width;

                    tsrc = rows[i] + x - j;
                    do
                    {
                        int m = ker[j];

                        if( !m )
                        {
                            int t = tsrc[j];

                            CV_CALC_MIN( val0, t );
                            t = tsrc[j + 1];
                            CV_CALC_MIN( val1, t );
                            t = tsrc[j + 2];
                            CV_CALC_MIN( val2, t );
                            t = tsrc[j + 3];
                            CV_CALC_MIN( val3, t );
                        }
                    }
                    while( ++j < 0 );
                }

                tdst[x] = (int) CV_TOGGLE_FLT( val0 );
                tdst[x + 1] = (int) CV_TOGGLE_FLT( val1 );
                tdst[x + 2] = (int) CV_TOGGLE_FLT( val2 );
                tdst[x + 3] = (int) CV_TOGGLE_FLT( val3 );
            }
        }
        else if( channels == 3 )
        {
            for( x = 0; x < width_n; x += 3 )
            {
                int val0 = INIT_VAL, val1 = INIT_VAL, val2 = INIT_VAL;

                char *ker = ker_data;

                for( i = 0; i < ker_height; i++, ker += ker_width )
                {
                    int j = -ker_width;

                    tsrc = rows[i] + x - j * 3;
                    for( ; j < 0; j++ )
                    {
                        int m = ker[j];

                        if( !m )
                        {
                            int t = tsrc[j * 3];

                            CV_CALC_MIN( val0, t );
                            t = tsrc[j * 3 + 1];
                            CV_CALC_MIN( val1, t );
                            t = tsrc[j * 3 + 2];
                            CV_CALC_MIN( val2, t );
                        }
                    }
                }

                tdst[x] = (int) CV_TOGGLE_FLT( val0 );
                tdst[x + 1] = (int) CV_TOGGLE_FLT( val1 );
                tdst[x + 2] = (int) CV_TOGGLE_FLT( val2 );
            }
        }
        else
        {
            for( x = 0; x < width_n; x += 4 )
            {
                int val0 = INIT_VAL, val1 = INIT_VAL, val2 = INIT_VAL, val3 = INIT_VAL;

                char *ker = ker_data;

                for( i = 0; i < ker_height; i++, ker += ker_width )
                {
                    int j = -ker_width;

                    tsrc = rows[i] + x - j * 4;
                    for( ; j < 0; j++ )
                    {
                        int m = ker[j];

                        if( !m )
                        {
                            int t = tsrc[j * 4];

                            CV_CALC_MIN( val0, t );
                            t = tsrc[j * 4 + 1];
                            CV_CALC_MIN( val1, t );
                            t = tsrc[j * 4 + 2];
                            CV_CALC_MIN( val2, t );
                            t = tsrc[j * 4 + 3];
                            CV_CALC_MIN( val3, t );
                        }
                    }
                }

                tdst[x] = (int) CV_TOGGLE_FLT( val0 );
                tdst[x + 1] = (int) CV_TOGGLE_FLT( val1 );
                tdst[x + 2] = (int) CV_TOGGLE_FLT( val2 );
                tdst[x + 3] = (int) CV_TOGGLE_FLT( val3 );
            }
        }

        if( width_rest )
        {
            if( need_copy )
                CV_COPY( (int *) dst, tbuf, width_n, x );
            else
                CV_COPY( (int *) (dst + width_n), tbuf + width_n, CV_MORPH_ALIGN, x );
        }

        /* rotate buffer */
        {
            int *t = rows[0];

            CV_COPY( rows, rows + 1, ker_height - 1, i );
            rows[i] = t;
            crows--;
            dst += dstStep;
        }
    }
    while( ++y < dst_height );

    roiSize->height = y;
    state->crows = crows;

    return CV_OK;
#undef INIT_VAL
}


static CvStatus
icvDilateArb_32f( float *src, int srcStep,
                  float *dst, int dstStep, CvSize * roiSize, CvMorphState * state, int stage )
{
#define INIT_VAL  INT_MIN
    int width = roiSize->width;
    int src_height = roiSize->height;
    int dst_height = src_height;
    int x, y = 0, i;

    int ker_x = state->ker_x;
    int ker_y = state->ker_y;
    int ker_width = state->ker_width;
    int ker_height = state->ker_height;
    int ker_right = ker_width - ker_x - ((width & 1) == 0);
    char *ker_data = (char *) (state->ker0 + ker_width);

    int crows = state->crows;
    int **rows = (int **) (state->rows);
    int *tbuf = (int *) (state->tbuf);

    int channels = state->channels;
    int ker_x_n = ker_x * channels;
    int ker_width_n = ker_width * channels;
    int width_n = width * channels;

    int starting_flag = 0;
    int width_rest = width_n & (CV_MORPH_ALIGN - 1);

    /* initialize cyclic buffer when starting */
    if( stage == CV_WHOLE || stage == CV_START )
    {
        for( i = 0; i < ker_height; i++ )
        {
            rows[i] = (int *) (state->buffer + state->buffer_step * i);
        }
        crows = ker_y;
        if( stage != CV_WHOLE )
            dst_height -= ker_height - ker_y - 1;
        starting_flag = 1;
    }

    if( stage == CV_END )
        dst_height += ker_height - ker_y - 1;

    srcStep /= sizeof_float;
    dstStep /= sizeof_float;

    do
    {
        int *tsrc, *tdst;
        int need_copy = 0;

        /* fill cyclic buffer - horizontal filtering */
        for( ; crows < ker_height; crows++ )
        {
            tsrc = (int *) src;
            tdst = rows[crows];

            if( src_height-- <= 0 )
            {
                if( stage != CV_WHOLE && stage != CV_END )
                    break;
                /* duplicate last row */
                tsrc = rows[crows - 1];
                CV_COPY( tdst, tsrc, width_n + ker_width_n, x );
                continue;
            }

            src += srcStep;

⌨️ 快捷键说明

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