Noise
Input Image

Gaussian Noise
- Gaussian Noise란?
- 정규분포 Noise, 각 픽셀과 관련없이 독립적으로 생김.
- 아래 수식에서 n은 정규분포를 가지는 잡음

Salt&Pepper Noise
- Salt&Pepper Noise란?
- impulsive noise or spike noise
- 0 또는 1이 랜덤하게 생김

result

Code
KImageColor Gaussian_Noise;
KImageColor Salt_Noise;
if(_q_pFormFocused != 0 && _q_pFormFocused->ImageColor().Address() && _q_pFormFocused->ID() == "OPEN")
{
Gaussian_Noise = _q_pFormFocused->ImageColor();
Salt_Noise = _q_pFormFocused->ImageColor();
}
else
return;
double sigma = ui->spin_GaussianParameter->value();
KGaussian GauN;
GauN.Create(0, sigma*sigma);
GauN.OnRandom(Gaussian_Noise.Size());
double dNoise = 0;
double Kp = 8;
for(int i = 0; i<Gaussian_Noise.Row();i++){
for(int j = 0; j<Gaussian_Noise.Col();j++){
dNoise = GauN.Generate();
if(Gaussian_Noise[i][j].r + dNoise*Kp > 255)
Gaussian_Noise[i][j].r = 255;
else if(Gaussian_Noise[i][j].r +dNoise*Kp < 0)
Gaussian_Noise[i][j].r = 0;
else
Gaussian_Noise[i][j].r += dNoise*Kp;
if(Gaussian_Noise[i][j].g + dNoise*Kp > 255)
Gaussian_Noise[i][j].g = 255;
else if(Gaussian_Noise[i][j].g +dNoise*Kp < 0)
Gaussian_Noise[i][j].g = 0;
else
Gaussian_Noise[i][j].g += dNoise*Kp;
if(Gaussian_Noise[i][j].b + dNoise*Kp > 255)
Gaussian_Noise[i][j].b = 255;
else if(Gaussian_Noise[i][j].b +dNoise*Kp < 0)
Gaussian_Noise[i][j].b = 0;
else
Gaussian_Noise[i][j].b += dNoise*Kp;
}
}
srand((int)time(NULL));
double Thres = 0.005;
double minus_Thres = (double)(1-Thres);
double random;
for(int i=0; i<Salt_Noise.Row(); i++){
for(int j=0;j<Salt_Noise.Col();j++){
random = (double) rand()/RAND_MAX;
if(random<Thres)
{
Salt_Noise[i][j].r = 0;
Salt_Noise[i][j].g = 0;
Salt_Noise[i][j].b = 0;
}
else if(random>minus_Thres){
Salt_Noise[i][j].r = 255;
Salt_Noise[i][j].g = 255;
Salt_Noise[i][j].b = 255;
}
}
}
ImageForm* q_pForm1 = new ImageForm(Salt_Noise, "Salt_and_Pepper Noise", this);
_plpImageForm->Add(q_pForm1);
q_pForm1->show();
ImageForm* q_pForm2 = new ImageForm(Gaussian_Noise, "Gaussian Noise", this);
_plpImageForm->Add(q_pForm2);
q_pForm2->show();
Box, Gaussian, Median Filter
Input Image

Box Filter
- Box Filtering
- 주변 픽셀값의 평균을 얻는 방식의 이미지 필터링
- 이미지 샘플과 filter kernel을 곱해서 필터링된 결과값을 얻음

- 장점
- 빠르다
- Box(i+1) = Box(i) - neighborhood(i)[first] + neighborhood(i+1)[last]
- 단점
- Signal frequencies shared with noise are lose
- Impulse noise is diffused but not removed
- The secondary lobes let noise into the filtered image

result

