OpenCv基础(三)
文章目录
四、滤波器
- 滤波器:即卷积核
- 步长:滑动窗口大小
- padding:边缘填充
- 超参数:卷积核数量K,卷积核大小F,步长S,padding大小P
- 输入输出尺寸:
N
=
(
W
−
F
+
2
P
)
/
S
+
1
N = (W-F+2P)/S+1
N=(W−F+2P)/S+1;H计算同理
- N:输出大小
W:输入大小
F:卷积核大小
P:填充值的大小
S:步长大小
- N:输出大小
代码示例:
filter2D(img,ddepth,kernel)
ddepth:
对哪个通道卷积,-1表示对所有通道进行卷积操作kernel:
卷积核,必须是float型
# 卷积案例
import cv2
import numpy as np
img = cv2.imread('../my_work/01.png')
# 卷积核必须是float型
kernel = np.ones((5,5),np.float32)/25
# 卷积操作
dst = cv2.filter2D(img,-1,kernel)
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.waitKey()
cv2.destroyAllWindows()
4.1 方盒滤波与均值滤波
boxFilter(src,ddepth,ksize[,dst[,anchor[,normalize[,borderType]]]])
- 方盒滤波 K = a×[全为1的矩阵]
normalize = True
时,a=1/(w×h),w、h
是滤波器的宽高normalize = False
时,a=1
- 一般情况下使用
normalize = True
,这时方盒滤波等价于均值滤波
blur(src,ksize[,dst[,anchor[,borderType]]])
- 均值滤波
代码示例:
import cv2
import numpy as np
img = cv2.imread('../my_work/01.png')
# 方盒滤波
dst = cv2.boxFilter(img,-1,(5,5),normalize=True)
# 均值滤波
dst2 = cv2.blur(img,(5,5))
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.imshow('dst2',cv2.hconcat((img,dst2)))
cv2.waitKey()
cv2.destroyAllWindows()
4.2 高斯滤波
- 要理解什么是高斯滤波,就要搞清楚什么是高斯函数,高斯函数就是高斯分布函数,也即正态分布
- 高斯滤波就是使用符合高斯分布函数的卷积核对图片进行卷积操作
GaussianBlur(src,ksize,sigmaX[,dst[,sigmaY[,borderType]]])
ksize:
卷积核大小sigmaX:
x轴的标准差sigmaY:
y轴的标准差,默认为0,若没有指定sigma的值,会分别从ksize的宽度和高度计算sigma,sigma越大,平滑效果越明显
import cv2
img = cv2.imread('../my_work/01.png')
dst = cv2.GaussianBlur(img,(5,5),1.0)
# 使用高斯滤波降噪,噪声符合高斯分布的话,采用高斯滤波降噪效果会非常好
img2 = cv2.imread('../my_work/02.png')
dst2 = cv2.GaussianBlur(img,(5,5),1.0)
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.imshow('dst2',cv2.hconcat((img2,dst2)))
cv2.waitKey()
cv2.destroyAllWindows()
4.3 中值滤波
- 中值滤波原理:假设有一个数组[1,5,5,6,7,8,9],取其中的中间值作为卷积后的结果值即可,中值滤波对椒盐噪声效果明显
import cv2
img = cv2.imread('../my_work/03.png')
dst = cv2.medianBlur(img,5)
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.waitKey()
cv2.destroyAllWindows()
4.4 双边滤波
-
双边滤波对于图像的边缘信息能更好的保存。
-
原理:一个与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘
-
空间距离:指当前点与中心点的欧氏距离。
-
灰度距离:指当前点灰度与中心点灰度的差的绝对值
-
-
双边滤波本质上是高斯滤波。
- 双边滤波与高斯滤波的不同是:双边滤波既利用了位置信息又利用了像素信息来定义滤波窗口的权重,而高斯滤波只利用了位置信息
-
bilateralFilter(src,d,sigmaColor,sigmaSpace[,dst[,borderType]])
-
sigmaColor:
是计算像素信息的sigma -
sigmaSpace
:是计算空间信息的sigma
-
import cv2
img = cv2.imread('../my_work/02.png')
dst = cv2.bilateralFilter(img,5,sigmaColor=10.0,sigmaSpace=2.0)
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.waitKey()
cv2.destroyAllWindows()
五、边缘检测
5.1 sobel算子
-
算子是寻找图像边缘的,sobel算子是对图像求一阶导数
-
一阶导数越大,说明像素在该方向的变化越大,边缘信号越强
-
原理:采用离散差分算子计算图像像素点亮度值的近似梯度,图像是二维的,即沿着两个方向计算
-
cv2.Sobel(img,ddepth,dx,dy,ksize)
dx:
x方向梯度dy:
y方向梯度ksize:
卷积核尺寸
x、y方向的梯度要分别计算出来,然后
cv2.add(dx,dy)
合并
import cv2
img = cv2.imread('../my_work/01.png')
# 计算x轴方向的梯度,只有x方向的边缘
dx = cv2.Sobel(img,-1,dx=1,dy=0,ksize=3)
# 计算y轴方向的梯度,只有y方向的边缘
dy = cv2.Sobel(img,-1,dx=0,dy=1,ksize=3)
# 合并
dst = cv2.add(dx,dy)
cv2.imshow('dst',dst)
cv2.waitKey()
cv2.destroyAllWindows()
5.2 Scharr算子
Scharr(src,ddepyh,dx,dy[,dstp[,scale[,delta[,borderType]]]])
- 该函数只作用于大小为3的内核
- 与sobel算子差不多,只是内核恒为3
import cv2
img = cv2.imread('../my_work/01.png')
# 计算x轴方向的梯度,只有x方向的边缘
dx = cv2.Scharr(img,-1,dx=1,dy=0)
# 计算y轴方向的梯度,只有y方向的边缘
dy = cv2.Scharr(img,-1,dx=0,dy=1)
dst = cv2.add(dx,dy)
cv2.imshow('dst',cv2.hconcat((dx,dy,dst)))
cv2.waitKey()
cv2.destroyAllWindows()
5.3 拉普拉斯算子
-
求2阶导数,即边缘处的二阶导数为0
-
Laplacian(src,ddepth[,dst[,ksize[,scale[,delta[,borderType]]]]])
-
可以同时求两个方向的边缘
-
对噪音敏感,一般要先去噪再调用拉普拉斯
-
import cv2
img = cv2.imread('../my_work/01.png')
dst = cv2.Laplacian(img,-1,ksize=3)
cv2.imshow('dst',cv2.hconcat((img,dst)))
cv2.waitKey()
cv2.destroyAllWindows()
5.4 Canny算子
-
被认为是边缘检测的最优算法
- 低错误率、高定位性、最小响应
-
Canny检测的一般步骤
- 1:去噪,边缘检测很容易受到噪声影响,一般用高斯滤波去噪
- 2:计算梯度,对平滑后的图像采用sobel算子计算梯度和方向
- 梯度方向被划分为4类,垂直、水平、两个对角线
- 3:非极大值抑制
- 获取梯度和方向之后,遍历图像,去除不是边界的点
- 实现方法:逐个遍历像素点,判断当前数据点是否是周围像素点中具有相同方向梯度的最大值
- 如果是,保留该点,否则归零
- 4:滞后阈值:防止去除边界点
- 梯度大于maxVal:是边界
- 小于minVal:丢弃
- minVal与maxVal中间:与边界相连,保留
-
Canny(img,minVal,maxVal....)
minval:
梯度最小阈值,阈值越大,边缘越不精细,越小越精细maxval:
梯度最大阈值
import cv2
img = cv2.imread('../my_work/01.png')
# 阈值越大,边缘越不精细,越小越精细
dst = cv2.Canny(img,100,200)
dst2 = cv2.Canny(img,64,128)
cv2.imshow('dst',cv2.hconcat((dst,dst2)))
cv2.waitKey()
cv2.destroyAllWindows()