#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
using namespace cv;
int Rows;//图像的行数
int Cols;//图像的列数
//生成高斯噪声
double generateGaussianNoise(const double &sigma,const double & mu)
{
const double epsilon = std::numeric_limits<double>::min();//返回目标数据类型能表示的最逼近1的正数和1的差的绝对值
static double z0, z1;
//构造随机变量
double u0, u1;
do
{
u0 = rand()*(1.0 / RAND_MAX);
u1 = rand()*(1.0 / RAND_MAX);
} while (u0 <epsilon||u1<epsilon);
z0 = sqrt(-2.0*log(u0))*cos(2 * CV_PI*u1);
//z1 = sqrt(-2.0*log(u0))*sin(2 * CV_PI*u1);
return z0 * sigma + mu;
}
//给图像添加高斯噪声
Mat addGaussianNoise(const Mat &grayImage)
{
double sigma=2.0; //方差
double mu=1; //均值
double k=10; //比例系数
Mat resultImage = grayImage.clone(); //图像的拷贝
for (int i = 0; i < Rows; i++)
{
for (int j = 0; j < Cols; j++)
{
double temp= resultImage.at<uchar>(i, j) + generateGaussianNoise(sigma,mu) * k;
if (temp < 0)
temp= 0;
if (temp> 255)
temp= 255;
resultImage.at<uchar>(i, j) = (uchar)temp;
}
}
return resultImage;
}
//给图像添加椒盐噪声
Mat addSaltPepperNoise(const Mat &grayImage)
{
Mat resultImage = grayImage.clone(); //图像的拷贝
int sp = Rows * Cols;
double snr = 0.9;
int np = int(sp * (1 - snr));
//std::cout << np << std::endl;
for (int i = 0; i < np; i++)
{
//产生随机的位置
int randx = rand()%Rows;
int randy = rand()%Cols;
int noise = rand() % 2;
if (noise)
{
resultImage.at<uchar>(randx, randy) = 255;
}
else
{
resultImage.at<uchar>(randx, randy) = 0;
}
}
return resultImage;
}
//给图像添加随机白噪声
Mat addRandWhiteNoise(const Mat &grayImage)
{
Mat resultImage = grayImage.clone(); //图像的拷贝
int sp = Rows * Cols;
double snr = 0.8;
int np = int(sp * (1 - snr));
//std::cout << np << std::endl;
for (int i = 0; i < np; i++)
{
//产生随机的位置
int randx = rand() % Rows;
int randy = rand() % Cols;
resultImage.at<uchar>(randx, randy) = 255;
}
return resultImage;
}
//均值滤波
Mat meanFilter(const Mat &imageNoise,int m,int n)
{
Mat resultImage = imageNoise.clone();
//图像的边缘不做处理
for (int i = m / 2; i < Rows - m / 2; i++)
{
for (int j = n / 2; j < Cols - n / 2; j++)
{
double temp = 0;
for (int x = i - m / 2; x <= i + m / 2; x++)
{
for (int y = j - n / 2; y <= j + n / 2; y++)
{
temp += imageNoise.at<uchar>(x, y);
}
}
resultImage.at<uchar>(i, j) = temp / (m*n);
}
}
return resultImage;
}
//中值滤波
Mat medianFilter(const Mat &imageNoise,int m,int n)
{
Mat resultImage = imageNoise.clone();
for (int i = m / 2; i < Rows - m / 2; i++)
{
for (int j = n / 2; j < Cols - n / 2; j++)
{
std::vector<double>getNearPixel;
double temp;
for (int x = i - m / 2; x <= i + m / 2; x++)
{
for (int y = j - n / 2; y <= j + n / 2; y++)
{
temp=imageNoise.at<uchar>(x, y);
getNearPixel.push_back(temp);
}
}
std::sort(getNearPixel.begin(), getNearPixel.end());
resultImage.at<uchar>(i, j) = getNearPixel[m*n/2];
}
}
return resultImage;
}
int main()
{
using namespace cv;
//读入图像并创建图像矩阵
Mat srcImage = imread("D:\\figure\\lena2.jpg");
Mat grayImage;
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//imshow("grayImage", grayImage);
//waitKey(0);
Rows = grayImage.rows;//行数
Cols = grayImage.cols;//列数
/*添加噪声处理*/
//添加高斯噪声
//Mat imageAddGn = addGaussianNoise(grayImage);
//imshow("imageGuassionNoise", imageAddGn);
//waitKey(0);
//添加椒盐噪声
//Mat imageAddSp = addSaltPepperNoise(grayImage);
//imshow("addSaltPepperNoise", imageAddSp);
//waitKey(0);
//添加随机白噪声
Mat imageAddRw = addRandWhiteNoise(grayImage);
//imshow("addRandWhiteNoise",imageAddRw);
//waitKey(0);
//去除噪声处理
//去除高斯噪声
//Mat imageDelGn1 = meanFilter(imageAddGn, 3, 3);
//Mat imageDelGn2 = medianFilter(imageAddGn, 5, 5);
//imshow("imageDelGn",imageDelGn2);
//waitKey(0);
//去除椒盐噪声
//Mat imageDelSp1 = meanFilter(imageAddSp, 5, 5);
//Mat imageDelSp2 = medianFilter(imageAddSp, 3, 3);
//imshow("imageDesSp",imageDelSp2);
//waitKey(0);
//去除随机白噪声
//Mat imageDelRw1 = meanFilter(imageAddRw, 5, 5);
Mat imageDelRw2 = medianFilter(imageAddRw, 5, 5);
imshow("imageDesRw", imageDelRw2);
waitKey(0);
return 0;
}
添加高斯噪声、椒盐噪声与均值、中值滤波处理
最新推荐文章于 2022-10-01 11:19:33 发布