Code
int filtersize = ui->spin_FilterSize->value();
ImageForm* q_pForm_s = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Salt_and_Pepper Noise")
{
q_pForm_s = (*_plpImageForm)[i];
break;
}
KImageColor Salt_Noise_2 = q_pForm_s->ImageColor();
ImageForm* q_pForm_g = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Gaussian Noise")
{
q_pForm_g = (*_plpImageForm)[i];
break;
}
KImageColor Gaussian_Noise_2 = q_pForm_g->ImageColor();
int size = 0.5*filtersize-0.5;
int box = filtersize*filtersize;
double sum_r_s,sum_g_s,sum_b_s;
double sum_r_g,sum_g_g,sum_b_g;
for(int ii = size; ii<Salt_Noise_2.Row()-size;ii++){
for(int jj = size; jj<Salt_Noise_2.Col()-size;jj++){
sum_r_s = 0;
sum_g_s = 0;
sum_b_s = 0;
sum_r_g = 0;
sum_g_g = 0;
sum_b_g = 0;
for(int i = -size; i<size+1; i++){
for(int j = -size; j<size+1;j++){
sum_r_s+=Salt_Noise[ii-i][jj-j].r;
sum_g_s+=Salt_Noise[ii-i][jj-j].g;
sum_b_s+=Salt_Noise[ii-i][jj-j].b;
sum_r_g+=Gaussian_Noise[ii-i][jj-j].r;
sum_g_g+=Gaussian_Noise[ii-i][jj-j].g;
sum_b_g+=Gaussian_Noise[ii-i][jj-j].b;
}
}
Salt_Noise_2[ii][jj].r=sum_r_s/box;
Salt_Noise_2[ii][jj].g=sum_g_s/box;
Salt_Noise_2[ii][jj].b=sum_b_s/box;
Gaussian_Noise_2[ii][jj].r=sum_r_g/box;
Gaussian_Noise_2[ii][jj].g=sum_g_g/box;
Gaussian_Noise_2[ii][jj].b=sum_b_g/box;
}
}
ImageForm* q_pForm3 = new ImageForm(Salt_Noise_2, "Box_Salt_n_Pepper", this);
_plpImageForm->Add(q_pForm3);
q_pForm3->show();
ImageForm* q_pForm4 = new ImageForm(Gaussian_Noise_2, "Box_Gaussian", this);
_plpImageForm->Add(q_pForm4);
q_pForm4->show();
Gaussian Filter

- 장점
- Secondary lobes가 없으므로 정확한 low-pass filter 구현이 가능하다.

result

Code
ImageForm* q_pForm_s = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Salt_and_Pepper Noise")
{
q_pForm_s = (*_plpImageForm)[i];
break;
}
KImageColor Salt_Noise_2 = q_pForm_s->ImageColor();
ImageForm* q_pForm_g = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Gaussian Noise")
{
q_pForm_g = (*_plpImageForm)[i];
break;
}
KImageColor Gaussian_Noise_2 = q_pForm_g->ImageColor();
int Gau_filter_size = 8*sigma + 1;
int size = std::sqrt(Gau_filter_size);
double mask_r_s, mask_g_s, mask_b_s;
double mask_r_g, mask_g_g, mask_b_g;
for(int ii = size; ii<Salt_Noise_2.Row()-size;ii++){
for(int jj = size; jj<Salt_Noise_2.Col()-size;jj++){
mask_r_s = 0;
mask_g_s = 0;
mask_b_s = 0;
mask_r_g = 0;
mask_g_g = 0;
mask_b_g = 0;
for(int i = -size; i<size+1; i++){
for(int j = -size; j<size+1;j++){
mask_r_s += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Salt_Noise[ii-i][jj-j].r;
mask_g_s += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Salt_Noise[ii-i][jj-j].g;
mask_b_s += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Salt_Noise[ii-i][jj-j].b;
mask_r_g += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Gaussian_Noise[ii-i][jj-j].r;
mask_g_g += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Gaussian_Noise[ii-i][jj-j].g;
mask_b_g += std::exp(-0.5*((i*i+j*j)/(sigma*sigma)))*Gaussian_Noise[ii-i][jj-j].b;
}
}
Salt_Noise_2[ii][jj].r = (1/(2*M_PI*sigma*sigma))*mask_r_s;
Salt_Noise_2[ii][jj].g = (1/(2*M_PI*sigma*sigma))*mask_g_s;
Salt_Noise_2[ii][jj].b = (1/(2*M_PI*sigma*sigma))*mask_b_s;
Gaussian_Noise_2[ii][jj].r = (1/(2*M_PI*sigma*sigma))*mask_r_g;
Gaussian_Noise_2[ii][jj].g = (1/(2*M_PI*sigma*sigma))*mask_g_g;
Gaussian_Noise_2[ii][jj].b = (1/(2*M_PI*sigma*sigma))*mask_b_g;
}
}
ImageForm* q_pForm3 = new ImageForm(Salt_Noise_2, "Gaussian_Salt_n_Pepper", this);
_plpImageForm->Add(q_pForm3);
q_pForm3->show();
ImageForm* q_pForm4 = new ImageForm(Gaussian_Noise_2, "Gaussian_Gaussian", this);
_plpImageForm->Add(q_pForm4);
q_pForm4->show();
Median Filter
- Median Filtering
- 주변 픽셀값을 sort한 후 중간값을 구하는 방식의 이미지 필터링
- 장점
- 경계가 흐려지지 않음
- 중간값을 선택하는 방법이기 때문에 Salt and Pepper noise에 강함

