梯度简单来讲就是求导,在图像上表现出来的就是提取图像的边缘(无论是横向的、纵向的、斜方向的等等),所须要的无非也是一个核模板,模板的不一样结果也不一样。因此能够看到,全部的这些个算子函数,归结到底均可以用函数cv2.filter2D()来表示,不一样的方法给予不一样的核模板,而后演化为不一样的算子而已。而且这只是这类滤波函数的一个用途,曾经写过一个关于matlab下滤波函数imfilter()的扩展应用(等同于opencv的cv2.filter2D函数):python
就是不少复杂的计算都是能够经过这个滤波函数组合实现,这样的话速度快。数组
Sobel算子是高斯平滑与微分操做的结合体,因此其抗噪能力很强,用途较多。通常的sobel算子包括x与y两个方向,算子模板为:
markdown
拉普拉斯算子能够实现图像的二阶倒数的定义,至于二阶倒数有什么意义,能够看这位博主的详细介绍:函数
OpenCV-Python教程(七、Laplacian算子)ui
其核模板为:
lua
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)#默认ksize=3
sobely = cv2.Sobel(img,cv2.CV_64F,0,1)
sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1)
laplacian = cv2.Laplacian(img,cv2.CV_64F)#默认ksize=3
#人工生成一个高斯核,去和函数生成的比较
kernel = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]],np.float32)#
img1 = np.float64(img)#转化为浮点型的
img_filter = cv2.filter2D(img1,-1,kernel)
sobelxy1 = cv2.Sobel(img1,-1,1,1)
plt.subplot(221),plt.imshow(sobelx,'gray')
plt.subplot(222),plt.imshow(sobely,'gray')
plt.subplot(223),plt.imshow(sobelxy,'gray')
plt.subplot(224),plt.imshow(laplacian,'gray')
plt.figure()
plt.imshow(img_filter,'gray')
上述一个很重要的问题须要明白的就是,在滤波函数第二个参数,当咱们使用-1表示输出图像与输入图像的数据类型一致时,若是原始图像是uint8型的,那么在通过算子计算之后,获得的图像可能会有负值,若是与原图像数据类型一致,那么负值就会被截断变成0或者255,使得结果错误,那么针对这种问题有两种方式改变(上述程序中都有):一种就是改变输出图像的数据类型(第二个参数cv2.CV_64F),另外一种就是改变原始图像的数据类型(此时第二个参数能够为-1,与原始图像一致)。
上述程序从结果上也说明使用函数cv2.filter2D也能达到相同的效果。spa
关于canny边缘检测算子,细究的话还算比较的复杂,给出一个介绍比较详细的博客吧:.net
那么opencv中的函数也很是简单,直接cv2.Canny(),这个函数须要五个参数,原始图像,两个范围控制值minVal和maxVal(见上述原理介绍),第四个参数用于规定核模板的大小(默认3),最后一个是true与false(默认)的选择,有一点不一样,不过重要,能够试着那个好用那个。
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0)
edges = cv2.Canny(img,100,200)#其余的默认
plt.subplot(121),plt.imshow(img,'gray')
plt.subplot(122),plt.imshow(edges,'gray')