边缘检测的意义

边缘检测:是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。

1.sobel算子

Sobel算子是一种常用的边缘检测算子,是一阶的梯度算法;对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高;当对精度要求不是很高时,是一种较为常用的边缘检测方法。常见的应用和物理意义是边缘检测。

思想:

算子使用两个3*3的矩阵算子分别和原始图片作卷积,分别得到横向Gx和纵向Gy的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点;

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_opencv


矩阵转换:

事实上卷积矩阵也可以由两个一维矩阵卷积而成,在opencv源码中就是用两个一维矩阵卷积生成一个卷积矩阵:

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_卷积_02


梯度值:图像的梯度值由以下公式计算:

图像近似梯度值如下:

对于原始图像,P5的梯度值为:

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_拉普拉斯算子_03


而opencv中怎么使用,请看下面的代码:

import cv2
import numpy as np
from scipy import signal

#读取图片
src_s = cv2.imread('../img/dip_switch_02.bmp', 0)
#对图片进行反色
src = cv2.bitwise_not(src_s)


# Sobel边缘检测算子
x = cv2.Sobel(src, cv2.CV_16S, 1, 0)
y = cv2.Sobel(src, cv2.CV_16S, 0, 1)
# cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
# 可选参数alpha是伸缩系数,beta是加到结果上的一个值,结果返回uint类型的图像
Scale_absX = cv2.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv2.convertScaleAbs(y)
edgesobel = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
edgesobel2 = cv2.bitwise_not(edgesobel)
cv2.putText(edgesobel2,"Sobel",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,0,255),4)
#显示图片
cv2.imshow('src_s', src_s)
cv2.imshow('sobel', edgesobel2)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行效果:

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_卷积_04

2.rober检测算子

Robert算子,又称Roberts边缘检测算子,是一种利用局部差分算子寻找边缘的算子。Robert算子图像处理后结果边缘不是很平滑。经分析,由于Robert算子通常会在图像边缘附近的区域内 产生较宽的响应,故采用上述算子检测的边缘图像常需做细化处理,边缘定位的精度不是很高。

def roberts(I, _boundary='fill', _fillvalue=0):
    # 图像的高,宽
    H1, W1 = I.shape[0:2]
    # 卷积核的尺寸
    H2, W2 = 2, 2
    # 卷积核1 和 锚点的位置
    R1 = np.array([[1, 0], [0, -1]], np.float32)
    kr1, kc1 = 0, 0
    # 计算full卷积
    IconR1 = signal.convolve2d(I, R1, mode='full', boundary=_boundary, fillvalue=_fillvalue)
    IconR1 = IconR1[H2 - kr1 - 1:H1 + H2 - kr1 - 1, W2 - kc1 - 1:W1 + W2 - kc1 - 1]
    # 卷积核2 和 锚点的位置
    R2 = np.array([[0, 1], [-1, 0]], np.float32)
    kr2, kc2 = 0, 1
    # 再计算full卷积
    IconR2 = signal.convolve2d(I, R2, mode='full', boundary=_boundary, fillvalue=_fillvalue)
    IconR2 = IconR2[H2 - kr2 - 1:H1 + H2 - kr2 - 1, W2 - kc2 - 1:W1 + W2 - kc2 - 1]
    return (IconR1, IconR2)
IconR1, IconR2 = roberts(src, 'symm')
# 45度方向上的边缘强度的灰度级显示
IconR1 = np.abs(IconR1)
edge45 = IconR1.astype(np.uint8)
# 135度方向上的边缘强度的灰度级显示
IconR2 = np.abs(IconR2)
edge135 = IconR2.astype(np.uint8)
# 用平方和的开方来衡量最后输出的边缘
edge = np.sqrt(np.power(IconR1, 2.0) + np.power(IconR2, 2.0))
edge = np.round(edge)
edge[edge > 255] = 255
edge = edge.astype(np.uint8)
edge2 = cv2.bitwise_not(edge)
cv2.putText(edge2,"robert",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,0,255),4)

运行效果:

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_python_05

3.高斯拉普拉斯算子

高斯拉普拉斯算子又称为LOG(Laplacian of Gaussian)算子,是在高斯函数的基础上再利用拉普拉斯算子提取边缘得出的一个算子。
拉普拉斯算子是一种高通滤波器,是影像灰度函数在两个垂直方向二阶偏导数之和。在离散数字影像的情况下,直接用影像灰度级的二阶差分代替连续情形下的二阶偏导数,对噪声很敏感,在提取边缘时往往会出现伪边缘响应。为克服拉普拉斯算子的不足,宜先对数字影像进行低通滤波,抑制噪声。高斯函数是一种很好的归一化低通滤波器,可用于对数字影像进行低通滤波以减少噪声的影响,在此基础上再利用拉普拉斯算子提取边缘,这就是高斯-拉普拉斯算子,又称为LOG(Laplacian of Gaussian)算子。

#拉普拉斯算子(高斯)
laplacian = cv2.Laplacian(src, cv2.CV_16S, ksize=5)
dst = cv2.convertScaleAbs(laplacian)
lap = cv2.bitwise_not(dst)
cv2.putText(lap,"guass",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(0,100,255),4)

运行效果:

python opencv 边缘检测算子 opencv边缘检测的结果怎么用_卷积_06