result

Code
int filtersize = ui->spin_FilterSize->value();
ImageForm* q_pForm_s = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Salt_and_Pepper Noise")
{
q_pForm_s = (*_plpImageForm)[i];
break;
}
KImageColor Salt_Noise_2 = q_pForm_s->ImageColor();
ImageForm* q_pForm_g = 0;
for(int i=0; i<_plpImageForm->Count();i++)
if((*_plpImageForm)[i]->ID()=="Gaussian Noise")
{
q_pForm_g = (*_plpImageForm)[i];
break;
}
KImageColor Gaussian_Noise_2 = q_pForm_g->ImageColor();
int size = 0.5*filtersize-0.5;
std::vector<double> v_r_s,v_g_s,v_b_s;
std::vector<double> v_r_g,v_g_g,v_b_g;
int box = filtersize*filtersize;
for(int ii = size; ii<Salt_Noise_2.Row()-size;ii++){
for(int jj = size; jj<Salt_Noise_2.Col()-size;jj++){
v_r_s.clear();
v_g_s.clear();
v_b_s.clear();
v_r_g.clear();
v_g_g.clear();
v_b_g.clear();
for(int i = -size; i<size+1; i++){
for(int j = -size; j<size+1;j++){
v_r_s.push_back(Salt_Noise[ii-i][jj-j].r);
v_g_s.push_back(Salt_Noise[ii-i][jj-j].g);
v_b_s.push_back(Salt_Noise[ii-i][jj-j].b);
v_r_g.push_back(Gaussian_Noise[ii-i][jj-j].r);
v_g_g.push_back(Gaussian_Noise[ii-i][jj-j].g);
v_b_g.push_back(Gaussian_Noise[ii-i][jj-j].b);
}
}
sort(v_r_s.begin(),v_r_s.end());
sort(v_g_s.begin(),v_g_s.end());
sort(v_b_s.begin(),v_b_s.end());
sort(v_r_g.begin(),v_r_g.end());
sort(v_g_g.begin(),v_g_g.end());
sort(v_b_g.begin(),v_b_g.end());
Salt_Noise_2[ii][jj].r = v_r_s[box/2];
Salt_Noise_2[ii][jj].g = v_g_s[box/2];
Salt_Noise_2[ii][jj].b = v_b_s[box/2];
Gaussian_Noise_2[ii][jj].r = v_r_g[box/2];
Gaussian_Noise_2[ii][jj].g = v_g_g[box/2];
Gaussian_Noise_2[ii][jj].b = v_b_g[box/2];
}
}
ImageForm* q_pForm3 = new ImageForm(Salt_Noise_2, "Median_Salt_n_Pepper", this);
_plpImageForm->Add(q_pForm3);
q_pForm3->show();
ImageForm* q_pForm4 = new ImageForm(Gaussian_Noise_2, "Median_Gaussian", this);
_plpImageForm->Add(q_pForm4);
q_pForm4->show();