canny cv

// EdgeCanny.cpp: implementation of the CEdgeCanny class.
//
//

#include "stdafx.h"
#include "EdgeCanny.h"
#include "math.h"
#include
#include

//
// Construction/Destruction
//

CEdgeCanny::CEdgeCanny()
{

}

CEdgeCanny::~CEdgeCanny()
{

}


#ifndef MAX
#define MAX(a,b)  ((a) < (b) ? (b) : (a))
#endif


void fnFilter2DC(int *dstmat,unsigned char *mat,int *Imag,int iSrcWidth,
                int iSrcHeight,int iKWidth,int iKHeight)
{
    int iWidthByteDuiqi = iSrcWidth;
    while(iWidthByteDuiqi%4 != 0)
    {
        iWidthByteDuiqi = (iWidthByteDuiqi/4+1)*4;
    }

    int iDealWidth = (iKWidth-1)/2;
    int iDealHeight = (iKHeight-1)/2;

    for (int i = 0; i < iSrcHeight; i++)
    {
        for (int j = 0; j < iSrcWidth; j++)
        {
            int sum = 0;

            for (int ky = -iDealHeight; ky <= iDealHeight; ky++)
            {
                for (int kx = -iDealWidth; kx <= iDealWidth; kx++)
                {
                    int matValue = 0;
                    if(i+ky<0 || i+ky>(iSrcHeight-1) ||  j+kx<0 || j+kx>(iSrcWidth-1) )
                    {
                        matValue = 0;
                    }
                    else
                    {
                        matValue = mat[(i+ky)*iWidthByteDuiqi+(j+kx)];
                    }

                    int kValue = Imag[(iDealHeight+ky)*iKWidth+(iDealWidth+kx)];
                    sum = matValue*kValue + sum;
                }
            }

            dstmat[i*iSrcWidth+j]= (int)sum;
        }
    }
}


void CEdgeCanny::cvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size,int iWidth,int iHeight)
{    
    //void* buffer = 0;
    //int local_alloc = 0;

    int origin = 0;
    int src_type, dst_type;

    unsigned char *src = (unsigned char*)srcarr;
    int *dst = (int*)dstarr;

    src_type = 0;
    dst_type = 3;
    origin = 0;
    

    int kernelv[9]={-1,0,1,
                    -2,0,2,
                    -1,0,1};

    int kernelh[9]={-1,-2,-1,
                    0,0,0,
                    1,2,1};

    if(1 == dx && 0 == dy)
    {
        fnFilter2DC(dst,src,kernelh, iWidth, iHeight,3,3);
    }

    if(0 == dx && 1 == dy)
    {
        fnFilter2DC(dst,src,kernelv, iWidth, iHeight,3,3);
    }
}


