中值滤波
原理:假设一个33的矩阵,中值滤波就是把这个矩阵的值重新排序,将中间的灰度值赋给中心点坐标处的灰度值。
例如上图就是重排序为98,98,99,99,99,100,100,100,101,将99赋给中心点。
中值滤波很容易处理椒盐噪声,椒盐噪声的存在是因为图像中某些点的灰度值为255或者0,当重新排序后,这些点会忽略掉,同时一幅图像的灰度值是跟临近像素的灰度值有关,不会突然的跃迁,总是有梯度的变换,所以修复了图像。
最大值最小值滤波的原理与中值滤波原理相同,只不过是把中间值换成最大值255或者最小值0进行变换。
均值滤波
原理:同样是以(x,y)为中心的33矩阵,它与输入图像的每一个像素进行相关产生一个新的像素,新像素的坐标为当前访问的像素坐标。可以是平均值,也可是权重。他可以降低噪声,但同时会模糊图像,去除了图像中不相关的细节。
锐化滤波器
分为二阶微分滤波器-拉普拉斯算子和一阶微分滤波器-梯度算子。
二阶的原理是对图像分别进行x和y的二阶偏导,即
二阶拉普拉斯算子是突出图像灰度变幻的区域,衰减灰度变换慢的区域。将原始图像和拉普拉斯变换后的图像叠加起来,可达到图像锐化的目的。
上述公式中减号是因为拉普拉斯算子为0,1,0,1,-4,1,0,1,0,得到的新像素的为负值,相减后得正值。
一阶滤波器-梯度算子
是对输入图像分别进行x和y导数,即
梯度的幅值为
梯度向量指出了在(x,y)处f的最大变换率方向。
在剃度算法中有几个常用的算子:
sobel算子,常用来边缘检测,具体算子结构如下
第一个算子左边暗右边亮,其余原理都如此。
prewitt算子不突出中间值的灰度,具体如下
opencv代码实现:
#include < iostream >
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat src,dst,dest,qwe,wer,qaz;
int main()
{
src=imread(“图像的路径”);
if(src.empty())
{
cout<<“not open successed!”<<endl;
return -1;
}
namedWindow(“input”,WINDOW_AUTOSIZE);
imshow(“input”,src);
medianBlur(src,dst,11);//11是算子的size;(中值滤波)
Blur(src,dest,Size(3,3),Point(-1,-1),BORDER_DEFAULT);//point(-1,-1)是默认值,最好不要改动,防止引起不必要的错误。border_default是边缘的补充方式,这里选用默认值。
Laplacian(src, qaz, -1, 1, 1, 0, BORDER_DEFAULT);//-1的意思是图片的深度即就是定义输出图像的类型,第四个是滤波器的size,其他的按默认值设置就好;
//下面是梯度算法
Mat grad;
Mat sobel_x, sobel_y;
Sobel(src, sobel_x, CV_16S, 1, 0, 1, BORDER_DEFAULT);//对x求偏导,1,0,代表的是水平方向,1是阶数,CV_16S是把输出数值转换成16位有符号数;
Sobel(src, sobel_y, CV_16S, 0, 1, 1, BORDER_DEFAULT);//对y求偏导
grad = abs(sobel_x) + abs(sobel_y);//求模
grad.convertTo(qwe, CV_8U);//转换为8位无符号数;
//可以自己设置滤波器然后进行滤波
kernel = (Mat_< int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, wer, -1, kernel);//kernel滤波器
namedWindow(“output”,WINDOW_AUTOSIZE);
imshow(“output”,dst);
waitKey(0);
return 0;
}
以上代码是自己所写,如有错误,请指正,谢谢呀。
拉普拉斯算子的可以参考一下这篇文章
https://www.cnblogs.com/german-iris/p/4840647.html
梯度算子的可以参考一下这篇文章
https://blog.csdn.net/qq_24946843/article/details/82426442?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task