Saturday, November 25, 2006

Understanding of Gaussian noise


void GrayImage::addGaussianNoise (double mean, double variance)
{
  cout << " Adding Gaussian noise with mean = " << mean << "and variance = "
  << variance << " to the image..." ;

  cout.flush();
  srand(1);
  #define unit_random() (1.0*rand()/RAND_MAX)
  #define TWO_PI 6.28318530717958647688
  double temp, u1, u2;
  int ix, iy;
  int num = width*height;
  int tempint;
  u1=0.0;
  for(int i = 0; i < num/2; i++) //奇偶數分開且同時處理
                   故只需要一半的點數
  {
    while (u1 == 0.0) u1 = unit_random(); //避免log(u1)為Error
    u2 = unit_random();
    temp = sqrt(-2.0*variance*log(u1)); //part of Box-Muller Eq.
    ix = (2*i)/width; //偶數列位置,如 p[even][*] 偶數處理部份開始
    iy = (2*i)%width; //偶數行位置,如 p[*][even]
    tempint = p[ix][iy] + (int) (temp * cos(TWO_PI*u2) + mean);
    if (tempint > 255)
      p[ix][iy] = 255;
    else if (tempint < 0)
      p[ix][iy] = 0;
    else
      p[ix][iy] = (unsigned char) tempint; //轉成char型態
                         //是因為tempint為浮點數
    ix = (2*i+1)/width;   //奇數列位置,如 p[odd][*] 奇數處理部份開始
    iy = (2*i+1)%width;  //奇數列位置,如 p[*][odd]
    tempint = p[ix][iy] + (int) (temp * sin(TWO_PI*u2) + mean);
    if (tempint > 255)
      p[ix][iy] = 255;
    else if (tempint <>
      p[ix][iy] = 0;
    else
      p[ix][iy] = (unsigned char) tempint; //轉成char型態
                          是因為tempint為浮點數
    u1 = 0.0; //將u1重新設定為0
  }
  u1=0.0;
  if( num & 1 ) // If num is odd //最後一點之處理
  {
    while (u1 == 0.0) u1 = unit_random();
    u2 = unit_random();
    temp = sqrt(-2.0*variance*log(u1));
    ix = (num-1)/width;
    iy = (num-1)%width;
    tempint = p[ix][iy] + (int) (temp * cos(TWO_PI*u2) + mean);
    if (tempint > 255)
      p[ix][iy] = 255;
    else if (tempint < 0)
      p[ix][iy] = 0;
    else
      p[ix][iy] = (unsigned char) tempint;
    u1 = 0.0;
  }
  cout << "done!" << endl;
}



NOTE:
ix = (2*i+1)/width;
iy = (2*i+1)%width;

ix = (num-1)/width;
iy = (num-1)%width; 有所不同之處需自行體會一番。

No comments: