图片处理(四)之边沿检测

来源:互联网 发布:unity3d手机游戏 编辑:程序博客网 时间:2024/04/28 02:40

本代码主要工作是对图片的数据进行边沿检测。

检测边界这里会说两种方法,一种叫Laplacian边沿检测,另一种叫Sobel边沿检测,Laplacian计算量相对较少,Sobel边沿更清晰。

 

首先我们要有一个概念,当对图片的数据进行一次求导后,得到的是图片的色差变化速度,当对图片的数据进行二次求导后,得到的是图片色差变化速度的速度,即色差突变,当我们收集所有的色差突变数据,得到的就是图片的边沿。

 

Laplacian边沿检测:二次求导,直接对xy整合计算,得到:

 @(@f )= f(x,y+1)+ f(x,y-1)+ f(x+1,y)+f(x-1,y)+ -4f(x,y)            //@表示求导

即:

|     0  |       1    |     0     |     

|     1  |   -4    |     1    |     

|     0  |       1    |      0    |

 

Sobel边沿检测:二次求导,x与y分开计算再整合,得到://@表示求导

@(@fx)=[f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)]

|     -1  |     0    |     1     |     

|     -2  |     0    |     2    |     

|     -1  |     0    |      1    |

 

@(@fx)=[f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)]-[f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1)]

 

|     1    |     2    |     1     |     

|     0   |     0    |     0     |     

|     -1   |     -2  |      -1   |

 

为整合计算,直接取绝对值进行相加,获取边沿数据,得到:

 @(@f )= Abs( @(@fx) )+abs( @(@fx) )

 

 

//GraphEdgeHandle1           Sobel边沿检测

//GraphEdgeHandle              Laplacian边沿检测

实现代码如下:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<math.h>

 

 

#define           ADD                     0

#define          SUB                       1

#define           MUL                     2

#define           DIV                      3

 

#define           Y_ADD                0

#define           Y_SUB                 1

 

#define         CUR_POS(x,y,width)           ((y)*width+(x))    

#define         X_POS(pos)                        ((pos)%PicWidth)

#define         Y_POS(pos)                        ((pos)/PicWidth)

 

#define           RANGE(x)            (x<0?0:(x>255?255:x))

 

 

//---------------picattribute----------------------    

unsignedint PicWidth;

unsignedint PicHeight;       

//--------------------------------------------------

 

voidGraphBrightHandle(unsigned char *src, unsigned char *dest, int size, int type,double num);

voidGraphLPFHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);

voidGraphEdgeHandle (unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);

voidGraphEdgeHandle1(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height);

 

 

intmain(int argc,char** argv)

{

    int nErrorCode=0;                                               

    FILE *fin;                                                  

    FILE *fout_Bright;

    FILE *fout_LPF;

       FILE *fout_Edge; 

      

    char szInFilename[256];                                     

    char szOutFilename[256]; 

                          

    if(argc>=2)                                                 

    {                                                           

        strcpy(szInFilename ,argv[1]);                                                 

    }                                                           

    else                                                        

    {                                                            

           strcpy(szInFilename, "44.raw");                                            

    }                                                                                                                            

    printf("src:%s\n",szInFilename);     

                              

                                                                

    if(argc>=4)   

    {

           PicWidth  = atoi(argv[2]);

           PicHeight= atoi(argv[3]);

    }

    else                                                         

    {                                                           

           PicWidth  = 640;

           PicHeight= 480;                     

    }        

    printf("PicWidth:%d,PicHeight:%d\n",PicWidth,PicHeight);

   

    fin = fopen(szInFilename , "rb");                          

    fout_Bright =fopen("GraphBright.raw"  ,"wb");

    fout_LPF   = fopen("GraphLPF.raw"    , "wb");

    fout_Edge  = fopen("GraphEdge.raw"   , "wb");

      

    if(fin && fout_Bright &&fout_LPF && fout_Edge)                                             

    {                                                           

           //getthe input file size                               

           unsignedint FileSize = 0;                                       

           fseek(fin,0, SEEK_END);                               

           FileSize= ftell(fin);                                  

           fseek(fin,0, SEEK_SET);                                

           printf("Filesize : %d\n", FileSize);                     

                                                                    

           //geta memory       

           unsignedchar *DataBuf = (unsigned char *)malloc(FileSize);

           memset(DataBuf,0, FileSize);

          

           //readdata to DataBuf                                       

           if ( 0 == fread(DataBuf, FileSize, 1,fin) )                                                                                                             

           {                                                       

            nErrorCode |= 0x4;                                   

           }                                                                                                                                                            

 

#if0   //Brignt Handle                                                                                        

           GraphBrightHandle(DataBuf,DataBuf, FileSize, MUL, 1.5);

           if( 0 == fwrite(DataBuf, FileSize, 1, fout_Bright) )

              {                                                                                                              

                     nErrorCode |= 0x8;                                

              }        

#endif

 

#if0   //LFP Handle              

           unsignedchar *DataBufLPF = (unsigned char *)malloc(FileSize);

           memset(DataBufLPF,0, FileSize);

           GraphLPFHandle(DataBuf,DataBufLPF, PicWidth, PicHeight);

           if( 0 == fwrite(DataBufLPF, FileSize, 1, fout_LPF) )

              {                                                                                                              

                     nErrorCode |= 0x10;                                 

              } 

#endif        

 

#if1   //Edge check                     

          unsignedchar *DataBufEdge = (unsigned char *)malloc(FileSize);

           memset(DataBufEdge,0, FileSize);         

           GraphEdgeHandle1(DataBuf,DataBufEdge, PicWidth, PicHeight);

           if( 0 == fwrite(DataBufEdge, FileSize, 1, fout_Edge) )

              {                                                                                                              

                     nErrorCode |= 0x11;                                

              } 

#endif 

 

    }                                                            

    else                                                        

    {                                                           

           nErrorCode|= 0x01;                                      

    }                                                           

                                                                

                                                                

    if(fin)                                                      

    {                                                           

           fclose(fin);                                            

    }                                                           

                                                                                                                         

       if(fout_Bright)                                                    

    {                                                           

           fclose(fout_Bright);                                            

    }    

        

       if(fout_LPF)                                                    

    {                                                           

           fclose(fout_LPF);                                           

    }   

                                                                         

    printf("nErrorCode: %d\n",nErrorCode);                     

    system("pause");                                            

    return nErrorCode;     

}

 

 

