利用CImage類對影象進行高斯噪聲生成
阿新 • • 發佈:2019-01-27
課上作業要求利用C裡面的自帶類庫對影象做一個高斯噪聲的生成,記錄一下大概的原理和步驟。
首先是對高斯函式的理解
這個函式是一個高斯概率密度的分佈表示式,表示為X~N(μ,σ²),其中μ表示均值,σ²表示方差,當μ=0,σ²=1時為標準正態分佈。
而高斯噪聲是要求生成的噪聲的概率密度函式符合高斯分佈。我覺得可以理解為所有的噪聲取樣服從高斯分佈的一種噪聲。有關高斯噪聲和高斯白噪聲的理解參考
高斯噪聲的生成就是在影象所有畫素上新增一個噪聲訊號:
n(x,y)=o(x,y)+g(x,y)
其關鍵是如何生成這個g(x,y)。當然x和y只是表示影象畫素的座標,對原畫素值加上一個高斯取樣值就可以生成一個高斯噪聲。計算機中生成高斯取樣的方法有很多,這裡我使用的是比較常用的Box-Muller
使用方法是首先生成兩個數a,b為在[0,1]的均勻分佈隨機取樣;
根據box-muller方法,對a,b做如下運算可以得到服從高斯分佈的兩個隨機數
使用任何一個都可以,我覺得這是二維的高斯取樣,然後咱們在這裡只需要選擇任何一維都可以。
最終生成的噪聲點為
n(x,y)=o(x,y)+(μ+N*σ);
接下來是利用CImage對影象進行處理階段了
下面我放上我的程式碼和效果圖
巨集定義和main函式部分
接下來是高斯噪聲生成函式#include <atlimage.h> #include<iostream> #include<stdio.h> #include<stdlib.h> #include<time.h> #define MU 0 //均值 #define SIGMA 2 //方差 #define k 16 #define PI 3.1415926 using namespace std; int addNoise(const CImage& input, CImage& noise); double guass(); int makeNoise(CImage input); int addNoise(const CImage& input, CImage& noise); int main() { CString ImagePath = "E:\\1myRobotFile\\公式演算法專案\\CameraCalibration\\input.jpg"; CImage image, noise; //讀入圖片 image.Load(ImagePath); makeNoise(image); cout << "successd" << endl; system("pause"); }
double guass() { //生成0-1的隨機數 double x1, x2; //生成0-1兩個隨機數 x1 = rand() / ((double)RAND_MAX); x2 = rand() / ((double)RAND_MAX); if (x1 < 1e-100) x1 = 1e-100; x1 = (-2) * log(x1); x2 = x2 * PI * 2; double g = MU + (sqrt(x1) * cos(x2)) * SIGMA; //double g = MU + (sqrt(x1) * sin(x2)) * SIGMA; return g; }
最後是輸出高斯噪聲模版和高斯噪聲疊加影象
int makeNoise(CImage input)
{
if (input == 0)
{
cout << "圖片輸入錯誤!" << endl;
return 0;
}
//噪聲圖片的建立
CImage gaussNoise, In;
CString ImagePath = "E:\\1myRobotFile\\公式演算法專案\\CameraCalibration\\input.jpg";
In.Load(ImagePath);
gaussNoise = input;
//gaussNoise.Create(input.GetWidth(), input.GetHeight(), 8);
//高斯噪音生成
int r, g, b;
for (int i = 0; i<gaussNoise.GetWidth(); i++)
{
for (int j = 0; j<gaussNoise.GetHeight(); j++)
{
r = guass();
g = guass();
b = guass();
gaussNoise.SetPixelRGB(i, j, r, g, b);
}
}
CString SImagePath = "E:\\1myRobotFile\\公式演算法專案\\CameraCalibration\\noise.jpg";
gaussNoise.Save(SImagePath);
addNoise(In, gaussNoise);
}
//噪聲和原圖的相加
int addNoise(const CImage& input, CImage& noise)
{
CImage addnoise;
COLORREF pixel1;
COLORREF pixel2;
int r, g, b;
if (input == 0 || noise == 0)
{
cout << "圖片輸入錯誤!" << endl;
return 0;
}
addnoise = input;
int w = addnoise.GetWidth();
int h = addnoise.GetHeight();
for (int i = 0; i < w; i++)
{
for (int j = 0; j<h; j++)
{
pixel1 = input.GetPixel(i, j);
pixel2 = noise.GetPixel(i, j);
/*r = GetRValue(pixel1);
g = GetGValue(pixel1);
b = GetBValue(pixel1);
cout << r << "," << g << "," << b << endl;*/
//r = GetRValue(pixel1) + GetRValue(pixel2) - 128;
//g = GetGValue(pixel1) + GetGValue(pixel2) - 128;
//b = GetBValue(pixel1) + GetBValue(pixel2) - 128;
r = GetRValue(pixel1) + GetRValue(pixel2) *k;
g = GetGValue(pixel1) + GetGValue(pixel2) *k;
b = GetBValue(pixel1) + GetBValue(pixel2) *k;
//cout << r << "," << g << "," << b << endl;
if (r>255)
{
r = 255;
}
if (g>255)
{
g = 255;
}
if (b>255)
{
b = 255;
}
if (r<0)
{
r = 0;
}
if (g<0)
{
g = 0;
}
if (b<0)
{
b = 0;
}
addnoise.SetPixelRGB(i, j, r, g, b);
}
}
CString SImagePath = "E:\\1myRobotFile\\公式演算法專案\\CameraCalibration\\output.jpg";
addnoise.Save(SImagePath);
}
效果圖如下
原圖
噪聲影象(μ=0,σ=2)
帶有高斯噪聲的影象