知识点:
- 模糊()
- 高斯模糊()
- medianBlur()
- 双边滤波器()
理论
- 平滑,也称为模糊,是一种简单且经常使用的图像处理操作。
- 平滑的原因有很多,下面将重点关注平滑以减少噪声。
- 要执行平滑操作,我们将对图像应用滤镜。最常见的滤波器类型是线性的,其中输出像素的值(即G(i ,j )被确定为输入像素值的加权和(即F(i + k ,j + l )):
G
(
i
,
j
)
=
∑
k
,
l
f
(
i
+
k
,
j
+
l
)
h
(
k
,
l
)
G(i ,j ) =\sum\limits_{k,l}{f(i+k,j+l)h(k,l)}
G(i,j)=k,l∑f(i+k,j+l)h(k,l)h (k ,l )被称为内核,它只不过是过滤器的系数。
它有助于将滤波器可视化为在图像上滑动的系数窗口。 - 有很多种过滤器,这里我们会提到最常用的过滤器:
归一化滤波器 (Normalized Box Filter)
- 这个过滤器是最简单的!每个输出像素是其内核邻居的平均值(所有这些像素都具有相同的权重)
- 模型: K = 1 K w i d t h ⋅ K h e i g h t [ 1 1 1 . . . 1 1 1 1 . . . 1 . . . . . . 1 . . . . . . 1 1 1 1 . . . 1 ] K=\dfrac{1}{K_{width}\cdot K_{height}}\begin{bmatrix} 1 & 1&1&...&1\\ 1 & 1&1&...&1\\.&.&.&...&1\\.&.&.&...&1\\1&1&1&...&1 \\ \end{bmatrix} K=Kwidth⋅Kheight1⎣⎢⎢⎢⎢⎡11..111..111..1...............11111⎦⎥⎥⎥⎥⎤
- API: blur(Mat src,Mat dst,Size(w,h),Point(-1,-1));
src : 源图像
dst : 目标图像
Size() : 定义要使用的内核的大小(宽度为w像素,高度为h像素)
Point : 表示锚点(被评估的像素)相对于邻域的位置。如果存在负值,则将内核的中心视为锚点.
高斯滤波器 (Gaussian Filter)
- 可能是最有用的过滤器(尽管不是最快的)。通过将输入数组中的每个点与高斯核进行卷积,然后将它们相加以产生输出数组来完成高斯滤波。
- 2D高斯可以表示为: G 0 ( x , y ) = A e − ( x − u x ) 2 2 σ x 2 + − ( y − u y ) 2 2 σ y 2 G_0(x ,y ) ={Ae}^{\dfrac{-(x-u_x)^2}{2\sigma_x^2}+\dfrac{-(y-u_y)^2}{2\sigma_y^2}} G0(x,y)=Ae2σx2−(x−ux)2+2σy2−(y−uy)2
- API :GaussianBlur(Mat src,Mat dst,Size(w,h),sigmax,sigmay)
src:源图像
dst:目标图像
Size(w,h) : 要使用的内核的大小(要考虑的邻居)。w ^和H必须是奇数和正数,否则将使用σX和σÿ参数计算大小。
sigmax : x中的标准差。写0表示使用内核大小计算σx
sigmay : y的标准差。写0表示使用内核大小计算σy。
双边滤波器 (Bilateral Filter)
-
已经解释了一些主要目标是平滑输入图像的滤镜。但是,有时滤镜不仅可以消除噪音,还可以平滑边缘。为了避免这种情况(至少在某种程度上),我们可以使用双边滤波器。
-
以与高斯滤波器类似的方式,双边滤波器还考虑具有分配给它们中的每一个的权重的相邻像素。这些权重有两个分量,第一个是高斯滤波器使用的相同权重。第二个组件考虑了相邻像素和评估像素之间的强度差异。
-
API : bilateralFilter(Mat src,Mat dst,int d,double sigmaColor,double sigmaSpace, int borderType)
src : 源8位或浮点,1通道或3通道图像。
dst : 与src具有相同大小和类型的目标映像。
d : 过滤期间使用的每个像素邻域的直径。如果它是非正数,则从sigmaSpace计算。
sigmaColor : 过滤颜色空间中的西格玛。参数的值越大意味着像素邻域内的更远的颜色(参见sigmaSpace)将混合在一起,从而产生更大的半等颜色区域。
sigmaSpace : 在坐标空间中过滤西格玛。较大的参数值意味着只要它们的颜色足够接近,更远的像素就会相互影响(参见sigmaColor)。当d> 0时,无论 sigmaSpace如何,它都指定邻域大小。否则,d与sigmaSpace成比例。
borderType : 用于外推图像外部像素的边框模式
中位数滤波器 (Median Filter)
- 中值滤波器遍历信号的每个元素(在这种情况下是图像),并用其相邻像素的中值(位于评估像素周围的方形邻域中)替换每个像素。
- 中位数滤波器对
- API : medianBlur(Mat src,Mat dst,int i)
src : 源图像椒盐噪声有很好的抑制作用
dst : 目标图像,必须与src的类型相同
i : 内核的大小(只有一个,因为我们使用方形窗口)。一定是奇怪的。
例子
- 归一化滤波器
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat srcImage,dst;
srcImage = imread("E:/image/6.jpg");
if (srcImage.empty()) {
printf("没有找到图片");
return -1;
}
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", srcImage);
blur(srcImage, dst, Size(7, 7), Point(-1, -1));
namedWindow("blur_image", WINDOW_AUTOSIZE);
imshow("blur_image", dst);
waitKey(0);
return 0;
}
效果图:
- 高斯滤波器
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat srcImage,dst;
srcImage = imread("E:/image/6.jpg");
if (srcImage.empty()) {
printf("没有找到图片");
return -1;
}
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", srcImage);
GaussianBlur(srcImage, dst, Size(7, 7),11,11);
namedWindow("GaussianBlur_image", WINDOW_AUTOSIZE);
imshow("GaussianBlur_image", dst);
waitKey(0);
return 0;
}
效果图:
- 中位数滤波器
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat srcImage,dst;
srcImage = imread("E:/image/6.jpg");
if (srcImage.empty()) {
printf("没有找到图片");
return -1;
}
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", srcImage);
medianBlur(srcImage,dst,3);
namedWindow("medianBlu", WINDOW_AUTOSIZE);
imshow("medianBlu", dst);
waitKey(0);
return 0;
}
效果图:
- 双边滤波器
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat srcImage,dst;
srcImage = imread("E:/image/6.jpg");
if (srcImage.empty()) {
printf("没有找到图片");
return -1;
}
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", srcImage);
bilateralFilter(srcImage,dst,15,150,3);
namedWindow("bilateralFilter", WINDOW_AUTOSIZE);
imshow("bilateralFilter", dst);
waitKey(0);
return 0;
}
效果图:
- 双边滤波器+filter2D图像增强
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat srcImage,dst;
srcImage = imread("E:/image/6.jpg");
if (srcImage.empty()) {
printf("没有找到图片");
return -1;
}
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", srcImage);
bilateralFilter(srcImage,dst,15,150,3);
namedWindow("bilateralFilter", WINDOW_AUTOSIZE);
imshow("bilateralFilter", dst);
Mat result;
Mat kernal = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(dst, result, -1, kernal,Point(-1,-1),0);
imshow("bilateralFilter_filter2D_result", result);
waitKey(0);
return 0;
}
效果图: