本文以下OpenCV都简写成"cv2"的形式,所有img都默认为一张图片
关联文章:
OpenCV和图像处理(一)
七、边缘与轮廓
1、图像梯度
1-1:Scharr 滤波器
Scharr 滤波器:Sobel 滤波器的改良版。
S x = [ − 3 0 3 − 10 0 10 − 3 0 3 ] S y = [ − 3 − 10 − 3 0 0 0 3 10 3 ] 计 算 梯 度 幅 值 和 方 向 S = S x 2 + S y 2 θ = a r c t a n ( S y S x ) S_x=\left[ \begin{matrix} -3&0&3\\ -10&0&10\\ -3&0&3 \end{matrix} \right] \quad S_y=\left[ \begin{matrix} -3&-10&-3\\ 0&0&0\\ 3&10&3 \end{matrix} \right]\\ 计算梯度幅值和方向\\ S=\sqrt{S_x^2+S_y^2}\quadθ=arctan(\frac{S_y}{S_x}) Sx=⎣⎡−3−10−30003103⎦⎤Sy=⎣⎡−303−10010−303⎦⎤计算梯度幅值和方向S=Sx2+Sy2θ=arctan(SxSy)
很明显,Scharr 滤波器把 Sobel 滤波器的参数"增强"了,所以效果会更显著一些。
此外,为了加速计算,可以简化幅值:
∣ S ∣ = ∣ S x ∣ + ∣ S y ∣ |S|=|S_x|+|S_y| ∣S∣=∣Sx∣+∣Sy∣
在数据相对小的时候,误差也不大,但是计算比平方和再开根号就快多了。
特别地,Sx在处理横向的梯度的时候,也在纵向方向上有类似"高斯"的功能;Sy则反过来。所以
Scharr 滤波器能有"低通模糊"的功效。
# 可以对比上文 Sobel 滤波器,注意这里没有ksize参数。
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
1-2:Laplacian 滤波器
Laplacian 梯度滤波器是求图像的二阶差分, 二阶差分在亮的一边是负的,在暗的一边是正的。常数部分为零。可以用来确定边的准确位置,以及像素在亮的一侧还是暗的一侧。可假设其离散实现类似于二阶Sobel导数。事实的确如此,OpenCV在计算拉普拉斯算子时直接使用Sobel算子。
L ( I m g ) = ∂ 2 I m g ∂ x 2 + ∂ 2 I m g ∂ y 2 L(Img)=\frac{∂^2Img}{∂x^2}+\frac{∂^2Img}{∂y^2} L(Img)=∂x2∂2Img+∂y2∂2Img
上面是微分的公式,先看一下一维一阶差分和二阶差分的公式:
∂ f ∂ x i = f ( x i + 1 ) − f ( x i ) ∂ 2 f ∂ x i 2 = f ( x i + 1 ) + f ( x i − 1 ) − 2 f ( x i ) \frac{∂f}{∂x_i}=f(x_{i+1})-f(x_i)\\ \frac{∂^2f}{∂x_i^2}=f(x_{i+1})+f(x_{i-1})-2f(x_i) ∂xi∂f