cvderiv.cpp.svn-base

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

SVN-BASE
1,921
字号
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "_cv.h"

/****************************************************************************************\
*                                        S O B E L                                       *
\****************************************************************************************/

/* This function calculates generalized Sobel kernel */
static int icvCalcKer( char *kernel, int order, int size,
                       CvDataType datatype, int origin )
{
    int i, j;
    int* kerI = (int*)kernel;
    int type = -1;
    
    if( size != CV_SCHARR )
    {
        if( size == 3 )
        {
            switch( order )
            {
            case 0:
                kerI[0] = 1;
                kerI[1] = 2;
                kerI[2] = 1;
                type = ICV_1_2_1_KERNEL;
                break;
            case 1:
                kerI[0] =-1;
                kerI[1] = 0;
                kerI[2] = 1;
                type = ICV_m1_0_1_KERNEL;
                break;
            case 2:
                kerI[0] = 1;
                kerI[1] =-2;
                kerI[2] = 1;
                type = ICV_1_m2_1_KERNEL;
                break;
            default:
                return CV_BADARG_ERR;
            }
        }
        else
        {
            int oldval, newval;

            memset( kerI + 1, 0, size * sizeof(kerI[0]));
            kerI[0] = 1;

            for( i = 0; i < size - order - 1; i++ )
            {
                oldval = kerI[0];
                for( j = 1; j <= size; j++ )
                {
                    newval = kerI[j]+kerI[j-1];
                    kerI[j-1] = oldval;
                    oldval = newval;
                }
            }

            for( i = 0; i < order; i++ )
            {
                oldval = -kerI[0];
                for( j = 1; j <= size; j++ )
                {
                    newval = kerI[j-1] - kerI[j];
                    kerI[j-1] = oldval;
                    oldval = newval;
                }
            }

            type = order & 1 ? ICV_ASYMMETRIC_KERNEL : ICV_SYMMETRIC_KERNEL;
        }
    }
    else
    {
        size = 3;
        if( order == 1 )
        {
            kerI[0] = -1;
            kerI[1] = 0;
            kerI[2] = 1;
            type = ICV_m1_0_1_KERNEL;
        }
        else
        {
            assert( order == 0 );
            kerI[0] = kerI[2] = 3;
            kerI[1] = 10;
            type = ICV_3_10_3_KERNEL;
        }
    }

    if( origin && (order & 1) )
        for( j = 0; j < size; j++ )
            kerI[j] = -kerI[j];

    if( datatype == cv32f )
        for( j = 0; j < size; j++ )
            ((float*)kerI)[j] = (float)kerI[j];

    return type;
}


IPCVAPI_IMPL( CvStatus, icvSobelInitAlloc,(
            int roiwidth, int datatype, int size,
            int origin, int dx, int dy, CvFilterState** state ))
{
    #define MAX_KERNEL_SIZE  7
    int ker[MAX_KERNEL_SIZE*2+1];
    CvDataType worktype = datatype != cv32f ? cv32s : cv32f;
    CvStatus status;
    int x_filter_type, y_filter_type;
    int x_size = size, y_size = size;
    
    if( !state )
        return CV_NULLPTR_ERR;

    if( size == CV_SCHARR )
    {
        if( dx + dy != 1 )
            return CV_BADRANGE_ERR;
        x_size = y_size = 3;
    }
    else
    {
        if( (size&1) == 0 || size < 1 || size > MAX_KERNEL_SIZE )
            return CV_BADRANGE_ERR;

        if( (unsigned)dx > 2 || (unsigned)dy > 2 )
            return CV_BADRANGE_ERR;

        if( size == 1 )
        {
            if( dy == 0 )
                x_size = 3, y_size = 1;
            else if( dx == 0 )
                x_size = 1, y_size = 3;
            else
                return CV_BADARG_ERR;
        }
    }

    x_filter_type = icvCalcKer( (char*)ker, dx, size < 0 ? size : x_size, worktype, 0 );
    y_filter_type = icvCalcKer( (char*)(ker + x_size), dy, size < 0 ? size : y_size,
                                worktype, origin != 0 );

    status = icvFilterInitAlloc( roiwidth, worktype, 1, cvSize( x_size, y_size ),
                                 cvPoint( x_size/2, y_size/2 ), ker,
                                 ICV_MAKE_SEPARABLE_KERNEL(x_filter_type, y_filter_type),
                                 state );
    if( status < 0 )
        return status;

    (*state)->origin = origin != 0;

    return CV_OK;
}


