文章目录
- 前言
- 一、归一化框滤波器
- 使用blur方法来实现
- 二、高斯滤波器
- 使用GaussianBlur方法实现
- 三、中值滤波器
- 使用medianBlur方法实现
- 四、双边过滤器
- 使用bilateralFilter方法实现
- 结语
前言
本教程将介绍使用OpenCV中的多种线性滤波器来对图像进行平滑处理,主要包括以下几种:
blur:模糊滤镜
GaussianBlur:高斯模糊滤镜
medianBlur:中值滤波器
bilateralFilter:双边滤波器
平滑处理是常用的图像处理操作之一,能有效去除噪声影响。在本教程中,我们将介绍平滑处理的原理,并以减少噪声为例进行展示。另外,需要注意的是,下面的解释主要来源于计算机视觉领域的经典教材《Richard Szeliski》和《Learning OpenCV: Algorithms and Applications》。
为了进行平滑处理,我们需要对图像应用一种滤波器。滤波器是一种将输入像素值(i.e. f(i+k,j+l)) 加权求和后得到输出像素值(i.e. g(i,j))的数学运算。最常见的滤波器类型是线性的,即输出像素值是输入像素值的加权和:
这些系数也被称为内核(kernel),它们构成了滤波器的核心部分。我们可以将内核想象成一个系数窗口,在图像上滑动这个窗口进行卷积计算。实际应用中,常用的滤波器有很多种,我们将介绍最
一、归一化框滤波器
其中之一是归一化框滤波器,也被称为均值滤波器。这是最简单的滤波器之一,对于每个输出像素,它的值都是其相邻像素的平均值(每个像素的权重相等)。其内核可表示为以下矩阵:
使用blur方法来实现
结构
Imgproc.blur(源Mat, 目标Mat, 模糊大小);
例子:
//图片读取
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/haizeiwang.png";
//放置图片
Mat blurMat = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
//模糊处理
Imgproc.blur(blurMat, blurMat,new Size(20,20));
//色彩模式转换
Imgproc.cvtColor(blurMat, blurMat, Imgproc.COLOR_BGR2RGB);
//结果放置在图片中
Texture2D blurTexture = new Texture2D(blurMat.cols(), blurMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(blurMat, blurTexture);
//展示在材质中
GameObject.Find("Cube1").GetComponent<Renderer>().material.mainTexture = blurTexture;
原图:
处理后:
二、高斯滤波器
高斯滤波器可能是最常用且最有用的滤波器之一(尽管不是最快的)。通过将输入图像中的每个像素与高斯核进行卷积并将卷积结果相加,就可以得到输出图像。它能够有效地平滑图像,并能够消除各种类型的噪声,例如高斯噪声。
对于一维的情况,可以发现位于中心的像素具有最大的权值,邻居的权值随着它们与中心像素之间的空间距离增加而减小。
需要注意的是,二维高斯核可以表示为以下形式:
其中,μ表示均值(即峰值),σ表示方差(对于每个变量x和y)。
2D数据公式可表示为:
使用GaussianBlur方法实现
结构:
Imgproc.GaussianBlur(源Mat, 目标Mat, 模糊大小(正奇数),X标准差, Y标准差,像素外推);
例子:
//图片读取
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/haizeiwang.png";
//放置图片
Mat blurMat = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
//模糊处理
Imgproc.GaussianBlur(blurMat, blurMat, new Size(33, 33), 0, 0);
//色彩模式转换
Imgproc.cvtColor(blurMat, blurMat, Imgproc.COLOR_BGR2RGB);
//结果放置在图片中
Texture2D blurTexture = new Texture2D(blurMat.cols(), blurMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(blurMat, blurTexture);
//展示在材质中
GameObject.Find("Cube1").GetComponent<Renderer>().material.mainTexture = blurTexture;
三、中值滤波器
中值滤波器遍历信号的每个元素(在这种情况下为图像),并用其相邻像素的中位数(位于估计像素周围的正方形邻域)中替换每个像素。
使用medianBlur方法实现
结构:
Imgproc.medianBlur(源Mat, 目标Mat, 模糊大小(正奇数));
例子:
//图片读取
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/haizeiwang.png";
//放置图片
Mat blurMat = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
//模糊处理
Imgproc.medianBlur(blurMat, blurMat, 33);
//色彩模式转换
Imgproc.cvtColor(blurMat, blurMat, Imgproc.COLOR_BGR2RGB);
//结果放置在图片中
Texture2D blurTexture = new Texture2D(blurMat.cols(), blurMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(blurMat, blurTexture);
//展示在材质中
GameObject.Find("Cube1").GetComponent<Renderer>().material.mainTexture = blurTexture;
四、双边过滤器
双边滤波器是一种可以消除噪声,同时保留边缘信息的滤波器。它类似于高斯滤波器,但它不仅考虑像素之间的空间距离,还考虑了它们的灰度值之间的差异。在计算每个像素与其相邻像素的权重时,双边滤波器使用两个分量:一个与高斯滤波器相同的空间权重,另一个则基于像素值之间的相似性权重。这两个分量都可以设置参数来调整其对输出图像的影响。
因为双边滤波器考虑了像素值之间的相似性,所以它可以保留边缘信息,而不像其他平滑滤波器(如高斯滤波器)会使边缘模糊。因此,双边滤波器在一些场景下比其他滤波器效果更好,例如图像去噪和图像增强。
需要注意的是,双边滤波器计算量相对较大,因此可能比其他滤波器更慢,但是可以通过调整参数来平衡计算量和滤波效果。
使用bilateralFilter方法实现
结构:
Imgproc.bilateralFilter(源Mat, 目标Mat, 每个像素邻域的直径, 像素邻域内影响颜色范围, 影响颜色距离);
例子
//图片读取
string readPath1 = Application.dataPath + "/OpenCVForUnity/Examples/Resources/haizeiwang.png";
//放置图片
Mat blurMat = Imgcodecs.imread(Utils.getFilePath(readPath1), Imgcodecs.IMREAD_COLOR);
//模糊处理
Imgproc.bilateralFilter(blurMat, blurMat, 15, 80, 80, Core.BORDER_DEFAULT);
//色彩模式转换
Imgproc.cvtColor(blurMat, blurMat, Imgproc.COLOR_BGR2RGB);
//结果放置在图片中
Texture2D blurTexture = new Texture2D(blurMat.cols(), blurMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(blurMat, blurTexture);
//展示在材质中
GameObject.Find("Cube1").GetComponent<Renderer>().material.mainTexture = blurTexture;
结语
虽然都是模糊效果,对比上面的效果图还是能发现有一定的区别,小伙伴们可以根据效果和性能的考虑。选择使用不同的滤波器,实现自己想要的效果喔。
那么本次分享就到这,可以的话顺手点个赞哈,谢谢观看。