CANNY算法源码

这是[精通VC图像处理(第三版)光盘]的canny算法部分,采用的是模板的方式

我找了很久,需要其它函数,到第二版或者网上找找吧,肯定能找到

#define  HDIB HANDLE
#define  PI 3.1415926

/************************************************************************* 
 * GausianFilterDIB
 * 
 * Parameters: 
 *        HDIB hDIB        - handle to global memory with a DIB spec 
 *                            in it followed by the DIB bits 
 * Return Value: 
 *        BOOL             - TRUE is success, else FALSE
 * Description: 
 *        Process Gausian filtering
 ***********************************************************************
*/
 
BOOL GausianFilterDIB(HDIB hDib)
{
    unsigned 
char mask[5][5];
    
int r, c, i, j;
    
int SUM;

//    WaitCursorBegin();

    
// 5x5 Gaussian mask
    mask[0][0= 2; mask[0][1=  4; mask[0][2=  5; mask[0][3=  4; mask[0][4= 2;
    mask[
1][0= 4; mask[1][1=  9; mask[1][2= 12; mask[1][3=  9; mask[1][4= 4;
    mask[
2][0= 5; mask[2][1= 12; mask[2][2= 15; mask[2][3= 12; mask[2][4= 5;
    mask[
3][0= 4; mask[3][1=  9; mask[3][2= 12; mask[3][3=  9; mask[3][4= 4;
    mask[
4][0= 2; mask[4][1=  4; mask[4][2=  5; mask[4][3=  4; mask[4][4= 2;

    
// copy to a new DIB to store original data
    HDIB hNewDib = CopyHandle(hDib);
    
if (! hNewDib)
    
{
//        WaitCursorEnd();
        return FALSE;
    }


    
// new DIB attributes
    WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
    WORD wDIBHeight 
= (WORD)DIBHeight(hNewDib);
    WORD wBytesPerLine 
= (WORD)BytesPerLine(hNewDib);

    
// original DIB become dest image
    LPBYTE lpDestDIB = (LPBYTE)GlobalLock(hDib);
    LPBYTE lpDestImage 
= FindDIBBits(lpDestDIB);

    
// get bits address in DIB
    LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
    LPBYTE lpDIBits 
= FindDIBBits(lpDIB);

    
for(r=0; r<wDIBHeight; r++)
    
{
        
for(c=0; c<wDIBWidth ; c++)
        
{
            SUM
=0;

            
long lOffset = PIXEL_OFFSET(r,c, wBytesPerLine);

            
if(r==0 || r==1 || r==wDIBHeight-2 || r==wDIBHeight-1)
                SUM 
=  *(lpDIBits + lOffset);
            
else if(c==0 || c==1 || c==wDIBWidth-2 || c==wDIBWidth-1)
                SUM 
=  *(lpDIBits + lOffset);
                 
            
// Convolution starts here
            else   
            
{
                
for(i=-2; i<=2; i++)  
                
{
                    
for(j=-2; j<=2; j++)  
                    
{
                        lOffset 
= PIXEL_OFFSET(r+i,c+j, wBytesPerLine);
                        SUM 
= SUM + (int)(*(lpDIBits + lOffset) * mask[i+2][j+2]/115);
                    }

                }

            }


            
if(SUM>255)  
                SUM
=255;
            
if(SUM<0)    
                SUM
=0;

            lOffset 
= PIXEL_OFFSET(r,c, wBytesPerLine);
            
*(lpDestImage + lOffset) = (unsigned char)(SUM);
        }

    }


    
// cleanup temp buffers
    GlobalUnlock(hNewDib);
    GlobalFree(hNewDib);
    GlobalUnlock(hDib);
    
    WaitCursorEnd();
    
return TRUE;
}



/************************************************************************* 
 * CannyEdegeDetectDIB() 
 * 
 * Parameters: 
 *        HDIB hDIB        - handle to global memory with a DIB spec 
 *                            in it followed by the DIB bits 
 * Return Value: 
 *        BOOL             - TRUE is success, else FALSE
 * Description: 
 *        Difference Edege Detect DIB
 ***********************************************************************
*/
 
BOOL CannyEdegeDetectDIB(HDIB hDib) 
{
    
int GX[3][3], GY[3][3];
    
int sumX, sumY, SUM;
    
int r,c, i, j;
    
double ORIENT;
    
int    edgeDirection;
    
int    highThreshold, lowThreshold;
    
int    leftPixel, rightPixel;
    
int    P1, P2, P3, P4, P5, P6, P7, P8;
    
long lOffset;

    WaitCursorBegin();

    
// 1. convert to gray scale
    ConvertToGrayscale(hDib, MEAN_GRAY, 000);

    
// 2. Gausian Filter DIB
    if (! GausianFilterDIB(hDib))
    
{
        WaitCursorEnd();
        
return FALSE;
    }


    
// 3. process...

    
// 3x3 GX Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html 
    GX[0][0= -1; GX[0][1= 0; GX[0][2= 1;
    GX[
1][0= -2; GX[1][1= 0; GX[1][2= 2;
    GX[
2][0= -1; GX[2][1= 0; GX[2][2= 1;

    
// 3x3 GY Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html 
    GY[0][0=  1; GY[0][1=  2; GY[0][2=  1;
    GY[
1][0=  0; GY[1][1=  0; GY[1][2=  0;
    GY[
2][0= -1; GY[2][1= -2; GY[2][2= -1;

    
// copy to a new DIB to store original data
    HDIB hNewDib = CopyHandle(hDib);
    
if (! hNewDib)
    
{
        WaitCursorEnd();
        
return FALSE;
    }


    
// new DIB attributes
    WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
    WORD wDIBHeight 
= (WORD)DIBHeight(hNewDib);
    WORD wBytesPerLine 
= (WORD)BytesPerLine(hNewDib);

    
// original DIB become dest image
    LPBYTE lpDestDIB = (LPBYTE)GlobalLock(hDib);
    LPBYTE lpDestImage 
= FindDIBBits(lpDestDIB);

    
// get bits address in DIB
    LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
    LPBYTE lpDIBits 
= FindDIBBits(lpDIB);

    
for(r=0; r<wDIBHeight; r++)
    
{
        
for(c=0; c<wDIBWidth; c++)
        
{
            sumX 
= 0;
            sumY 
= 0;

            
// image boundaries
            if(r==0 || r==wDIBHeight-1)
                SUM 
= 0;
            
else if(c==0 || c==wDIBWidth-1)
                SUM 
= 0;

            
// Convolution starts here
            else   
            
{
                
/***********************************
                * X gradient approximation
                **********************************
*/

                
for(i=-1; i<=1; i++)  
                
{
                    
for(j=-1; j<=1; j++)  
                    
{
                        lOffset 
= PIXEL_OFFSET(r+i,c+j, wBytesPerLine);
                        sumX 
= sumX + (int)(*(lpDIBits + lOffset) * GX[i+1][j+1]);
                    }

                }


                
/**************************
                * Y gradient approximation
                *************************
*/

                
for(i=-1; i<=1; i++)  
                
{
                    
for(j=-1; j<=1; j++)  
                    
{
                        lOffset 
= PIXEL_OFFSET(r+i,c+j, wBytesPerLine);
                        sumY 
= sumY + (int)(int)(*(lpDIBits + lOffset) * GY[i+1][j+1]);
                    }

                }


                
/***********************************************
                * GRADIENT MAGNITUDE APPROXIMATION (Myler p.218)
                **********************************************
*/

                SUM 
= abs(sumX) + abs(sumY);

                
if(SUM>255)    
                    SUM
=255;
                
if(SUM<0)      
                    SUM
=0;
            }


            
/***************************
            * Magnitude orientation
            **************************
*/

            
/* Cannot divide by zero*/
            
if(sumX == 0)   
            
{
                
if(sumY==0
                    ORIENT 
= 0.0;
                
else if (sumY<0)   
                
{
                    sumY 
= -sumY;

                    ORIENT 
= 90.0;
                }

                
else 
                    ORIENT 
= 90.0;
            }


            
// Can't take invtan of angle in 2nd Quad
            else if(sumX<0 && sumY>0)   
            
{
                sumX 
= -sumX;
                ORIENT 
= 180 - ((atan((float)(sumY)/(float)(sumX))) * (180/PI));
            }


            
// Can't take invtan of angle in 4th Quad
            else if(sumX>0 && sumY<0)   
            
{
                sumY 
= -sumY;
                ORIENT 
= 180 - ((atan((float)(sumY)/(float)(sumX))) * (180/PI));
            }


            
// else angle is in 1st or 3rd Quad
            else 
                ORIENT 
= (atan((float)(sumY)/(float)(sumX))) * (180/PI);


            
/***************************************************
            * Find edgeDirection by assigning ORIENT a value of
            * either 0, 45, 90 or 135 degrees, depending on which
            * value ORIENT is closest to
            ***************************************************
*/

            
if(ORIENT < 22.5
                edgeDirection 
= 0;
            
else if(ORIENT < 67.5
                edgeDirection 
= 45;
            
else if(ORIENT < 112.5
                edgeDirection 
= 90;
            
else if(ORIENT < 157.5
                edgeDirection 
= 135;
            
else 
                edgeDirection 
= 0;

            
/***************************************************
            * Obtain values of 2 adjacent pixels in edge
            * direction.
            ***************************************************
*/

            
if(edgeDirection == 0)   
            
{
                lOffset 
= PIXEL_OFFSET(r,c-1, wBytesPerLine);
                leftPixel 
= (int)(*(lpDIBits + lOffset));
                lOffset 
= PIXEL_OFFSET(r,c+1, wBytesPerLine);
                rightPixel 
= (int)(*(lpDIBits + lOffset));
            }


            
else if(edgeDirection == 45)   
            
{
                lOffset 
= PIXEL_OFFSET(r+1,c-1, wBytesPerLine);
                leftPixel 
= (int)(*(lpDIBits + lOffset));
                lOffset 
= PIXEL_OFFSET(r+1,c+1, wBytesPerLine);
                rightPixel 
= (int)(*(lpDIBits + lOffset));
            }


            
else if(edgeDirection == 90)   
            
{
                lOffset 
= PIXEL_OFFSET(r-1,c, wBytesPerLine);
                leftPixel 
= (int)(*(lpDIBits + lOffset));
                lOffset 
= PIXEL_OFFSET(r+1,c, wBytesPerLine);
                rightPixel 
= (int)(*(lpDIBits + lOffset));
            }


            
else   
            
{
                lOffset 
= PIXEL_OFFSET(r-1,c-1, wBytesPerLine);
                leftPixel 
= (int)(*(lpDIBits + lOffset));
                lOffset 
= PIXEL_OFFSET(r-1,c+1, wBytesPerLine);
                rightPixel 
= (int)(*(lpDIBits + lOffset));
            }


            
/*********************************************
            * Compare current magnitude to both adjacent
            * pixel values.  And if it is less than either
            * of the 2 adjacent values - suppress it and make
            * a nonedge.
            ********************************************
*/


            
if(SUM < leftPixel || SUM < rightPixel) 
                SUM 
= 0;
            
else   
            
{
                
/**********************
                * Hysteresis
                *********************
*/

                 highThreshold 
= 120;
                 lowThreshold 
= 40;

                 lOffset 
= PIXEL_OFFSET(r,c, wBytesPerLine);
                 
if(SUM >= highThreshold)
                       SUM 
= *(lpDIBits + lOffset); // edge
                 else if(SUM < lowThreshold)
                     SUM 
= 0;  // nonedge

                 
// SUM is between T1 & T2
                 else   
                 
{
                    
// Determine values of neighboring pixels
                    lOffset = PIXEL_OFFSET(r-1,c-1, wBytesPerLine);
                    P1 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r-1,c, wBytesPerLine);
                    P2 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r-1,c+1, wBytesPerLine);
                    P3 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r,c-1, wBytesPerLine);
                    P4 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r,c+1, wBytesPerLine);
                    P5 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r+1,c-1, wBytesPerLine);
                    P6 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r+1,c, wBytesPerLine);
                    P7 
= (int)*(lpDIBits + lOffset);
                    lOffset 
= PIXEL_OFFSET(r+1,c+1, wBytesPerLine);
                    P8 
= (int)*(lpDIBits + lOffset);

                    
// Check to see if neighboring pixel values are edges
                    lOffset = PIXEL_OFFSET(r,c, wBytesPerLine);
                    
if( P1 > highThreshold || P2 > highThreshold || 
                        P3 
> highThreshold || P4 > highThreshold || 
                        P5 
> highThreshold || P6 > highThreshold || 
                        P7 
> highThreshold || P8 > highThreshold)
                        SUM 
= *(lpDIBits + lOffset); // make edge
                    else 
                        SUM 
= 0// make nonedge
                }

            }


            lOffset 
= PIXEL_OFFSET(r,c, wBytesPerLine);
            
*(lpDestImage + lOffset) =  (BYTE)(SUM);
        }

    }


    
// cleanup temp buffers
    GlobalUnlock(hNewDib);
    GlobalFree(hNewDib);
    GlobalUnlock(hDib);
    
    WaitCursorEnd();
    
return TRUE;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值