总:

图像处理之边缘检测

图像边缘检测——二阶微分算子(上)Laplace算子、LOG算子、DOG算子

图像边缘检测——二阶微分算子(下)Canny算子

一:Sobel算子

Sobel算子的数学基础

一阶和二阶差分(同时参考冈萨雷斯的书)

Sobel 算子是一个离散的一阶微分算子,用来计算图像灰度函数的近似梯度。

在空间域上Sobel算子很容易实现,执行速度快,对部分噪声具有平滑作用,还能够提供较为精确的边缘方向信息,缺点是边缘定位精度不够高。边缘是指一个物体与另一个物体的分界处,一般边缘内外处都会有灰度值上的差异,Sobel算子就是通过像素点空间邻域内上下,左右相邻点的灰度加权运算,求取物体边缘。

 

经典Sobel的卷积因子为:

深度学习 边缘检查 边缘检测算法_Data

 

对于待检测边缘的图像I,分别在水平(X)方向和垂直方向(Y)方向求导,方法是分别图像I与卷积核Gx和Gy进行卷积,公式表述如下:

                                               

深度学习 边缘检查 边缘检测算法_图像处理_02

                   

深度学习 边缘检查 边缘检测算法_Data_03

之后对求得的水平和垂直方向的梯度图像上的每一点执行:

 

深度学习 边缘检查 边缘检测算法_深度学习 边缘检查_04

    

或更为简单粗暴的:

深度学习 边缘检查 边缘检测算法_Data_05

   

G即为Sobel求得的梯度图像。

 

以下是C++实现:

int sobel(IplImage* src, IplImage*  tar , int limit ) 
{
    int SblMask1[3][3],SblMask2[3][3];

    //水平的模板
     SblMask1[0][0] = -1; //{-1,0,1,-2,0,2,-1,0,1};  
     SblMask1[0][1] = -2;
     SblMask1[0][2] = -1;
     SblMask1[1][0] = 0;
     SblMask1[1][1] = 0;
     SblMask1[1][2] = 0;
     SblMask1[2][0] = 1;
     SblMask1[2][1] = 2;
     SblMask1[2][2] = 1;

     //垂直的模板
     SblMask2[0][0] = -1;
     SblMask2[0][1] = 0;
     SblMask2[0][2] = 1;
     SblMask2[1][0] = -2;
     SblMask2[1][1] = 0;
     SblMask2[1][2] = 2;
     SblMask2[2][0] = -1;
     SblMask2[2][1] = 0;
     SblMask2[2][2] = 1;
//    }
    
    int H = src->height ; int W = src->width ; 
    int i , j , h , w , temp1 , temp2 ; 
    for ( h = 1 ; h < H - 1 ; h ++)
    {    
        for( w = 1 ; w < W - 1 ; w ++)
        {
            temp1 = temp2 = 0 ; 

            for(i = 0 ; i < 3 ; i++)
            {
                for(j = 0 ; j < 3 ; j++)
                {
                    temp1 += (src->imageData+(h - 1 + i)*src->widthStep)[(w - 1 + j)] * SblMask1[i][j] ;
                    temp2 += (src->imageData+(h - 1 + i)*src->widthStep)[(w - 1 + j)] * SblMask2[i][j] ;
                }
            }
            int k = sqrt(temp1*temp1 + temp2*temp2 )  ;
            if(  k > limit)
                (tar->imageData + tar->widthStep * h)[w] = (uchar)255; 
            else
                (tar->imageData + tar->widthStep * h)[w] = (uchar)0 ;
        }
    }
    
    return 0;
}

 二:canny算子及C++实现

Canny边缘检测及C++实现

三:拉普拉斯算子

冈萨雷斯图像处理有详细介绍

四:也可以通过先将图像膨胀或腐蚀后与膨胀或腐蚀前的图相减得到边缘

深度学习 边缘检查 边缘检测算法_边缘检测_06

 

Sobel算子检测方法对灰度渐变和噪声较多的图像处理效果较好,sobel算子对边缘定位不是很准确,图像的边缘不止一个像素;当对精度要求不是很高时,是一种较为常用的边缘检测方法。    

Canny方法不容易受噪声干扰,能够检测到真正的弱边缘。优点在于,使用两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中。

Laplacian算子法对噪声比较敏感,所以很少用该算子检测边缘,而是用来判断边缘像素视为与图像的明区还是暗区。拉普拉斯高斯算子是一种二阶导数算子,将在边缘处产生一个陡峭的零交叉, Laplacian算子是各向同性的,能对任何走向的界线和线条进行锐化,无方向性。这是拉普拉斯算子区别于其他算法的最大优点。