图像边缘主要包含下面几个部分
导入库
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
图片输出函数
def show(img):
if img.ndim == 2:
plt.imshow(img,cmap='gray')
else:
plt.imshow(cv.cvtColor(img,cv.COLOR_RGB2BGR))
plt.show()
Premitt算子
Premitt算子一般包含以下两种:
通过对水平方向和竖直方向的图片进行处理,然后合成,看最终的效果如何。
kx = np.array([
[-1,0,1],
[-1,0,1],
[-1,0,1]
],dtype=np.float32)
ky = np.array([
[-1,-1,-1],
[0,0,0],
[1,1,1]
],dtype=np.float32)
imgX = cv.filter2D(img,cv.CV_64F,kx)
imgY = cv.filter2D(img,cv.CV_64F,ky)
imgXY2 = np.abs(imgX)+np.abs(imgY)
show(np.hstack([img,np.abs(imgX).clip(0,255),np.abs(imgY).clip(0,255),np.abs(imgXY2).clip(0,255)]))
处理效果如下所示:
Roberts算子
Roberts算子也有两种形式,跟Premitt算子大同小异。
#Roberts算子
kx = np.array([
[-1,0],
[0,1]
],dtype=np.float32)
ky = np.array([
[0,1],
[1,0]
],dtype=np.float32)
imgX = cv.filter2D(img,cv.CV_64F,kx)
imgY = cv.filter2D(img,cv.CV_64F,ky)
imgXY = np.sqrt(imgX**2+imgY**2)
imgXY2 = np.abs(imgX)+np.abs(imgY)
show(np.hstack([img,np.abs(imgX).clip(0,255),np.abs(imgY).clip(0,255),np.abs(imgXY2).clip(0,255)]))
但是效果不如前者
Sobel-Feldman、Scharr算子
这两种算子与上面的两种算子,卷积核不一样,其余的地方大同小异,看看效果如何。
#soble-feldmen算子
imgX = cv.Sobel(img,cv.CV_16S,1,0)#x方向一阶偏导,y方向0阶偏导
imgY = cv.Sobel(img,cv.CV_16S,0,1)#y方向一阶偏导,x方向0阶偏导
imgXY = np.abs(imgX)+np.abs(imgY)
show(np.hstack([img,np.abs(imgX).clip(0,255),np.abs(imgY).clip(0,255),np.abs(imgXY).clip(0,255)]))
#Scharr算子
imgX = cv.Scharr(img,cv.CV_64F,1,0)
imgY = cv.Scharr(img,cv.CV_64F,0,1)
imgXY = np.sqrt(imgX**2+imgY**2)
show(np.hstack([img,np.abs(imgX).clip(0,255),np.abs(imgY).clip(0,255),np.abs(imgXY).clip(0,255)]))
soble-feldmen算子
Scharr算子
Laplacian算子
Laplacian算子基本上卷积核如下图所示:
opencv中有用来实现的方法
#Laplacian算子
img_lap = cv.Laplacian(img,cv.CV_64F)
show(np.abs(img_lap).clip(10,255))
LoG算子
LoG算子,是高斯模糊和Laplacian算子结合而成的。
#Log算子
img_blur = cv.GaussianBlur(img,(3,3),1)
img_log = cv.Laplacian(img_blur,cv.CV_64F)
show(np.hstack([np.abs(img_lap).clip(0,255),np.abs(img_log).clip(0,255)]))
和单纯的Laplacian相比,去除了很多噪声,emmm但是效果不是很好,可能是参数的问题。
Canny算法
Canny算法的处理方式:
opencv中自带的方法:
#canny边缘检测
img2 = cv.Canny(img,20,200)#低于20一定不是边缘,大于200就一定是强边缘,处于20-200之间的,如果靠近强边缘就一定是边缘
show(np.hstack([img,img2]))