voidGraphBrightHandle(unsigned char *src, unsigned char *dest, int size, int type,double num)

{

       int i = 0;

    int R = 0, G = 0, B = 0;

   

    for(i = 0; i < size; i+=3)

    {

           R= src[i+0];

           G= src[i+1];

           B= src[i+2];

          

           switch(type)

           {

                  case ADD: R += num; G += num; B += num;  break;

                  case SUB: R -= num; G -= num; B -= num;  break;

                     case MUL: R *= num; G *= num; B *= num;  break;

                     case DIV: R /= num; G /= num; B /= num;  break;

                     default: printf("no exist Brighttype\n"); break;

              }                       

                 

           if(R< 0) R = 0;

              if(G< 0) G = 0;

              if(B< 0) B = 0;

           if(R> 255) R = 255;

              if(G> 255) G = 255;

              if(B> 255) B = 255;

                                          

           dest[i+0]= R;

           dest[i+1]= G;

           dest[i+2]= B;       

       }    

}

 

 

voidGraphLPFHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)

{

       unsigned int C, U, D, R, L;  

       int x, y;

       double tmp;

       for(y = 0; y < Height; y++)

    {

       for(x = 0; x < Width; x++)

       {      

                C = CUR_POS(x,y,Width);

                (0       == x)? (L = C):( L = y*Width + (x-1) );

                     (Width-1 == x)? (R = C):( R = y*Width + (x+1) );

                     (0       == y)? (U = C):( U = (y-1)*Width + x );

                     (Height-1 == y)? (D = C):( D =(y+1)*Width + x ); 

        

                   tmp =*(src+3*C+0)*0.5

                            +*(src+3*L+0)*0.125

                            +*(src+3*R+0)*0.125

                            +*(src+3*U+0)*0.125

                            +*(src+3*D+0)*0.125;

                     *(dest+3*C+0) = tmp;

                           

                     tmp = *(src+3*C+1)*0.5

                            +*(src+3*L+1)*0.125

                            +*(src+3*R+1)*0.125

                            +*(src+3*U+1)*0.125

                            +*(src+3*D+1)*0.125;

                     *(dest+3*C+1) = tmp;

                                  

                     tmp = *(src+3*C+2)*0.5

                            +*(src+3*L+2)*0.125

                            +*(src+3*R+2)*0.125

                            +*(src+3*U+2)*0.125

                            +*(src+3*D+2)*0.125;

                     *(dest+3*C+2) = tmp;                                            

           }         

    }    

}

 

voidGraphEdgeHandle1(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)

