图像平滑
1.1 算法介绍
(1)空间邻域平均法:
在图像中以当前像素 f(i,j)为中心切出一个 3*3 像素组成的图像块,如下图所示,设当
前像素 f(i,j)的灰度值为g(i,j)时,则:
g(i,j)={f(i,j)+f(i-1,j-1)+f(i,j-1)+f(i+1,j-1)+f(i-1,j)+f(i+1,j)+f(i-1,j+1),+f(i,j+1)+f(i+1,j+1)}/9
(2)中值滤波法:
中值滤波是指在图像中以当前像素 f(i,j)为中心切出一个 N*M(例如 3*3)像素组成的
图像块,如上图所示的那样,设当前像素 f(i,j)的灰度值为 g(i,j)时,则 g(i,j)取 N*N 个像素灰
度值中的中值值。
中值(定义):将一些数排序之后,正中间的一个数(奇数个数字),或者中间两个数的平均数.
选做内容:
(3)最大(小)值滤波:
最大(小)值滤波是指在图像中以当前像素 f(i,j)为中心切出一个 N*M(例如 3*3)像素组成
的图像块,设当前像素 f(i,j)的灰度值为 g(i,j)时,则 g(i,j)取 N*N 个诸像素灰度值中的最大(小)
值.
因为网上没有现成的最值滤波代码,下面简单地进行实现,程序很简单,这里需要说明的是,如果程序中的循环去掉了边缘像素,也就是这里:
for (int i = 1; i < rowNumber - 1; i++)
{
for (int j = 1; j <colNumber - 1; j++)
如果非要加上边缘像素运算也可以,同样非常简单,直接加边,在原有图像矩阵基础上四周各自加上一个像素单位的边缘即可。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
//*******************最值(最大/最小值)滤波********************
int main() {
Mat src = imread("1.jpg");
cvtColor(src, src, CV_BGR2GRAY);//转换为灰度图像
int rowNumber = src.rows;
int colNumber = src.cols;
Mat dst = Mat::zeros(rowNumber,colNumber, CV_8U);
imshow("【原图】", src);
//最大值滤波操作
for (int i = 1; i < rowNumber - 1; i++)
{
for (int j = 1; j <colNumber - 1; j++)
{
int maxt = 0; //如果是最小值滤波则初始化maxt=255;
for (int k = i - 1; k <=i + 1; k++)
for (int m = j - 1; m <=j + 1; m++)
if (maxt<src.at<uchar>(k, m))
//如果是最小值滤波,小于号改成大于号就可
maxt = src.at<uchar>(k, m);
dst.at<uchar>(i, j) = maxt;
}
}
imshow("【最大值处理后图像】", dst);
waitKey();
imwrite("最小值处理.jpg", dst);
imwrite("灰度图.jpg", dst);
return 0;
}
运行结果:
原灰度图像
最大值滤波得到的图像