代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
//添加椒盐噪声
Mat addSaltNoise(Mat srcImage, int n)
{
Mat resultImage = srcImage.clone();
for (int k = 0; k < n; k++)
{
//随机取行列值
int i = rand() % resultImage.cols;
//%是求余运算,rand求随机数,一起是求0-图像列值之间的随机数
int j = rand() % resultImage.rows;
if (resultImage.channels() == 1) {
resultImage.at<uchar>(j, i) = 255;
}
else
{
resultImage.at<Vec3b>(j, i)[0] = 255;
resultImage.at<Vec3b>(j, i)[1] = 255;
resultImage.at<Vec3b>(j, i)[2] = 255;
}
}
return resultImage;
}
//均值滤波
Mat myAverage(Mat& srcImage)
{
if (srcImage.channels() != 1) { cvtColor(srcImage, srcImage, COLOR_BGR2GRAY); }
imshow("gray", srcImage);
Mat dstImage = Mat::zeros(srcImage.size(), srcImage.type());
//Mat mask = Mat::ones(3, 3, srcImage.type());
for (int k = 1; k < srcImage.rows-1; k++)
{
for (int n = 1; n < srcImage.cols - 1; n++)
{
uchar f = 0;
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
f += srcImage.at<uchar>(k + i, n + j);
}
}
dstImage.at<uchar>(k, n) =uchar( f / 9);
}
}
return dstImage;
}
//中值滤波
Mat myMedian(Mat& srcImage)
{
Mat dstImage = srcImage.clone();
//定义一个向量List
vector<uchar>List;
//遍历图像源
for (int k = 1; k < srcImage.cols - 1; k++)
{
for (int n = 1; n < srcImage.rows - 1; n++) {
//对模板窗口进行遍历
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
//将窗口内的像素放进向量内
List.push_back(srcImage.at<uchar>(n + j, k + i));
}
}
//对窗内元素进行排序
sort(List.begin(), List.end());
//取向量的中间元素作为当前元素
dstImage.at<uchar>(n, k) = List[5];
//清除当前向量内的元素
List.clear();
}
}
return dstImage;
}
int main()
{
Mat srcImage = imread("C:/Users/86176/Pictures/pics/house.jpg");
if (srcImage.empty()) { printf("no image\n"); return -1; }
Mat resultImage=addSaltNoise(srcImage, 5000);
imshow("原图", srcImage);
imshow("椒盐", resultImage);
Mat dstImage = myAverage(resultImage);
imshow("均值滤波", dstImage);
Mat dst = myMedian(resultImage);
imshow("中值滤波", dst);
waitKey(0);
return 0;
}
//
效果
原图
添加椒盐噪声
均值滤波
中值滤波