IPCVAPI_IMPL( CvStatus, icvSobel_8u16s_C1R,(
             const uchar* pSrc, int srcStep,
             short* dst, int dstStep, CvSize* roiSize,
             CvFilterState* state, int stage ))
{
    uchar* src = (uchar*)pSrc;
    int width = roiSize->width;
    int src_height = roiSize->height;
    int dst_height = src_height;
    int x, y = 0, i;

    int ker_width = state->ker_width;
    int ker_height = state->ker_height;
    int ker_x = ker_width/2;
    int ker_y = ker_height/2;
    int ker_right = ker_width - ker_x;

    int crows = state->crows;
    int **rows = (int**)(state->rows);
    short *tbufw = (short*)(state->tbuf);
    int *trow = 0;

    int* fmaskX = (int*)(state->ker0) + ker_x;
    int* fmaskY = (int*)(state->ker1) + ker_y;
    int fmX0 = fmaskX[0], fmY0 = fmaskY[0];

    int is_small_width = width < MAX( ker_x, ker_right );
    int starting_flag = 0;
    int width_rest = width & (CV_MORPH_ALIGN - 1);
    int origin = state->origin;
    int x_type = ICV_X_KERNEL_TYPE(state->kerType),
        y_type = ICV_Y_KERNEL_TYPE(state->kerType);
    int x_asymm = (x_type & 3) - 1, /* <0 - general kind (not used),
                                       0-symmetric, 1-asymmetric*/
        y_asymm = (y_type & 3) - 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;

    dstStep /= sizeof(dst[0]);

    do
    {
        int need_copy = is_small_width | (y == 0);
        uchar *tsrc;
        int   *tdst;
        short *tdst2;
        int   *saved_row = rows[ker_y];

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

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

            need_copy |= src_height == 1;

            if( ker_width > 1 )
            {
                uchar* tbufc = (uchar*)tbufw;

                if( need_copy )
                {
                    tsrc = tbufc - ker_x;
                    CV_COPY( tbufc, src, width, x );
                }
                else
                {
                    CV_COPY( tbufc - ker_x, src - ker_x, ker_x, x );
                    CV_COPY( tbufc, src + width, ker_right, x );
                }

                /* make replication borders */
                {
                uchar pix = tsrc[ker_x];
                CV_SET( tsrc, pix, ker_x, x );

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

                if( x_asymm )
                {
                    /* horizontal filter: asymmetric case */
                    if( x_type == ICV_m1_0_1_KERNEL )
                    {
                        for( i = 0; i < width; i++ )
                            tdst[i] = tsrc[i+2] - tsrc[i];
                    }
                    else
                    {
                        for( i = 0; i < width; i++ )
                        {
                            int j;
                            int t0 = tsrc[i + ker_x]*fmX0;

                            for( j = 1; j <= ker_x; j++ )
                                t0 += (tsrc[i+ker_x+j] - tsrc[i+ker_x-j])*fmaskX[j];

                            tdst[i] = t0;
                        }
                    }
                }
                else
                {
                    if( x_type == ICV_1_2_1_KERNEL )
                    {
                        for( i = 0; i < width; i++ )
                            tdst[i] = tsrc[i+1]*2 + tsrc[i] + tsrc[i+2];
                    }
                    else if( x_type == ICV_3_10_3_KERNEL )
                    {
                        for( i = 0; i < width; i++ )
                            tdst[i] = tsrc[i+1]*10 + (tsrc[i] + tsrc[i+2])*3;
                    }
                    else
                    {
                        /* horizontal filter: symmetric case */
                        for( i = 0; i < width; i++ )
                        {
                            int j;
                            int t0 = tsrc[i + ker_x]*fmX0;

                            for( j = 1; j <= ker_x; j++ )
                                t0 += (tsrc[i+ker_x+j] + tsrc[i+ker_x-j])*fmaskX[j];

                            tdst[i] = t0;
                        }
                    }
                }

                if( !need_copy )
                {
                    /* restore borders */
                    CV_COPY( src - ker_x, tbufc - ker_x, ker_x, x );
                    CV_COPY( src + width, tbufc, ker_right, x );
                }
            }
            else
            {
                CV_COPY( tdst, tsrc + ker_x, width, x );
            }

            if( crows < ker_height )
                src += srcStep;
        }

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

            for( i = 0; i < ker_y; i++ )
            {
                tdst = rows[i];
                CV_COPY( tdst, trow, width, x );
            }
        }

        /* vertical convolution */
        if( crows != ker_height )

⌨️ 快捷键说明

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