1 . 模糊
其实,不管是均值滤波,还是高斯滤波,其核心计算是卷积操作。 相应位置元素相乘后,累加,再取平均;每一次卷积计算的表达式如下:
g(i,j)=1k×l∑k,lf(i+k,j+l)h(k,l)
其中,k,l表示卷积核的尺寸;h表示卷积核 因此,卷积计算的核心是卷积核的选择;另外,卷积核的尺寸最好是奇数,因为需要对局部视野中心进行赋值。
2 . 均值模糊
1 . 概念
均值模糊就是将范围以内的像素取一个均值然后赋给自己,范围越大,归一化程度越强,越模糊。 下面就是opencv给的API
blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));
2 . 代码
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img = imread("D:/VS项目/mohu/1.jpg");
Mat img2;
blur(img, img2, Size(11, 11));
imshow("img", img);
imshow("img2", img2);
waitKey(0);
return 0;
}
3 . 高斯模糊
1 . 概念
高斯模糊和均值模糊其原理上的唯一区别只是在于卷积核的值不同罢了,高斯卷积核矩阵值服从二维高斯函数。 而高斯模糊本质上是低通滤波器,输出图像的每个像素点是原图像上对应像素点与周围像素点的加权和。 下图就是一维和二维正态分布的函数图像 二维正态分布的函数的密度函数就是高斯函数 从以上描述中我们可以看出,高斯滤波模板中最重要的参数就是高斯分布的标准差σ。它代表着数据的离散程度,如果σ较小,那么生成的模板中心系数越大,而周围的系数越小,这样对图像的平滑效果就不是很明显;相反,σ较大时,则生成的模板的各个系数相差就不是很大,比较类似于均值模板,对图像的平滑效果就比较明显。
下面是opencv自带的高斯模糊的API
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT);
src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
ksize,高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数(并不能理解)。或者,它们可以是零的,它们都是由sigma计算而来。
sigmaX,表示高斯核函数在X方向的的标准偏差。
sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
2 . 代码
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
cv::namedWindow("in", cv::WINDOW_AUTOSIZE);
cv::namedWindow("out", cv::WINDOW_AUTOSIZE);
cv::Mat img = cv::imread("D:/VS项目/mohu/1.jpg");
cv::imshow("in", img);
cv::Mat out;
cv::GaussianBlur(img, out, cv::Size(5, 5), 3, 3);
cv::GaussianBlur(out, out, cv::Size(5, 5), 3, 3);
cv::imshow("out", out);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
4 . 双边模糊
1 . 概念
双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。 双边滤波器的好处是可以做边缘保存(edge preserving),一般用高斯滤波去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。
opencv自带的API
C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
InputArray src: 输入图像,可以是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。 OutputArray dst: 输出图像,和原图像有相同的尺寸和类型。 int d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。 double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。 double sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace. int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.
2 . 代码
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat srcImage, dstImage;
int g_nBilateralFilterValue;
const int g_nBilateralFilterMax = 100;
void on_Trackbar(int, void*)
{
bilateralFilter(srcImage, dstImage, g_nBilateralFilterValue, g_nBilateralFilterValue * 2, g_nBilateralFilterValue / 2);
imshow("【双边滤波器窗口】", dstImage);
}
int main()
{
srcImage = imread("D:/VS项目/mohu/1.jpg");
imshow("【原图】", srcImage);
dstImage.create(srcImage.size(), srcImage.type());
g_nBilateralFilterValue = 0;
namedWindow("【双边滤波器窗口】");
createTrackbar("Value", "【双边滤波器窗口】", &g_nBilateralFilterValue, g_nBilateralFilterMax, on_Trackbar);
on_Trackbar(g_nBilateralFilterValue, 0);
waitKey(0);
return 0;
}
5 . 参考博客
https://zhuanlan.zhihu.com/p/358910882 https://blog.csdn.net/godadream/article/details/81568844 https://zhuanlan.zhihu.com/p/127023952 https://blog.csdn.net/keith_bb/article/details/54427779
|