opencv:图形梯度以及边缘检测
OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr 和 Laplacian。Sobel,Scharr 其实就是求一阶或二阶导数。Scharr 是对 Sobel(使用小的卷积核求解求解梯度角度时)的优化。Laplacian 是求二阶导数。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img=cv.imread('D:/code/opencv/images/1.png')
# cv2.CV_64F 输出图像的深度(数据类型),可以使用-1, 与原图像保持一致 np.uint8
laplacian=cv.Laplacian(img,cv.CV_64F)
# 参数 1,0 为只在 x 方向求一阶导数,最大可以求 2 阶导数。
sobelx=cv.Sobel(img,cv.CV_64F,1,0,ksize=5)
# 参数 0,1 为只在 y 方向求一阶导数,最大可以求 2 阶导数。
sobely=cv.Sobel(img,cv.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()
Canny边缘检测
- 第一步:用高斯滤波器去除噪声
- 第二步:使用Sobel算子计算水平方向和竖直方向的一阶导数
- 第三步:非极大值抑制
- 第四步:滞后阈值
然而在opencv中只需要一个函数:
cv.Canny()
#这个函数的第一个参数是输入图像。第二和第三个分别是 minVal 和 maxVal(当图像的灰度梯度高于maxval时被认为是真正的边界,低于minval的边界会被抛弃)。第三个参数设置用来计算图像梯度的 Sobel卷积核的大小,默认值为 3。最后一个参数L2gradient,它可以用来设定求梯度大小的方程。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('D:/code/opencv/images/1.png')
edges = cv.Canny(img, 100, 200)
#参数:图像 minval maxval
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
图像金字塔
我们可以使用函数cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔。函数 cv2.pyrDown() 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def pyramid_demo(image):
level = 4 # 金字塔
temp = image.copy()
pyramid_images = []
for i in range(level):
dst = cv.pyrDown(temp) # 进行降采样
# dst=cv.pyrUp(temp) 放大
pyramid_images.append(dst)
cv.imshow("pyramid_down_" + str(i + 1), dst)
temp = dst.copy()
img = cv.imread('D:/code/opencv/images/1.png')
cv.imshow("demo", img) # 将src图片放入该创建的窗口中
pyramid_demo(img)
cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows() # 关闭所有窗口