给图像分别添加高斯噪声、椒盐噪声和均匀分布的噪声, 然后分别使用空间滤波器进行图像复原,要求使用均值滤波 器中至少四种滤波器进行处理,并比较各滤波器的效果。C++
时间: 2024-03-20 08:42:53 浏览: 84
以下是使用C++进行图像噪声添加和空间滤波的示例代码:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace cv;
using namespace std;
// 添加高斯噪声
void addGaussianNoise(Mat& img, double mean, double stddev)
{
Mat noise = Mat::zeros(img.size(), CV_8UC1);
randn(noise, mean, stddev); // 生成高斯噪声矩阵
img += noise; // 像素值加上噪声值
}
// 添加椒盐噪声
void addSaltPepperNoise(Mat& img, double ratio)
{
int num = img.rows * img.cols * ratio;
for (int i = 0; i < num; i++)
{
int x = rand() % img.cols;
int y = rand() % img.rows;
if (rand() % 2 == 0)
img.at<uchar>(y, x) = 0; // 盐噪声
else
img.at<uchar>(y, x) = 255; // 椒噪声
}
}
// 添加均匀分布噪声
void addUniformNoise(Mat& img, double a, double b)
{
Mat noise = Mat::zeros(img.size(), CV_8UC1);
randu(noise, Scalar(a), Scalar(b)); // 生成均匀分布噪声矩阵
img += noise; // 像素值加上噪声值
}
// 均值滤波器
Mat meanFilter(const Mat& img, int ksize)
{
Mat result = Mat::zeros(img.size(), CV_8UC1);
int border = ksize / 2;
for (int i = border; i < img.rows - border; i++)
{
for (int j = border; j < img.cols - border; j++)
{
int sum = 0;
for (int y = -border; y <= border; y++)
{
for (int x = -border; x <= border; x++)
{
sum += img.at<uchar>(i + y, j + x);
}
}
result.at<uchar>(i, j) = sum / (ksize * ksize);
}
}
return result;
}
// 加权均值滤波器
Mat weightedMeanFilter(const Mat& img, int ksize)
{
Mat result = Mat::zeros(img.size(), CV_8UC1);
int border = ksize / 2;
double weight = 1.0 / (ksize * ksize);
double centerWeight = (ksize * ksize - 1) * weight;
for (int i = border; i < img.rows - border; i++)
{
for (int j = border; j < img.cols - border; j++)
{
double sum = 0;
for (int y = -border; y <= border; y++)
{
for (int x = -border; x <= border; x++)
{
if (y == 0 && x == 0)
sum += centerWeight * img.at<uchar>(i + y, j + x);
else
sum += weight * img.at<uchar>(i + y, j + x);
}
}
result.at<uchar>(i, j) = sum;
}
}
return result;
}
// 中值滤波器
Mat medianFilter(const Mat& img, int ksize)
{
Mat result = Mat::zeros(img.size(), CV_8UC1);
int border = ksize / 2;
vector<uchar> values(ksize * ksize);
for (int i = border; i < img.rows - border; i++)
{
for (int j = border; j < img.cols - border; j++)
{
int index = 0;
for (int y = -border; y <= border; y++)
{
for (int x = -border; x <= border; x++)
{
values[index++] = img.at<uchar>(i + y, j + x);
}
}
sort(values.begin(), values.end());
result.at<uchar>(i, j) = values[ksize * ksize / 2];
}
}
return result;
}
// 自适应加权平均滤波器
Mat adaptiveWeightedMeanFilter(const Mat& img, int ksize, double delta)
{
Mat result = Mat::zeros(img.size(), CV_8UC1);
int border = ksize / 2;
double weight = 1.0 / (ksize * ksize);
for (int i = border; i < img.rows - border; i++)
{
for (int j = border; j < img.cols - border; j++)
{
double sum = 0;
double center = img.at<uchar>(i, j);
for (int y = -border; y <= border; y++)
{
for (int x = -border; x <= border; x++)
{
double diff = abs(img.at<uchar>(i + y, j + x) - center);
double w = diff <= delta ? weight / (1 + diff * diff / (delta * delta)) : 0;
sum += w * img.at<uchar>(i + y, j + x);
}
}
result.at<uchar>(i, j) = sum;
}
}
return result;
}
int main()
{
srand(time(NULL));
Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
if (img.empty())
{
cout << "Failed to read image" << endl;
return -1;
}
// 添加高斯噪声
Mat img1 = img.clone();
addGaussianNoise(img1, 0, 10);
// 添加椒盐噪声
Mat img2 = img.clone();
addSaltPepperNoise(img2, 0.1);
// 添加均匀分布噪声
Mat img3 = img.clone();
addUniformNoise(img3, -50, 50);
// 均值滤波器
Mat mean1 = meanFilter(img1, 3);
Mat mean2 = meanFilter(img1, 5);
Mat mean3 = meanFilter(img1, 7);
Mat mean4 = meanFilter(img1, 9);
// 加权均值滤波器
Mat weightedMean1 = weightedMeanFilter(img1, 3);
Mat weightedMean2 = weightedMeanFilter(img1, 5);
Mat weightedMean3 = weightedMeanFilter(img1, 7);
Mat weightedMean4 = weightedMeanFilter(img1, 9);
// 中值滤波器
Mat median1 = medianFilter(img1, 3);
Mat median2 = medianFilter(img1, 5);
Mat median3 = medianFilter(img1, 7);
Mat median4 = medianFilter(img1, 9);
// 自适应加权平均滤波器
Mat adaptiveWeightedMean1 = adaptiveWeightedMeanFilter(img1, 3, 10);
Mat adaptiveWeightedMean2 = adaptiveWeightedMeanFilter(img1, 5, 10);
Mat adaptiveWeightedMean3 = adaptiveWeightedMeanFilter(img1, 7, 10);
Mat adaptiveWeightedMean4 = adaptiveWeightedMeanFilter(img1, 9, 10);
// 显示结果
namedWindow("Original", WINDOW_NORMAL);
namedWindow("Gaussian Noise", WINDOW_NORMAL);
namedWindow("Mean Filter 3x3", WINDOW_NORMAL);
namedWindow("Mean Filter 5x5", WINDOW_NORMAL);
namedWindow("Mean Filter 7x7", WINDOW_NORMAL);
namedWindow("Mean Filter 9x9", WINDOW_NORMAL);
namedWindow("Weighted Mean Filter 3x3", WINDOW_NORMAL);
namedWindow("Weighted Mean Filter 5x5", WINDOW_NORMAL);
namedWindow("Weighted Mean Filter 7x7", WINDOW_NORMAL);
namedWindow("Weighted Mean Filter 9x9", WINDOW_NORMAL);
namedWindow("Median Filter 3x3", WINDOW_NORMAL);
namedWindow("Median Filter 5x5", WINDOW_NORMAL);
namedWindow("Median Filter 7x7", WINDOW_NORMAL);
namedWindow("Median Filter 9x9", WINDOW_NORMAL);
namedWindow("Adaptive Weighted Mean Filter 3x3", WINDOW_NORMAL);
namedWindow("Adaptive Weighted Mean Filter 5x5", WINDOW_NORMAL);
namedWindow("Adaptive Weighted Mean Filter 7x7", WINDOW_NORMAL);
namedWindow("Adaptive Weighted Mean Filter 9x9", WINDOW_NORMAL);
imshow("Original", img);
imshow("Gaussian Noise", img1);
imshow("Mean Filter 3x3", mean1);
imshow("Mean Filter 5x5", mean2);
imshow("Mean Filter 7x7", mean3);
imshow("Mean Filter 9x9", mean4);
imshow("Weighted Mean Filter 3x3", weightedMean1);
imshow("Weighted Mean Filter 5x5", weightedMean2);
imshow("Weighted Mean Filter 7x7", weightedMean3);
imshow("Weighted Mean Filter 9x9", weightedMean4);
imshow("Median Filter 3x3", median1);
imshow("Median Filter 5x5", median2);
imshow("Median Filter 7x7", median3);
imshow("Median Filter 9x9", median4);
imshow("Adaptive Weighted Mean Filter 3x3", adaptiveWeightedMean1);
imshow("Adaptive Weighted Mean Filter 5x5", adaptiveWeightedMean2);
imshow("Adaptive Weighted Mean Filter 7x7", adaptiveWeightedMean3);
imshow("Adaptive Weighted Mean Filter 9x9", adaptiveWeightedMean4);
waitKey(0);
return 0;
}
```
其中,`addGaussianNoise`、`addSaltPepperNoise`和`addUniformNoise`分别用于添加高斯噪声、椒盐噪声和均匀分布噪声;`meanFilter`、`weightedMeanFilter`、`medianFilter`和`adaptiveWeightedMeanFilter`分别用于实现均值滤波器、加权均值滤波器、中值滤波器和自适应加权平均滤波器。在`main`函数中,首先读入`lena.jpg`图像,然后依次对其添加高斯噪声、椒盐噪声和均匀分布噪声,并使用均值滤波器中的四种滤波器、加权均值滤波器、中值滤波器和自适应加权平均滤波器进行处理,最后将处理结果显示出来。
阅读全文