图像运算和图像增强十一
图像锐化之 Scharr、Canny、LOG 实现边缘检测
(1)Scharr算子
Scharr算子又称为Scharr滤波器,也是计算x或y方向上的图像差分。Scharr 算子的函数原型如下所示,和 Sobel 算子几乎一致,只是没有ksize 参数。
dst = Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[,
borderType]]]]])
- ddepth 表示目标图像所需的深度,针对不同的输入图像,输出目标图像有不同的深度
- dx 表示 x 方向上的差分阶数,取值 1 或 0
- dy 表示 y 方向上的差分阶数,取值 1 或 0
- scale 表示缩放导数的比例常数,默认情况下没有伸缩系数
- delta 表示将结果存入目标图像之前,添加到结果中的可选增量值
- borderType 表示边框模式
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图像
img=cv2.imread('luo.png')
lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#灰度化处理图像
grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Schar算子
x=cv2.Scharr(grayimage,cv2.CV_32F,1,0)#X方向
y=cv2.Scharr(grayimage,cv2.CV_32F,0,1)#Y方向
absX=cv2.convertScaleAbs(x)
absY=cv2.convertScaleAbs(y)
Scharr=cv2.addWeighted(absX,0.5,absY,0.5,0)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
titles=['原始图像','Scharr算子']
images=[lenna_img,Scharr]
for i in range(2):
plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
plt.title(title[i])
plt.xticks([]),plt.yticks([])
plt.show()
(2)Cann算子
Canny算子的实现步骤如下:
第一步,使用高斯平滑去除噪声。
第二步,按照Sobel滤波器步骤计算梯度幅值和方向,寻找图像的强度梯度。
第三步,通过非极大值抑制(Non-maximum Suppression)过滤掉非边缘像素,将模糊的边界变得清晰。
第四步,利用双阈值方法来确定潜在的边界。
第五步,利用滞后技术来跟踪边界。
edges = Canny(image, threshold1, threshold2[, edges[,
apertureSize[, L2gradient]]])
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('luo.png')
lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#高斯滤波降噪
gaussia=cv2.GaussianBlur(grayimage,(3,3),0)
#Canny算子
Canny=cv2.Canny(gaussian,50,150)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
titles=['原始图像','Canny算子']
images=[lenna_img,Canny]
for i in range(2):
plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
plt.title(title[i])
plt.xticks([]),plt.yticks([])
plt.show()
(3)LOG算子
LOG 算子综合考虑了对噪声的抑制和对边缘的检测两个方面,并且把Gauss 平滑滤波器和 Laplacian 锐化滤波器结合了起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('luo.png')
lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#先通过高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)
#再通过拉普拉斯算子做边缘检测
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3)
LOG = cv2.convertScaleAbs(dst)
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
#显示图形
titles = ['原始图像', 'LOG 算子']
images = [lenna_img, LOG]
for i in range(2):
plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()