# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#读取图像
img = cv.imread('d:/paojie.png')
img1 = cv.cvtColor(img, cv.COLOR_BGR2RGB)
#灰度化处理图像
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#高斯滤波
gaussianBlur = cv.GaussianBlur(grayImage, (3,3), 0)
#阈值处理
ret, binary = cv.threshold(gaussianBlur, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
#Roberts算子
kernelx = np.array([[-1,0],[0,1]], dtype=int)
kernely = np.array([[0,-1],[1,0]], dtype=int)
x = cv.filter2D(binary, cv.CV_16S, kernelx)
y = cv.filter2D(binary, cv.CV_16S, kernely)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Roberts = cv.addWeighted(absX, 0.5, absY, 0.5, 0)
#Prewitt算子
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 = cv.filter2D(binary, cv.CV_16S, kernelx)
y = cv.filter2D(binary, cv.CV_16S, kernely)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Prewitt = cv.addWeighted(absX,0.5,absY,0.5,0)
#Sobel算子
x = cv.Sobel(binary, cv.CV_16S, 1, 0)
y = cv.Sobel(binary, cv.CV_16S, 0, 1)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Sobel = cv.addWeighted(absX, 0.5, absY, 0.5, 0)
#拉普拉斯算法
dst = cv.Laplacian(binary, cv.CV_16S, ksize = 3)
Laplacian = cv.convertScaleAbs(dst)
#效果图
titles = ['Source Image', 'Binary Image', 'Roberts Image',
'Prewitt Image','Sobel Image', 'Laplacian Image']
images = [img1, binary, Roberts, Prewitt, Sobel, Laplacian]
for i in np.arange(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
输出结果如图所示。其中,Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。