Skip to content

基础滤波函数

来自本人笔记: https://github.com/masterAllen/LearnOpenCV/blob/main/docs/基础滤波函数

一些滤波,基础知识。

前提知识:基本没有,知道滤波是个啥玩意就行,网上查一下,五分钟搞定。

函数说明:

个人认为可以把 OpenCV 滤波函数分为四种类型:第一,通用型函数、获取滤波核函数;第二,常见的低通滤波;第三,常见的高通滤波;第四,杂项滤波。

通用型、获取滤波:

  • filter2D:通用二维滤波
  • sepFilter2D:可拆分的二维滤波,如高斯滤波,可以拆分为两个一维滤波叉乘,对于这种滤波按照两个一维去做速度会增加很多,该方法就需要传入两个一维滤波作为其中参数
  • getGaussianKernel: 获取高斯滤波核
  • getDerivKernels: 获取Sobel算子和Scharr算子的滤波核

低通:

  • blur: 均值滤波,最后会归一化(即如果是3x3,那么就会除以9)
  • boxFilter: 相当于是上面blur的一个扩展,有参数支持是否归一化
  • sqrBoxFilter: 平方后进行均值滤波(常用在求方差、标准差等操作)
  • bilateralFiltear, GaussionBlur, medianblur: 双边滤波,高斯滤波,中值滤波
  • stackBlur: stackBlur can generate similar results as Gaussian blur, and the time consumption does not increase with the increase of kernel size.

高通:

  • Sobel, Scharr: Sobel算子, Scharr算子,都是相当于图像一维求导,其中第一个函数已经覆盖了第二个函数
  • Laplacian: 拉普拉斯滤波(相当于二维求导)

其他滤波:

具体细节

具体用的时候还是要查文档,这里只是记录一下用的时候注意点。有些函数有的属性没记录,要么太简单(比如 src 这种表示输入图片),要么和别的函数一样(这个全局搜索一下即可)。

filter2D

1720691767475

这个函数做的是相关操作,而不是卷积!!如图片所属,如果核不是对称的,需要事先翻转!!

  • kernel: 滤波核,single-channel 操作,也就是即使输入彩色图片,每一个通道都是做同样的滤波操作。如果想要通道做不同处理,需要自行分离通道,分别去调用滤波函数再合成
  • achor: 如上面图片所展示的。默认值 (-1, -1) 会自动将其放在滤波核的中心,一般都是这个参数,没太理解这个的意义
  • borderType: 边界怎么处理,经典的细节问题了。默认值是类似 gfedcb|abcdefgh|gfedcba 这种处理。

不重要的参数:

  • ddepth: 滤波后图片的深度,即第三维度是多少。-1则保持输入图片一样,一般都是这个参数(比如输入RGB彩色图片,-1保持一样,那么第三维度就是3)
  • delta: 计算完结果做一个偏移,个人感觉没啥用,后续多写一句话即可

sepFilter2D

  • 如果能拆分就请尽量用这个函数,速度提升确实很多
  • kernelX, kernelY:两个方向的滤波核

getGaussianKernel

1720692528242

1720693712509

  • 如图片所述,返回值不是二维的矩阵,而是一维!即二维高斯核拆分后的一维向量。可以直接传入 sepFilter2D 函数,如果想要二维核,请手动再去乘一下。
  • sigma 如果不是正数,则是通过图片所展示的公式计算。
  • ksize 表示直径,Opencv 中其他函数的 ksize 也都是直径。

getDerivKernels

  • 返回两个 n*1 的向量,叉乘后对应 Sobel 或 Scharr 的二维核;常用的几个组合:
  • ksize=-1, dx=1, dy=0: [-1, 0, 1] * [3, 10, 3]
  • ksize=1, dx=1, dy=0: [0] * [-1, 0, 1]
  • ksize=3, dx=1, dy=0: [1, 2, 1].T * [-1, 0, 1]
  • ksize=3, dx=1, dy=1: [-1, 0, 1].T * [-1, 0, 1]
  • dx, dy: Derivative order,官方文档没有给出核内容生成的公式,试了一些(ksize, dx, dy)组合很难推出公式来,源码也很难看出来,用的时候直接动手随便试。不过上面常用的占了绝大部分场景。

blur, boxFilter

  • blur 默认归一化,boxFilter 有一个参数 normalize,bool 属性用于标识是否归一化;所以只要记住 boxFilter 即可

GaussianBlur

  • ksize: 格式 (x, y),x 和 y 奇数;如果是 (0, 0),那么将会根据 sigma 计算,根据在 getGaussianKernel 那里的图片公式,本质其实类似直径要大于6倍标准差。
  • sigmaX, sigmaY: 标准差;sigmaY 如果为 0,那么就和 sigmaX 相等;sigmaXY 都为 0,那么就按照 ksize 计算,同样参考 getGaussianKernel 那里的图片公式。

medianBlur

  • src: When ksize is 3 or 5, the image depth should be CV_8U, CV_16U, or CV_32F. For larger ksize, it can only be CV_8U.
  • medianBlur 的边界处理和其他不同,是 aaaaaa|abcdefgh|hhhhhhh,而且这个好像还不能改...

bilateralFilter

OpenCV 本身官网就写的非常好了,直接参考过来:

1720694304559

  • d, sigmaSpace: 核的直径,空间上的 sigma;如果 d 不是正数,那么由 sigmaSpace 计算;如果 d 是正数,那么 sigmaSpace 无论有没有赋值,最后实际中肯定是通过 d 计算的。计算方式参考 getGaussianKernel,一样的。
  • sigmaColor: A larger value of the parameter means that farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting in larger areas of semi-equal color.

stackBlur

  • 参数很少,直接查阅官方文档。

Sobel, Scharr

  • 前者已经包含后者了,直接用第一个函数即可;这两函数和 getDeriveKernels 深度绑定,可以先去那个函数查阅
  • ksize=-1: 使用 Scharr 内核,其大小为 3*3,并且如果内核大小确定是 3,那么更推荐用 Scharr,其效果更好
  • ksize=1: 和 get DerivKernels 一样,用的是 3x1,如 dx,dy=1,0 时核内容为 [-1, 0, 1]
  • ksize, dx, dy: 和 getDerivKernels 一样属性。同样很难根据参数手算出核内容,所以先用 getDerviKernels 查看核内容。

Lapalician

  • ksize=1: 此时核内容就是常说的 [[0, -1, 0], [-1, 4, -1], [0, -1, 0]]
  • ksize>1: 利用 Sobel 算子做如下公式,具体的 Sobel 算子可以先用 getDerivKernels 看一下内容。
    1720716253707

getGaborKernel

  • 参数具体可查阅文档,没有什么其他额外的设置。比起函数使用,我觉得更重要的是 Gabor Filter 究竟用在什么地方,很少用到,查阅资料主要还是纹理识别方面,这两篇文章相对实用性较强:文章一文章二

pyrMeanShiftFiltering

  • 参数没什么说的,都是算法原理上涉及到的超参。算法的细节原理:TODO

Comments