边缘检测即将原图像中景物或人物等的边缘(轮廓)的检测。
其实边缘检测和锐化真的比较相近,只是程度不同而已。通过对边缘点做灰度差分即可得到边缘。(可参考上一博)
通常为了让效果更佳明显,会做一个二值化。
至于二值化的方法也有很多种,比如全局的二值化的Ostu算法,迭代算法,大津法等,还有自适应的二值化等,之后的文章会详细进行介绍。
对于边缘检测 同样可以使用拉普拉斯算子,Kirsh算子,Canny算子等。
拉普拉斯算子Kirsh算子之一
Canny算子之一
以下是以Kirsh算子为例做卷积对图像进行边缘检测:其中最后使用了二值化使效果更明显。
#Kirsch算子边缘化
def Kirsch():
global edgeImage
kir = [ 5 , -3 , -3,
-3 , 0 , 5,
-3 , 5 , -3 ]
image = originalImage.convert('L');
h,w = image.size
opix = image.load()
processImage = Image.new('L' , (h,w))
npix = processImage.load()
total = 0
for i in range(h):
for j in range(w):
f11 = opix[abs(i - 1) , abs(j - 1)]
f12 = opix[abs(i - 1) , j]
if j != w - 1:
f13 = opix[abs(i - 1) , j + 1]
else:
f13 = opix[abs(i - 1) , j]
f21 = opix[i , abs(j - 1)]
f22 = opix[i , j]
if j != w - 1:
f23 = opix[i , j + 1]
else :
f23 = opix[i , j]
if i != h - 1:
f31 = opix[i + 1 , abs(j - 1)]
else:
f31 = opix[i , abs(j - 1)]
if i != h - 1:
f32 = opix[i + 1 , j]
else:
f32 = opix[i , j]
if i != h - 1 and j != w - 1:
f33 = opix[i + 1 , j + 1]
else :
f33 = opix[i , j]
temp = f11 * kir[0] + f12 * kir[1] + f13 * kir[2] + f21 * kir[3] + f22 * kir[4] + f23 * kir[5] + f31 * kir[6] + f32 * kir[7] + f33 * kir[8]
npix[i,j] = temp;
total += abs(temp)
val = total / (h * w) * 1.618
edgeImage = processImage.convert('L')
for i in range (h):
for j in range (w):
if (npix[i,j] < val):
npix[i,j] = 0
else :
npix[i,j] = 255
以下是效果图:
原图
边缘检测图:
拉普拉斯
Kirsh
canny
二值化后的图像
拉普拉斯
kirsh
canny