Prewitt算子也是一种一阶微分算子,用于边缘检测。与Robert使用22的模板不同,Prewitt算子使用的是33的模板,利用像素点上下、左右邻点的灰度差来检测边缘,故其边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。
其数学表达式如下:
G(i) = | f(i-1, j-1) + f(i-1,j)+f(i-1,j+1) - [f(i+1,j-1)+f(i+1,j)+f(i+1,j+1)] |
G(j) = | f(i-1, j+1) + f(i,j+1)+f(i+1,j+1) - [f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)] |
则 P(i,j)=max[G(i),G(j)]
或 P(i,j)=G(i)+G(j)
其算子如下:
在Python中,Prewitt算子的实现过程与Robert算子类似。首先通过numpy定义模板,也就是卷积核,再调用函数filter2D对图像进行卷积,最终通过convertScaleAbs()和addWeighted函数实现。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
#Robert
def PreWitt(img):
result = img
oi = np.array([[-1,-1,-1], [0,0,0],[1,1,1]])
oj = np.array([[-1,0,1],[-1,0,1],[-1,0,1]])
x = cv.filter2D(img, cv.CV_16S, oi)
y = cv.filter2D(img, cv.CV_16S, oj)
# 转uint8
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
result = cv.addWeighted(absX, 0.5, absY, 0.5, 0)
return result
img = cv.imread('lena512color.tiff', 0)
cv.imshow('lena', img)
p = PreWitt(img)
cv.imshow('PreWitt', p)
cv.waitKey(0)
结果如下:
Prewitt算子适合用来识别噪声较多、灰度渐变的图像。
此算子也可以应用在彩色图像上,运行结果如下图所示,左图为原彩色图像,右图为经过Prewitt算子检测后的边缘图像。此种显示方式只显示了边缘,除了边缘部分其他皆为0,即全黑。