文章目录

  • 滤波
  • 滤波实例
  • 1. 均值滤波
  • 2. 方框滤波
  • 设置normalize为0
  • 设置normalize为1
  • 3. 高斯滤波
  • 高通滤波的使用
  • 4. 中值滤波
  • 5. 双边滤波
  • 6. 2D卷积(自定义滤波)


滤波

由于可能会有中值这种操作,所以滑窗或者说卷积的大小一般是奇数。
大致有以下几种滤波:

  1. 均值滤波;
  2. 方框滤波;
  3. 高斯滤波;
  4. 中值滤波;
  5. 双边滤波;
  6. 2D卷积(自定义滤波)

均值滤波

方框滤波

函数说明

def blur(src, ksize, dst=None, anchor=None, borderType=None, /) -> dst

def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None, /) -> dst

函数使用

r=cv2.blur(o,(5,5))

r=cv2.boxFilter(o,-1,(5,5))

ddepth为-1表示与原图像使用同样的深度 ddepth表示处理图像的深度 normalize表示是否使用归一化,归一化的话就和均值滤波一样了

滤波实例

1. 均值滤波

设置核大小即可,因为均值主要是对滑动的窗口求均值
def blur(src, ksize, dst=None, anchor=None, borderType=None, /) -> dst,对应到实际使用r=cv2.blur(o,(5,5))

  • 将矩阵结果保存到excel中
#导入库文件
import cv2
import pandas as pd

o=cv2.imread("image\\lenaNoise.png",cv2.IMREAD_GRAYSCALE)
#——将读取之后的图片数据保存进文件中
dataframe = pd.DataFrame(data=o)
dataframe.to_excel("文件.xlsx",index=False,header=False)
print("*"*100)
#使用均值滤波
r=cv2.blur(o,(5,5))#实现均值滤波
#获取均值滤波之后的数据,将其保存进excel
dataframe2 = pd.DataFrame(data=r)
dataframe2.to_excel("文件2.xlsx",index=False,header=False)
#显示原始以及滤波之后的图片
cv2.imshow("original",o)
cv2.imshow("result",r)
#销毁相关数据
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_opencv

2. 方框滤波

在方框滤波中,可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。
对应到参数上的不同就是normalize是0还是1,是1表示需要进行归一化,是0表示不需要进行归一化。

设置normalize为0

import cv2
o=cv2.imread("image\\lenaNoise.png")
r=cv2.boxFilter(o,-1,(5,5)) 
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_卷积_02

设置normalize为1

如果将归一化参数normalize设置为0,也就是不进行求平均值,那么很有可能就会超过255的值,整个就会变成纯白,如果如下图所示,result变成看纯白

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_03

3. 高斯滤波

高斯滤波里面的值是按照正态分布的,

def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None, /) -> dst在调用高斯滤波函数的时候,我们可以看到实际调用的函数是cv2.getGaussianKernel(ksize, sigma, ktype=None)

opencv HoughCircles识别椭圆 opencv findcirclesgrid_均值滤波_04


这个虽然是二维卷积,但是其实是通过一维卷积进行实现,分别在X以及Y方向上进行卷积,其卷积核如下(并且在边缘会有默认的padding操作):

opencv HoughCircles识别椭圆 opencv findcirclesgrid_opencv_05


所以其位置的公式计算opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_06

opencv HoughCircles识别椭圆 opencv findcirclesgrid_卷积_07


这个位置计算

带入公式

-1

0

1

坐标位置

1

2

3

计算

0-(3-1)/2

1-(3-1)/2

2-(3-1)/2

i-(ksize-1)/2

这些坐标位置就可以直接带入正态分布(也可以叫做高通分布)中去:

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_08


并且换个角度去看,先进行X滤波,再进行Y滤波,就等于下面的滤波器,然后代入到二维正态分布:

opencv HoughCircles识别椭圆 opencv findcirclesgrid_opencv_09


opencv HoughCircles识别椭圆 opencv findcirclesgrid_均值滤波_10

高通滤波的使用

函数定义:def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None, /) -> dst 实际调用:r=cv2.GaussianBlur(o,(3,3),0,0) 代码使用:

import cv2
a=cv2.getGaussianKernel(3, 1)
print(a)

o=cv2.imread("image\\lenaNoise.png")
o=cv2.resize(o, (5,5))
r=cv2.GaussianBlur(o,(3,3),0,0)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

cv2.getGaussianKernel(ksize, sigma, ktype=None)

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_11

4. 中值滤波

在一个滑窗范围内,首先进行排序,然后找到排在中间的那个数,将其替代这个位置的像素值
示例:

import cv2
o=cv2.imread("image\\lenaNoise.png")
r=cv2.medianBlur(o,3)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_12

5. 双边滤波

由于前面的滤波方式容易在边缘发生模糊的情况,尤其突变的时候,而边缘信息正是突变的地方。尤其是均值滤波这种,将一个滤波范围内的像素就给平均了,于是反而都处于相近的像素,将原本的信息改变了

opencv HoughCircles识别椭圆 opencv findcirclesgrid_卷积_13


下面就是经过高斯处理之后的效果,会显得比较模糊:

opencv HoughCircles识别椭圆 opencv findcirclesgrid_均值滤波_14


给距离以及色彩增加权重的考虑,如下图所示,在计算左边区域的时候,给右边的权重少一点,其判断一句是左边的像素值明显比右边大很多,而计算右边的时候,就会将左边的权重给的小很多,其判断

opencv HoughCircles识别椭圆 opencv findcirclesgrid_均值滤波_15


由于参考了空间以及色彩的因素,所以需要有这两个差值的阈值。其函数定义如下:

def bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None, /) -> dst

  1. d是在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径。推荐为5;
  2. sigmaColor是滤波处理时选取的颜色差值范围,该值决定了周围哪些像素点能够参与到滤波中来。为255表示指定直径所有的点都可以参与运算。
  3. sigmaSpace是坐标空间中的sigma值。它的值越大,说明有越多的点能够参与到滤波计算中来。当d>0时,无论sigmaSpace的值如何,d都指定邻域大小;否则,d与sigmaSpace的值成比例,也就是淋雨大小通过sigmaSpace计算;

查看滤波效果:

import cv2
o=cv2.imread("image\\lenaNoise.png")
r=cv2.bilateralFilter(o,25,100,100)
cv2.imshow("original",o)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_均值滤波_16

opencv HoughCircles识别椭圆 opencv findcirclesgrid_opencv_17

如果将滤波设计很大:

import cv2
o=cv2.imread("image\\bilTest.bmp")
g=r=cv2.GaussianBlur(o,(55,55),0,0)
b=cv2.bilateralFilter(o,55,100,100)
cv2.imshow("original",o)
cv2.imshow("Gaussian",g)
cv2.imshow("bilateral",b)
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_18


双边滤波一般只能比较好进行低频的滤波,常见的就是边缘了。

6. 2D卷积(自定义滤波)

def filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None, /) -> dst

  1. ddepth表示图像的深度,如果为-1就表示和原图像一样的深度;
  2. kernel:为自定义的卷积核
import cv2
import numpy as np
o=cv2.imread("image\\lena.bmp")
kernel = np.ones((9,9),np.float32)/81
r = cv2.filter2D(o,-1,kernel)
cv2.imshow("original",o)
cv2.imshow("Gaussian",r)
cv2.waitKey()
cv2.destroyAllWindows()

opencv HoughCircles识别椭圆 opencv findcirclesgrid_python_19