{

       int x, y;

       int xA,xB,xC,xD,xE,xF;

       int yA,yB,yC,yD,yE,yF;

       int Sx,Sy,tmp;

      

       for(y = 1; y < Height-1; y++)

    {

       for(x = 1; x < Width-1; x++)

       {

                     xA = (y-1)*Width + (x-1);

                     xB = (y+0)*Width + (x-1);

                     xC = (y+1)*Width + (x-1);

                     xD = (y-1)*Width + (x+1);

                     xE = (y+0)*Width + (x+1);

                     xF = (y+1)*Width + (x+1);

                    

                     yA = (y-1)*Width + (x-1);

                     yB = (y-1)*Width + (x+0);

                     yC = (y-1)*Width + (x+1);

                     yD = (y+1)*Width + (x-1);

                     yE = (y+1)*Width + (x+0);

                     yF = (y+1)*Width + (x+1);

                    

                     //R  

                     Sx =-*(src+3*xA+0)-*(src+3*xB+0)*2-*(src+3*xC+0)

                             +*(src+3*xD+0)+*(src+3*xE+0)*2+*(src+3*xF+0);

             

                     Sy =-*(src+3*yA+0)-*(src+3*yB+0)*2-*(src+3*yC+0)

                             +*(src+3*yD+0)+*(src+3*yE+0)*2+*(src+3*yF+0);

             

                     tmp = abs(Sx)+abs(Sy);

                     *(dest+3*CUR_POS(x,y,Width)+0) =RANGE(tmp);

                    

                     //G  

                     Sx =-*(src+3*xA+1)-*(src+3*xB+1)*2-*(src+3*xC+1)

                             +*(src+3*xD+1)+*(src+3*xE+1)*2+*(src+3*xF+1);

             

                     Sy =-*(src+3*yA+1)-*(src+3*yB+1)*2-*(src+3*yC+1)

                             +*(src+3*yD+1)+*(src+3*yE+1)*2+*(src+3*yF+1);

             

                     tmp = abs(Sx)+abs(Sy);

                     *(dest+3*CUR_POS(x,y,Width)+1) =RANGE(tmp);

                    

                     //B  

                     Sx =-*(src+3*xA+2)-*(src+3*xB+2)*2-*(src+3*xC+2)

                             +*(src+3*xD+2)+*(src+3*xE+2)*2+*(src+3*xF+2);

             

                     Sy =-*(src+3*yA+2)-*(src+3*yB+2)*2-*(src+3*yC+2)

                             +*(src+3*yD+2)+*(src+3*yE+2)*2+*(src+3*yF+2);

                             

                     tmp = abs(Sx)+abs(Sy);

                     *(dest+3*CUR_POS(x,y,Width)+2) =RANGE(tmp);

                    

           }

    }    

 

      

}

 

 

 

voidGraphEdgeHandle(unsigned char *src, unsigned char *dest, unsigned int Width,unsigned int Height)

{

    unsigned int C, U, D, R, L;  

       int x, y, tmp;

       for(y = 0; y < Height; y++)

    {

       for(x = 0; x < Width; x++)

       {      

                C = CUR_POS(x,y,Width);

                (0       == x)? (L = C):( L = y*Width + (x-1) );

                     (Width-1 == x)? (R = C):( R = y*Width + (x+1) );

                     (0       == y)? (U = C):( U = (y-1)*Width + x );

                     (Height-1 == y)? (D = C):( D =(y+1)*Width + x ); 

        

                   tmp =*(src+3*C+0)*(-4)

                            +*(src+3*L+0)*1

                            +*(src+3*R+0)*1

                            +*(src+3*U+0)*1

                            +*(src+3*D+0)*1;

                     if(tmp < 0)       tmp = 0;

                     if(tmp > 255) tmp = 255;           

                     *(dest+3*C+0) = tmp;

                                  

                     tmp = *(src+3*C+1)*(-4)

                            +*(src+3*L+1)*1

                            +*(src+3*R+1)*1

                            +*(src+3*U+1)*1

                            +*(src+3*D+1)*1;

                     if(tmp < 0)       tmp = 0;

                     if(tmp > 255) tmp = 255;           

                     *(dest+3*C+1) = tmp;  

                           

                     tmp = *(src+3*C+2)*(-4)

                            +*(src+3*L+2)*1

                            +*(src+3*R+2)*1

                            +*(src+3*U+2)*1

                            +*(src+3*D+2)*1;

                     if(tmp < 0)       tmp = 0;

                     if(tmp > 255) tmp = 255;           

                     *(dest+3*C+2) = tmp;                                                   

           }         

    }                          

 

 

 

 

 

0 0
原创粉丝点击