python图像处理(⼗⼀)——图像锐化与边缘检测之Roberts
算⼦、Prewitt算⼦。。。
在图像增强过程中,通常利⽤各类图像平滑算法消除噪声,图像的常见噪声主要有加性噪声、乘性噪声和量化噪声等。⼀般来说,图像的能量主要集中在其低频部分,噪声所在的频段主要在⾼频段,同时图像边缘信息也主要集中在其⾼频部分。这将导致原始图像在平滑处理之后,图像边缘和图像轮廓模糊的情况出现。为了减少这类不利效果的影响,就需要利⽤图像锐化技术,使图像的边缘变得清晰。
⼀、Roberts算⼦
Roberts算⼦⼜称交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条,常来处理具有陡峭的低噪声图像,当图像边缘接近于正负45,处理效果最佳。缺点是对边缘定位信息不太准确,提取的边缘线条较粗。Roberts算⼦模板分为⽔平⽅向和垂直⽅向。
在python中Roberts算⼦主要是通过Numpy定义模板,再调⽤OpenCV中的filter2D()函数实现边缘提取,该函数主要是利⽤内核实现对图像的卷积运算,其函数原型如下:
dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
参数如下:
src原图像
dst⽬标图像,与原图像尺⼨和通过数相同
ddepth⽬标图像的所需深度
kernel 卷积核(或相当于相关核),单通道浮点矩阵;如果要将不同的内核应⽤于不同的通道,请使⽤拆分将图像拆分为单独的颜⾊平⾯,然后单独处理它们。
anchor内核的锚点,指⽰内核中过滤点的相对位置;锚应位于内核中;默认值(-1,-1)表⽰锚位于内核中⼼。
detal在将它们存储在dst中之前,将可选值添加到已过滤的像素中。类似于偏置。
borderType像素外推法,参见BorderTypes
Roberts算法代码如下所⽰:
import cv2
import matplotlib.pyplot as plt
import numpy as np
#读取图像
image = cv2.imread('E:/pythonProject/12.png')
lena = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#灰度转化处理
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#roberts算⼦
kernelx = np.array([[-1, 0], [0, 1]], dtype= int)
htmlborder
kernely = np.array([[0, -1], [1, 0]], dtype= int)
x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
#转uint8
absX = vertScaleAbs(x)
absY = vertScaleAbs(y)
#加权和
Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
#显⽰中⽂标签
#图像显⽰
titles = [u'原始图像', u'Robertes图像']
images = [lena, Roberts]
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.show()
输出结果如下所⽰:
⼆、Prewitt算⼦
Prewitt算⼦是⼀种图像边缘检测的微分算⼦,由于Prewitt算⼦采⽤3*3模板对区域中的像素进⾏计算,⽽Roberts算⼦的是利⽤2*2模板,因此,Prewitt算⼦边缘检测结果在⽔平⽅向和垂直⽅向均⽐Roberts算⼦更加明显。Prewitt算⼦适合⽤来处理噪声较多,灰度渐变的图像。
在python中,Prewitt算⼦处理过程与Roberts算⼦较为相似,主要是通过Numpy定义模板,再调⽤OpenCV中的filter2D()函数实现对图像的卷积运算,最终通过vertScaleAbs(),和cv2.addWeighted()实现图像边缘提取。
Prewitt算法代码如下所⽰:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#输⼊图像
image = cv2.imread('E:/pythonProject/12.png')
lena = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#灰度转化处理
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#kernel
kernelX = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]],dtype= int)
kernelY = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]],dtype= int)
x = cv2.filter2D(grayImage, cv2.CV_16S, kernelX)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernelY)
#转uint8
absX = vertScaleAbs(x)
absY = vertScaleAbs(y)
#加权和
Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
#图象显⽰
titles = [u'原始图像', u'Prewitt图像']
images = [lena, Prewitt]
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.show()
输出结果如下所⽰:
从其效果图输出可以明显看出,Prewitt算⼦在垂直⽅向和⽔平⽅向其边缘检测结果均⽐Roberts算⼦边缘检测轮廓要更明显。
三、Sobel算⼦
Sobel算⼦根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这⼀现象检测边缘。对噪声具有平滑作⽤,提供较为精确的边缘⽅向信息,边缘定位精度不够⾼。当对精度要求不是很⾼时,是⼀种较为常⽤的边缘检测⽅法。
函数原型:
在sobel处理之后还要⽤vertScaleAbs()求其绝对值,并将图像转化为uint8格式。
Sobel算法代码如下所⽰:
import cv2
import matplotlib.pyplot as plt
#读取图像
image = cv2.imread('E:/pythonProject/12.png')
lean = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#转灰度图像
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#Sobel算⼦
x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)#对x⼀阶求导
y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)#对y⼀阶求导
absX = vertScaleAbs(x)
absY = vertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
#图像输出
titles = [u'原始图像', u'Sobel图像']
images = [lean, Sobel]
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.show()
输出结果如下所⽰:
四、Laplacian算⼦
Laplace函数实现的⽅法是先⽤Sobel 算⼦计算⼆阶x和y导数,再求和。函数原型:
Laplacian算⼦代码如下所⽰:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。