void CEdgeCanny::fnSobleEdge(unsigned char *pBuffer,unsigned char **pBufferDst,int iWidth, int iHeight,
                        bool bVertical,bool bHorizon,int ithreshold,int fillvalue)
{
    if( (!bVertical) && (!bHorizon) )
    {
        return;
    }
    
//    int iframe =0;

    int *dx = 0;
    int *dy = 0;
    
    int aperture_size= 3;
    
    if(bVertical)
    {
        dx = new int[iWidth*iHeight];
        cvSobel( pBuffer, dx, 1, 0, aperture_size,iWidth,iHeight);
    }

    if(bHorizon)
    {
        dy = new int[iWidth*iHeight];
        cvSobel( pBuffer, dy, 0, 1, aperture_size,iWidth,iHeight);
    }


    aperture_size = 3;

    int iWidthBWByteDuiqi = iWidth;
    while(iWidthBWByteDuiqi%4 != 0)
    {
        iWidthBWByteDuiqi = (iWidthBWByteDuiqi/4+1)*4;
    }

    if(0 != pBufferDst )
    {
        *pBufferDst = new unsigned char[iWidthBWByteDuiqi*iHeight];
    }
    else
    {
        return;
    }

    for(int i=0;i     {
        for(int j=0;j         {
            int ivaluev =0;//垂直
            int ivalueh =0;//水平

            if(bVertical)
            {
                ivaluev = dx[i*iWidth+j];
                ivaluev = abs(ivaluev);
            }

            if(bHorizon)//
            {
                ivalueh = dy[i*iWidth+j];
                ivalueh = abs(ivalueh);
            }

            if(abs(ivalueh)< abs(ivaluev))
            {
                ivalueh = ivaluev;
            }
            
            if(abs(ivalueh)             {
                (*pBufferDst)[i*iWidthBWByteDuiqi+j] =0; 
            }
            else
            {
                (*pBufferDst)[i*iWidthBWByteDuiqi+j] = fillvalue;
            }
        }
    }

    m_pdx = dx;
    m_pdy = dy;

/*    if(0 != dx)
    {
        delete [] dx;
        dx = 0;
    }

    if(0 != dy)
    {
        delete [] dy;
        dy = 0;
    }
*/
    //CImageOp objCImageOp;
    //int iframe =0;
    //objCImageOp.fnWriteGray(*pBufferDst,iframe,iWidth,iHeight,0); //
    return;
}

#define INT_MAX       2147483647    /* maximum (signed) int value */
void  CEdgeCanny::fnCannyEdge( const BYTE* srcarr, BYTE** dstarr,int iWidth, int iHeight,
         double low_thresh, double high_thresh, int aperture_size )
{//?????high_thresh?low_thresh?2?? ??matlab??????//matlab??0.4?2???
    //matlab???3???,???????,????????
    int *icvFilterSobelVert_8u16s_C1R_p = 0;

    void *buffer = 0;
    BYTE **stack_top, **stack_bottom = 0;

    BYTE *src = (BYTE*)srcarr;
    //BYTE *dst = (BYTE**)dstarr;
    BYTE **dst = dstarr;

    CSizeEdge size;
    size.width = iWidth;
    size.height = iHeight;

    int flags = aperture_size;
    int low, high;
    int* mag_buf[3];


    BYTE* map;
    int mapstep, maxsize;
    int i, j;

    if( low_thresh > high_thresh )
    {
      //  double t;
      //  CV_SWAP( low_thresh, high_thresh, t );
    }

    aperture_size &= INT_MAX;
   
    int iWidthByteDuiqi = iWidth;//short???
//    while(iWidthByteDuiqi%2 != 0)
//    {
//        iWidthByteDuiqi = (iWidthByteDuiqi/2+1)*2;
//    }

    int * dx = new int[iWidthByteDuiqi*iHeight];
    int * dy = new int[iWidthByteDuiqi*iHeight];

    //cvSobel( src, dx, 1, 0, aperture_size,iWidth,iHeight);//??soble ??dx,??dy/
    //cvSobel( src, dy, 0, 1, aperture_size,iWidth,iHeight);

    cvSobel( src, dx, 0, 1, aperture_size,iWidth,iHeight);//??soble ??dx,??dy/
    cvSobel( src, dy, 1, 0, aperture_size,iWidth,iHeight);

    //dx?cv??1000??????dy?1000??cv?????

    //low = cvFloor( low_thresh );//??????????
    //high = cvFloor( high_thresh );

    low = low_thresh;//??????????
    high = high_thresh;//ll

    buffer = malloc( (size.width+2)*(size.height+2) +
                                (size.width+2)*3*sizeof(int));

    mag_buf[0] = (int*)buffer;
    mag_buf[1] = mag_buf[0] + size.width + 2;
    mag_buf[2] = mag_buf[1] + size.width + 2;//mag_buf ???3????


    map = (BYTE*)(mag_buf[2] + size.width + 2);//?3????
    mapstep = size.width + 2;//???


    maxsize = MAX( 1 << 10, size.width*size.height/10 );//?,?,????????
    stack_top = stack_bottom = (BYTE**)malloc( maxsize*sizeof(stack_top[0]) );
    //????,?,??????,??????????????????????

    memset( mag_buf[0], 0, (size.width+2)*sizeof(int) );//
    memset( map, 1, mapstep );//?3???
    memset( map + mapstep*(size.height + 1), 1, mapstep );//

    /* sector numbers 
       (Top-Left Origin)

        1   2   3
         *  *  * 
          * * *  
        0*******0
          * * *  
         *  *  * 
        3   2   1
    */


    #define CANNY_PUSH(d)    *(d) = (BYTE)2, *stack_top++ = (d)
    #define CANNY_POP(d)     (d) = *--stack_top
    //???,???,??????????


    //mag_row = cvMat( 1, size.width, CV_32F );//?????
    //float *mag_row = new float[iWidth*iHeight];//??????????

    //float *mag_row = new float[iWidth];//??iWidth*iHeight????,??????????mag_row?
    //???,?????

    // calculate magnitude and angle of gradient, perform non-maxima supression.
    // fill the map with one of the following values:
    //   0 - the pixel might belong to an edge
    //   1 - the pixel can not belong to an edge
    //   2 - the pixel does belong to an edge
    int dxstep = iWidth;//*2;
    int dystep = iWidth;//*2; //??????cv????dx??short?????
    //?????????????
    for( i = 0; i <= size.height; i++ )  //G:\aa6\test5.bmp      53
    {
        int* _mag = mag_buf[(i > 0) + 1] + 1;

        float* _magf = (float*)_mag;
        //const short* _dx = (short*)(dx + dxstep*i);//??????????
        //const short* _dy = (short*)(dy + dystep*i);

        const int* _dx = (int*)(dx + dxstep*i);//??????????
        const int* _dy = (int*)(dy + dystep*i);

        BYTE* _map;
        int x, y;
        int magstep1, magstep2;
        int prev_flag = 0;

        if( i < size.height )
        {
            _mag[-1] = _mag[size.width] = 0;//?,?????0.

            if( !(flags & CV_CANNY_L2_GRADIENT) )
            {
                for( j = 0; j < size.width; j++ )
                {
                    _mag[j] = abs(_dx[j]) + abs(_dy[j]);//???????????????????????
                    //_dy????cv???????
                    //??????
                }//??????mag_buf?? ???????
            }
            else if( icvFilterSobelVert_8u16s_C1R_p != 0 ) // check for IPP
            {
                // use vectorized sqrt
              /*  mag_row = _magf;
                for( j = 0; j < size.width; j++ )
                {
                    x = _dx[j]; y = _dy[j];
                    _magf[j] = (float)((double)x*x + (double)y*y);

                }//???????

                //cvPow( &mag_row, &mag_row, 0.5 );
                //double pow( double x, double y );//??????,?????????
                //??icvFilterSobelVert_8u16s_C1R_p?????0??
                */
                ;
            }
            else
            {
                for( j = 0; j < size.width; j++ )
                {
                    x = _dx[j]; y = _dy[j];
                    _magf[j] = (float)sqrt((double)x*x + (double)y*y);
                }
            }
        }
        else
            memset( _mag-1, 0, (size.width + 2)*sizeof(int) );

        // at the very beginning we do not have a complete ring
        // buffer of 3 magnitude rows for non-maxima suppression
        if( i == 0 )
            continue;

        _map = map + mapstep*i + 1;//??map?i??????
        _map[-1] = _map[size.width] = 1;
        
        _mag = mag_buf[1] + 1; // take the central row
        //

        _dx = (int*)(dx + dxstep*(i-1));
        _dy = (int*)(dy + dystep*(i-1));
        
        magstep1 = (int)(mag_buf[2] - mag_buf[1]);
        magstep2 = (int)(mag_buf[0] - mag_buf[1]);


        if( (stack_top - stack_bottom) + size.width > maxsize )
        {
            BYTE** new_stack_bottom;

            maxsize = MAX( maxsize * 3/2, maxsize + size.width );//????,????????,??
            //???????
            new_stack_bottom = (BYTE**)malloc( maxsize * sizeof(stack_top[0]));


            memcpy( new_stack_bottom, stack_bottom, (stack_top - stack_bottom)*sizeof(stack_top[0]) );
            //?????copy??????
            stack_top = new_stack_bottom + (stack_top - stack_bottom);


            free(stack_bottom);
            stack_bottom = new_stack_bottom;//?????????
        }


        for( j = 0; j < size.width; j++ )//?????????
        {
            #define CANNY_SHIFT 15
            #define TG22  (int)(0.4142135623730950488016887242097*(1<             //TG22??????

            x = _dx[j];
            y = _dy[j];

            int s = x ^ y;
            int m = _mag[j];//m??????????i???????????????

            x = abs(x);
            y = abs(y);
            if( m > low )//low = 50
            {
                int tg22x = x * TG22;
                int tg67x = tg22x + ((x + x) << CANNY_SHIFT);

                y <<= CANNY_SHIFT;

                if( y < tg22x )
                {
                    if( m > _mag[j-1] && m >= _mag[j+1] )//???????????????
                    {
                        if( m > high && !prev_flag && _map[j-mapstep] != 2 )//????2????_map??,0,1.
                        {//??????????            //?????????????????

                            CANNY_PUSH( _map + j );//???????????????????
                            prev_flag = 1;//?????1.????,????????
                        }
                        else
                            _map[j] = (BYTE)0;//?????0._map???i??????//???????0,

                        //?????????0.?????????0.
                        continue;
                    }
                }
                else if( y > tg67x )
                {
                    if( m > _mag[j+magstep2] && m >= _mag[j+magstep1] )
                    {
                        if( m > high && !prev_flag && _map[j-mapstep] != 2 )
                        {
                            CANNY_PUSH( _map + j );
                            prev_flag = 1;
                        }
                        else
                            _map[j] = (BYTE)0;

                        continue;
                    }
                }
                else
                {
                    s = s < 0 ? -1 : 1;
                    if( m > _mag[j+magstep2-s] && m > _mag[j+magstep1+s] )
                    {
                        if( m > high && !prev_flag && _map[j-mapstep] != 2 )
                        {
                            CANNY_PUSH( _map + j );
                            prev_flag = 1;
                        }
                        else
                            _map[j] = (BYTE)0;

                        continue;
                    }
                }
            }//??????,?????0,??????????1,?????????
            //?2???????
            //2??????????


            prev_flag = 0;//?????????1.
            _map[j] = (BYTE)1;//????
        }

        // scroll the ring buffer
        _mag = mag_buf[0];/// ????????
        mag_buf[0] = mag_buf[1];
        mag_buf[1] = mag_buf[2];    //mag_buf?
        mag_buf[2] = _mag;//????
    }

    // now track the edges (hysteresis thresholding)
    while( stack_top > stack_bottom )//????? hysteresis:??  ????
    {
        BYTE* m;
        if( (stack_top - stack_bottom) + 8 > maxsize )//????????
        {
            BYTE** new_stack_bottom;
            maxsize = MAX( maxsize * 3/2, maxsize + 8 );//??????????8??


            new_stack_bottom = (BYTE**)malloc( maxsize * sizeof(stack_top[0]));

            memcpy( new_stack_bottom, stack_bottom, (stack_top - stack_bottom)*sizeof(stack_top[0]) );
            stack_top = new_stack_bottom + (stack_top - stack_bottom);

            //cvFree( &stack_bottom );
            free(stack_bottom);//ll

            stack_bottom = new_stack_bottom;
        }

        CANNY_POP(m);//??? ???8??????????????????????
    
        //m????????????

        if( !m[-1] )  //?m?8??,?????0?,????2.  ???1,?????
            CANNY_PUSH( m - 1 );//???

        if( !m[1] )
            CANNY_PUSH( m + 1 );//??

        if( !m[-mapstep-1] )//?????
            CANNY_PUSH( m - mapstep - 1 );

        if( !m[-mapstep] )//??
            CANNY_PUSH( m - mapstep );

        if( !m[-mapstep+1] )//??????
            CANNY_PUSH( m - mapstep + 1 );

        if( !m[mapstep-1] )//?????
            CANNY_PUSH( m + mapstep - 1 );

        if( !m[mapstep] )//??
            CANNY_PUSH( m + mapstep );

        if( !m[mapstep+1] )//??????
            CANNY_PUSH( m + mapstep + 1 );

    }

    // the final pass, form the final image
    int dststep = iWidth;

//    int iWidthBWByteDuiqi = iWidth;//short???
    while(dststep%4 != 0)
    {
        dststep = (dststep/4+1)*4;
    }

    if(NULL != dst)
    {
        *dst = new BYTE[dststep*size.height];
    }
    else
    {
        return;
    }

    for( i = 0; i < size.height; i++ )
    {
        const BYTE* _map = map + mapstep*(i+1) + 1;//?????????

        BYTE* _dst = (*dst) + dststep*i;//??????
        
        for( j = 0; j < size.width; j++ )
            _dst[j] = (BYTE)-(_map[j] >> 1);//??????

        //        2>>1 ?1
        //        1>>1 ?0
        //        0>>1 ?0
        //      ?????????-1??uchar,???1  256??uchar,????????255??
    }//??????0?255.

    //_map?,?,0,1,2,
    //2: >>1,??1,????1.
    //1: >>1  ????0.
    //0: >>1  ????0.
    //???????,??0?1.

  //  __END__;

    if(NULL !=dx)
    {
        delete [] dx;
        dx = NULL;//??? ?dx???,???????
    }

    if(NULL != dy)
    {
        delete [] dy;
        dy = NULL;
    }

    if(NULL != buffer)
    {
        free(buffer);
        buffer = NULL;
    }

    if(NULL != stack_bottom)
    {
        free(stack_bottom);
        stack_bottom = NULL;
    }

//    CImageOp objCImageOp;
    int iframe =0;

//    objCImageOp.fnWriteGray(*dst,iframe,iWidth,iHeight,0); //
    //objCImageOp.fnWriteGray(pBufferScaled,iframe,iWidth,iHeight,0); //

}

/*
void CEdgeCanny::cvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size,int iWidth,int iHeight)
{    
    //void* buffer = 0;
    //int local_alloc = 0;

    int origin = 0;
    int src_type, dst_type;

    unsigned char *src = (unsigned char*)srcarr;
    int *dst = (int*)dstarr;

    src_type = 0;
    dst_type = 3;
    origin = 0;
    

    int kernelv[9]={-1,0,1,
                    -2,0,2,
                    -1,0,1};

    int kernelh[9]={-1,-2,-1,
                    0,0,0,
                    1,2,1};

    if(1 == dx && 0 == dy)
    {
        fnFilter2D(dst,src,kernelh, iWidth, iHeight,3,3);
    }

    if(0 == dx && 1 == dy)
    {
        fnFilter2D(dst,src,kernelv, iWidth, iHeight,3,3);
    }
}
*/
/*
void CEdgeCanny::fnSobleEdge(unsigned char *pBuffer,unsigned char **pBufferDst,int iWidth, int iHeight,
                        bool bVertical,bool bHorizon,int ithreshold,int fillvalue)
{
    if( (!bVertical) && (!bHorizon) )
    {
        return;
    }
    
//    int iframe =0;

    int *dx = 0;
    int *dy = 0;
    
    int aperture_size= 3;
    
    if(bVertical)
    {
        dx = new int[iWidth*iHeight];
        cvSobel( pBuffer, dx, 1, 0, aperture_size,iWidth,iHeight);
    }

    if(bHorizon)
    {
        dy = new int[iWidth*iHeight];
        cvSobel( pBuffer, dy, 0, 1, aperture_size,iWidth,iHeight);
    }


    aperture_size = 3;

    int iWidthBWByteDuiqi = iWidth;
    while(iWidthBWByteDuiqi%4 != 0)
    {
        iWidthBWByteDuiqi = (iWidthBWByteDuiqi/4+1)*4;
    }

    if(0 != pBufferDst )
    {
        *pBufferDst = new unsigned char[iWidthBWByteDuiqi*iHeight];
    }
    else
    {
        return;
    }

    for(int i=0;i     {
        for(int j=0;j         {
            int ivaluev =0;//垂直
            int ivalueh =0;//水平

            if(bVertical)
            {
                ivaluev = dx[i*iWidth+j];
                ivaluev = abs(ivaluev);
            }

            if(bHorizon)//
            {
                ivalueh = dy[i*iWidth+j];
                ivalueh = abs(ivalueh);
            }

            if(abs(ivalueh)< abs(ivaluev))
            {
                ivalueh = ivaluev;
            }
            
            if(abs(ivalueh)             {
                (*pBufferDst)[i*iWidthBWByteDuiqi+j] =0; 
            }
            else
            {
                (*pBufferDst)[i*iWidthBWByteDuiqi+j] = fillvalue;
            }
        }
    }

    if(0 != dx)
    {
        delete [] dx;
        dx = 0;
    }

    if(0 != dy)
    {
        delete [] dy;
        dy = 0;
    }

    //CImageOp objCImageOp;
    //int iframe =0;
    //objCImageOp.fnWriteGray(*pBufferDst,iframe,iWidth,iHeight,0); //
    return;
}

*/

 

.h

// EdgeCanny.h: interface for the CEdgeCanny class.
//
//

#if !defined(AFX_EDGECANNY_H__60D443F2_3775_4635_8179_F75B91B7FDF8__INCLUDED_)
#define AFX_EDGECANNY_H__60D443F2_3775_4635_8179_F75B91B7FDF8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define CV_CANNY_L2_GRADIENT  (1 << 31)

struct CSizeEdge
{
    int width;
    int height;
};

class CEdgeCanny  
{
public:

    void  fnCannyEdge( const unsigned char* srcarr, unsigned char** dstarr,int iWidth, int iHeight,
         double low_thresh, double high_thresh, int aperture_size );


    void fnSobleEdge(unsigned char *pBuffer,unsigned char **pBufferDst,int iWidth, int iHeight,
                bool bVertical,bool bHorizon,int ithreshold,int fillvalue=255);


    CEdgeCanny();
    virtual ~CEdgeCanny();

    private:
    void cvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size,int iWidth,int iHeight );

        int *  m_pdx;
    int *  m_pdy;
};

#endif // !defined(AFX_EDGECANNY_H__60D443F2_3775_4635_8179_F75B91B7FDF8__INCLUDED_)
 

你可能感兴趣的:(canny cv)