簡介
高斯噪聲是指它的概率密度函數服從高斯分佈(即正態分佈)的一類噪聲,高斯噪聲是一個加性噪聲(加性噪聲一般指熱噪聲、散彈噪聲等,它們與信號的關係是相加,不管有沒有信號,噪聲都存在)。
產生原因:
1)圖像傳感器在拍攝時市場不夠明亮、亮度不夠均勻;
2)電路各元器件自身噪聲和相互影響;
3)圖像傳感器長期工作,溫度過高。
這裏說一下高斯白噪聲:
白噪聲是一種功率譜密度爲常數的隨機信號或隨機過程。換句話說,此信號在各個頻段上的功率是一樣的,由於白光是由各種頻率(顏色)的單色光混合而成,因此此信號的這種具有平坦功率譜的性質被稱作是“白色”,此信號也因此被稱作白噪聲。相對的,其他不具有這一性質的噪聲信號被稱爲有色噪聲(功率譜隨頻率變化)。
當隨機的從高斯分佈中獲取採樣值時,採樣點所組成的隨機過程就是“高斯白噪聲”;同理,當隨機的從均勻分佈中獲取採樣值時,採樣點所組成的隨機過程就是“均勻白噪聲”。
“非白的高斯”噪聲——高斯色噪聲。這種噪聲其分佈是高斯的,但是他的頻譜不是一個常數,或者說,對高斯信號採樣的時候不是隨機採樣的,而是按照某種規律來採樣的。
這麼說來我們添加的高斯噪聲應該大部分都爲高斯白噪聲。
對於灰度圖像的添加高斯噪聲有很多,也比較簡單,沒有什麼疑問。而對於彩色圖像,由於有三個通道,如何將高斯噪聲添加進去也有了不同的方法。目前我見到兩種方法:
(1)將彩色圖像分爲RGB三個通道,對每個通道都添加高斯噪聲,這樣添加的高斯噪聲會在圖像上形成彩色的噪點。
(2)將彩色圖像從RGB顏色模式轉換爲YCC顏色模式,對其中的亮度通道添加高斯噪聲,而後將YCC顏色模式再轉回RGB模式,這樣添加的高斯噪聲在圖像上只會表現出亮度不同的噪點,不對顏色造成影響。
效果如下圖:
原始圖像:
RGB三通道加高斯噪聲圖像:
YCC模式下Y道加高斯噪聲圖像:
OpenCV 代碼
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
using namespace cv;
using namespace std;
///////////////////////////////////////////////////////////////////////////////////////////////
//1. 將彩色圖像分爲RGB三個通道,對每個通道都添加高斯噪聲,這樣添加的高斯噪聲會在圖像上形成彩色的噪點。
// 方法來源:
///////////////////////////////////////////////////////////////////////////////////////////////
void GaussianNoiseFullChannel(const Mat &src, Mat &dst, double u, double v);
///////////////////////////////////////////////////////////////////////////////////////////////
//2. 將彩色圖像轉爲YCC顏色模式,分離通道,對Y通道添加高斯噪聲,合併通道(噪聲圖像無顏色變化,有亮度變化)
// 方法來源: https://blog.csdn.net/cutelily2014/article/details/50253583
///////////////////////////////////////////////////////////////////////////////////////////////
void GaussianNoiseSingleChannel(const Mat &src, Mat &dst, double u, double v);
int main()
{
Mat srcImg = imread("C:\\Users\\Wei\\Desktop\\w.jpg",IMREAD_COLOR);//原圖
Mat dstImg1;
Mat dstImg2;
double u = 0.0;
double v = 15.0;
GaussianNoiseFullChannel(srcImg, dstImg1,u,v);
GaussianNoiseSingleChannel(srcImg, dstImg2, u, v);
imshow("img", srcImg);//顯示噪聲圖像;
imshow("Full Channel", dstImg1);//顯示噪聲圖像;
imshow("Single Channel", dstImg2);//顯示噪聲圖像;
imwrite("C:\\Users\\Wei\\Desktop\\dstImg1.jpg", dstImg1);
imwrite("C:\\Users\\Wei\\Desktop\\dstImg2.jpg", dstImg2);
waitKey(0);
destroyAllWindows();
return 0;
}
void GaussianNoiseSingleChannel(const Mat &src, Mat &dst,double u, double v)
{
if (src.empty() || src.channels() != 3)
{
cout << "Image is empty or not 3 channels" << endl;
return;
}
Mat noiseImg(src.size(), CV_64FC1); //存放噪聲圖像
RNG rng((unsigned)time(NULL)); //生成隨機數 (均值,高斯)
rng.fill(noiseImg, RNG::NORMAL, u, v); //隨機高斯填充矩陣
Mat yccImg; //用來進行對原圖像的轉換
cvtColor(src, yccImg, COLOR_BGR2YCrCb); //色彩空間轉換;
Mat sigImg[3]; //用來存儲單通道圖像
split(yccImg, sigImg); //將圖像分解到單通道,一幅灰度圖像
sigImg[0].convertTo(sigImg[0], CV_64FC1); //將uchar轉爲double
sigImg[0] = sigImg[0] + noiseImg; //添加高斯噪聲()
sigImg[0].convertTo(sigImg[0], CV_8UC1); //Y通道加高斯噪聲後圖像,自動截斷小於零和大於255的值
Mat gaussianImg(src.size(), CV_8UC3); //添加高斯噪聲的圖像;
merge(sigImg, 3, gaussianImg); //和並三個通道
cvtColor(gaussianImg, dst, COLOR_YCrCb2BGR); //色彩空間轉換
//imshow("noise", sigImg[0]); //顯示噪聲圖像
}
void GaussianNoiseFullChannel(const Mat &src, Mat &dst,double u,double v)
{
if (src.empty() || src.channels() != 3)
{
cout << "Image is empty or not 3 channels" << endl;
return;
}
Mat noiseImg(src.size(), CV_64FC3); //存放噪聲圖像
RNG rng((unsigned)time(NULL)); //生成隨機數 (均值,高斯)
rng.fill(noiseImg, RNG::NORMAL, u, v); //隨機高斯填充矩陣
Mat gaussianImg;
src.convertTo(gaussianImg, CV_64FC3); //將uchar轉換爲double格式
gaussianImg = gaussianImg + noiseImg; //添加噪聲
gaussianImg.convertTo(dst, CV_8UC3); //將double轉爲uchar 自動截斷小於零和大於255的值
}