天天看点

opencv+python 边缘检测的基本原理,及Sobel、LoG和Canny算子的程序实现

图像边缘检测的原理:

图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量、检测和定位。

opencv+python 边缘检测的基本原理,及Sobel、LoG和Canny算子的程序实现

边缘检测的基本原理: 边缘检测的本质是微分,如上图所示,当相邻两个像素点的灰度值差异越大时,也就是其斜率越陡,也就是微分值越大,进而通过这个来判断边缘,实际中常用差分,x方向和y方向。

Sobel算子

opencv+python 边缘检测的基本原理,及Sobel、LoG和Canny算子的程序实现

原理:算子使用两个3X3的矩阵(图1)算子使用两个3X3的矩阵(图1)去和原始图片作卷积,分别得到横向G(x)和纵向G(y)的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点。

LoG算子

opencv+python 边缘检测的基本原理,及Sobel、LoG和Canny算子的程序实现

原理:首先对图像做高斯滤波,然后再求其拉普拉斯(Laplacian)二阶导数。即图像与 Laplacian of the Gaussian function 进行滤波运算。最后,通过检测滤波结果的零交叉(Zero crossings)可以获得图像或物体的边缘。因而,也被业界简称为Laplacian-of-Gaussian (LoG)算子。

Canny算子

算法步骤:

第一步:对原始图像进行灰度化、对图像进行高斯滤波

Canny算法通常处理的图像为灰度图,因此如果摄像机获取的是彩色图像,那首先就得进行灰度化。对一幅彩色图进行灰度化,就是根据图像各个通道的采样值进行加权平均。图像高斯滤波的实现可以用两个一维高斯核分别两次加权实现,也可以通过一个二维高斯核一次卷积实现。

第二步:用一阶偏导的有限差分来计算梯度的幅值方向

关于图像灰度值得梯度可使用一阶有限差分来进行近似,这样就可以得图像在x和y方向上偏导数的两个矩阵。

第三步:对梯度幅值进行非极大值抑制

图像梯度幅值矩阵中的元素值越大,说明图像中该点的梯度值越大,但这不不能说明该点就是边缘(这仅仅是属于图像增强的过程)。

第四步:用双阈值算法检测和连接边缘

Canny算法中减少假边缘数量的方法是采用双阈值法。选择两个阈值(关于阈值的选取方法在扩展中进行讨论),根据高阈值得到一个边缘图像,这样一个图像含有很少的假边缘,但是由于阈值较高,产生的图像边缘可能不闭合,为解决这样一个问题采用了另外一个低阈值。在高阈值图像中把边缘链接成轮廓,当到达轮廓的端点时,该算法会在断点的8邻域点中寻找满足低阈值的点,再根据此点收集新的边缘,直到整个图像边缘闭合。

三种边缘检测的程序实现:

# -*- coding:utf-8 -*-
#本程序用于边缘检测
import cv2  #导入opencv模块
import numpy as np

print("Hellow word!")     #打印“Hello word!”,验证模块导入成功

img = cv2.imread("lena.jpg")  #导入图片,图片放在程序所在目录
cv2.namedWindow("imagshow", 2)   #创建一个窗口
cv2.imshow('imagshow', img)    #显示原始图片

#高斯模糊
blurred = cv2.GaussianBlur(img, (3, 3), 0)
#转换为灰度图
out_img_GRAY=cv2.cvtColor(blurred,cv2.COLOR_BGR2GRAY)#将图片转换为灰度图
cv2.namedWindow("img_GRAY", 2)   #创建一个窗口
cv2.imshow('img_GRAY', out_img_GRAY)    #显示原始图片


#使用Canny算子进行边缘检测
edge_output = cv2.Canny(out_img_GRAY, 10, 300)
cv2.namedWindow("Canny", 2)   #创建一个窗口
cv2.imshow('Canny', edge_output)    #显示原始图片


#使用sobel算子进行边缘检测
sobel = cv2.Sobel(out_img_GRAY,-1,1,0,ksize=3)
cv2.namedWindow("sobel", 2)   #创建一个窗口
cv2.imshow('sobel', sobel)    #显示原始图片


#使用laplacian算子进行边缘检测
laplacian = cv2.Laplacian(out_img_GRAY,-1)
cv2.namedWindow("laplacian", 2)   #创建一个窗口
cv2.imshow('laplacian', laplacian)    #显示原始图片

cv2.waitKey()
           

实现效果如图:

opencv+python 边缘检测的基本原理,及Sobel、LoG和Canny算子的程序实现

从左到右分别为:灰度图、Canny算子、soble算子、laplacian算子

继续阅读