一、噪声的种类和生成
1.1椒盐噪声
椒盐噪声又称作脉冲噪声,它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声,其样子就像在图像上随机地撒上一些盐粒和黑椒粒,因此被称为椒盐噪声
在图像中添加椒盐噪声如下:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void saltAndPepper(cv::Mat image, int n)
{
for (int k = 0; k < n / 2; k++)
{
int i, j;
i = std::rand() % image.cols;
j = std::rand() % image.rows;
int write_black = std::rand() % 2;
if (write_black == 0)
{
if (image.type() == CV_8UC1)
{
image.at<uchar>(j, i) = 255;
}
else if (image.type() == CV_8UC3)
{
image.at<Vec3b>(j, i)[0] = 255;
image.at<Vec3b>(j, i)[1] = 255;
image.at<Vec3b>(j, i)[2] = 255;
}
}
else
{
if (image.type() == CV_8UC1)
{
image.at<uchar>(j, i) =0;
}
else if (image.type() == CV_8UC3)
{
image.at<Vec3b>(j, i)[0] = 0;
image.at<Vec3b>(j, i)[1] = 0;
image.at<Vec3b>(j, i)[2] = 0;
}
}
}
}
int main()
{
Mat lena = imread("D://lena.png");//自已定义导入的图像
Mat equalLena = imread("D://equalLena.png", IMREAD_ANYDEPTH);
if (lena.empty() || equalLena.empty())
{
cout << "请确认是否正确" << endl;
return -1;
}
imshow("lena原图",lena);
imshow("equalLena原图", equalLena);
saltAndPepper(lena, 10000);
saltAndPepper(equalLena, 10000);
imshow("lena添加椒盐噪声",lena);
imshow("equalLena添加椒盐噪声", equalLena);
waitKey(0);
return 0;
}
1.2高斯噪声
高斯噪声是指噪声分布的概率密度函数服从高斯分布(正态分布)的一类噪声,其产生的主要原因是相机在拍摄时视场较暗且亮度不均匀。相机长时间工作使得温度过高同样会引起高斯噪声,另外,电路元器件自身噪声和互相影响也是造成高斯噪声的重要原因之一
在图像中添加高斯噪声
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void GaussianNoise(Mat imag1,Mat imag2)
{
Mat lena_noise = Mat::zeros(imag1.rows, imag1.cols, imag1.type());
Mat equalLena_noise = Mat::zeros(imag1.rows, imag1.cols, imag2.type())
RNG rng;
rng.fill(lena_noise, RNG::NORMAL, 10, 20);
rng.fill(equalLena_noise, RNG::NORMAL, 15, 30);
imshow("三通道高斯噪声", lena_noise);
imshow("单通道高斯噪声", equalLena_noise);
imag1 = imag1 + lena_noise;
imag2 = imag2 + equalLena_noise;
imshow("lena添加高斯噪声", imag1);
imshow("equalLen高斯噪声", imag2);
}
int main()
{
Mat lena = imread("D://lena.png");
Mat equalLena = imread("D://equalLena.png", IMREAD_ANYDEPTH);
if (lena.empty() || equalLena.empty())
{
cout << "请确认是否正确" << endl;
return -1;
}
imshow("lena原图",lena);
imshow("equalLena原图", equalLena);
GaussianNoise(lena,equalLena);
waitKey(0);
return 0;
}
二、图像的线性滤波
2.1图像均值滤波
int main()
{
Mat lena = imread("D://lena.png", IMREAD_ANYDEPTH);
Mat lena_salt = imread("D://lena_salt.png", IMREAD_ANYDEPTH);
Mat lena_guass = imread("D://lena_guass.png", IMREAD_ANYDEPTH);
if (lena.empty() || lena_salt.empty() || lena_guass.empty())
{
cout << "could not load in ...." << endl;
return -1;
}
Mat result_3, result_9;
Mat result_3guass, result_9guass;
Mat result_3salt, result_9salt;
blur(lena, result_3, Size(3, 3));
blur(lena, result_9, Size(9, 9));
blur(lena_guass, result_3guass, Size(3, 3));
blur(lena_guass, result_9guass, Size(9, 9));
blur(lena_salt , result_3salt, Size(3, 3));
blur(lena_salt, result_9salt, Size(9, 9));
imshow("lena", lena);
imshow("result_3", result_3);
imshow("result_9", result_9);
imshow("lena_guass", lena_guass);
imshow("result_3guass", result_3guass);
imshow("result_9guass", result_9guass);
imshow("lena_salt", lena_salt);
imshow("result_3salt", result_3salt);
imshow("result_9salt", result_9salt);
waitKey(0);
return 0;
}
2.2图像方框滤波
int main()
{
Mat lena = imread("D://lena.png");
if (lena.empty())
{
cout << "could not load ...." << endl;
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", lena);
Mat lena_32F;
lena.convertTo(lena_32F, CV_32F, 1.0 / 255);
Mat resultNorm,lena_32fsqr;
boxFilter(lena, resultNorm, -1, Size(3, 3), Point(-1, -1), false);
sqrBoxFilter(lena_32F, lena_32fsqr, -1, Size(3, 3), Point(-1, -1), true);
imshow("resultNorm", resultNorm);
imshow("lena_32fsqr", lena_32fsqr);
waitKey(0);
return 0;
}
2.3图像高斯滤波
int main()
{
Mat lena = imread("D://lena.png");
Mat lena_salt = imread("D://lena_salt.png");
Mat lena_guass = imread("D://lena_guass.png");
if (lena.empty() || lena_salt.empty() || lena_guass.empty())
{
cout << "could not load in ...." << endl;
return -1;
}
Mat result_3, result_9;
Mat result_3guass, result_9guass;
Mat result_3salt, result_9salt;
GaussianBlur(lena, result_3, Size(3, 3),10,20);
GaussianBlur(lena, result_9, Size(9, 9),10,20);
GaussianBlur(lena_guass, result_3guass, Size(3, 3), 10, 20);
GaussianBlur(lena_guass, result_9guass, Size(9, 9), 10, 20);
GaussianBlur(lena_salt , result_3salt, Size(3, 3), 10, 20);
GaussianBlur(lena_salt, result_9salt, Size(9, 9), 10, 20);
imshow("lena", lena);
imshow("result_3", result_3);
imshow("result_9", result_9);
imshow("lena_guass", lena_guass);
imshow("result_3guass", result_3guass);
imshow("result_9guass", result_9guass);
imshow("lena_salt", lena_salt);
imshow("result_3salt", result_3salt);
imshow("result_9salt", result_9salt);
waitKey(0);
return 0;
}
三、图像的非线性滤波
3.1图像中值滤波
using namespace cv;
using namespace std;
int main()
{
Mat lena = imread("D://lena_salt.png");
if (lena.empty())
{
cout << "could not load ...." << endl;
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", lena);
Mat img3;
medianBlur(lena, img3, 3);
imshow("img3", img3);
waitKey(0);
return 0;
}
3.2图像双边滤波
int main()
{
Mat img1 = imread("D://lena.png");
Mat img2 = imread("D://test.png");
if (img1.empty()||img2.empty())
{
cout << "could not load ...." << endl;
return -1;
}
Mat result1, result2, result3, result4;
//验证不同滤波器直径的滤波效果
bilateralFilter(img1, result1, 9, 50, 25 / 2);
bilateralFilter(img1, result2, 25, 50, 25 / 2);
//验证不同标准差值的滤波效果
bilateralFilter(img2, result3, 9, 9, 9);
bilateralFilter(img2, result4, 9, 200, 200);
//显示原图
imshow("img1", img1);
imshow("img2", img2);
//不同滤波器直径效果
imshow("result1", result1);
imshow("result2", result2);
//不同标准插值效果
imshow("result3", result3);
imshow("result4", result4);
waitKey(0);
return 0;
}
四、图像的边缘检测
int main()
{
Mat kernel1 = (Mat_<float>(1, 2) << 1, -1);
Mat kernel2 = (Mat_<float>(1, 3) << 1, 0,-1);
Mat kernel3 = (Mat_<float>(3, 1) << 1, 0,-1);
Mat kernelXY = (Mat_<float>(2, 2) << 1,0,0,-1);
Mat kernelYX = (Mat_<float>(2, 2) << 0,-1,1,0);
Mat img = imread("D://test.png");
if (img.empty())
{
cout << "could not load ...." << endl;
return -1;
}
Mat result1, result2, result3, result4, result5, result6;
//检测图像边缘,以[1,-1]开始
filter2D(img, result1, CV_16S, kernel1);
convertScaleAbs(result1, result1);
//以[1,0,-1]检测水平方向边缘
filter2D(img, result2, CV_16S, kernel2);
convertScaleAbs(result2, result2);
//以[1,0,-1]检测垂直方向边缘
filter2D(img, result3, CV_16S, kernel3);
convertScaleAbs(result3, result3)
//整幅图像的边缘
result6 = result2 + result3;
//检测由左上到右下方向边缘
filter2D(img, result4, CV_16S, kernelXY);
convertScaleAbs(result4, result4);
//检测由右上到左下方向边缘
filter2D(img, result5, CV_16S, kernelYX);
convertScaleAbs(result5, result5);
namedWindow("img", WINDOW_FREERATIO);
imshow("img", img);
imshow("result1", result1);
imshow("result2", result2);
imshow("result3", result3);
imshow("result4", result4);
imshow("result5", result5);
imshow("result6", result6);
waitKey(0);
return 0;
}