2016-11-23 409 views
-2

我想给高斯噪声的输入图像添加高斯噪声PDF(概率分布函数),我写这个代码并检查很多次,但输出不正确,我很困惑!用C++添加高斯噪声

int main() { 
    Mat Frame; 
    string address; 
    printf("Please Drag and Drop Your Image"); 
    cin >> address; 
    Frame = imread(address, CV_LOAD_IMAGE_GRAYSCALE); 
    int arrayOfIntensity[256] = { 0 }, intensity; 

    //NEW COUNT INTENSITY OF EVERY PIXEL 
    for (int i = 0; i < Frame.rows; i++) 
     for (int j = 0; j < Frame.cols; j++) 
      arrayOfIntensity[Frame.at<uchar>(i, j)]++; 

    //SUM OF INTENSITY 
    int sumOfintensity = 0; 
    for (int i = 0; i < Frame.rows; i++) 
     for (int j = 0; j < Frame.cols; j++) 
      sumOfintensity += Frame.at<uchar>(i, j); 
    //AVG OF INTENSITY 
    double avgOfintensity = sumOfintensity, varOfintensity = 0; 
    avgOfintensity /= Frame.rows*Frame.cols; 
    //VARIANCE OF INTENSITY 
    for (int i = 0; i < Frame.rows; i++) 
     for (int j = 0; j < Frame.cols; j++) 
      varOfintensity += pow(Frame.at<uchar>(i, j) - avgOfintensity, 2); 
    varOfintensity/= Frame.rows*Frame.cols; 
    //PROBABILITY 
    float probability[256] = { 0 }, intermediate[256] = { 0 }, factor, sumProb[256] = { 0 }, newSumProb[256] = { 0 }; 
    factor = (sqrt(6.28)*avgOfintensity); 
    cout << "factor :" << factor << endl; 
    factor = 1/factor; 
    cout << "new factor :" << factor << endl; 
    for (int i = 0; i < 256; i++) { 
     intermediate[i] =-1*(pow(i - avgOfintensity, 2))/(2 * pow(varOfintensity, 2)); 
     probability[i] = factor*(pow(2.718281, intermediate[i])); 
     //SUM OF PROBABILTY 
     if (i == 0) 
      sumProb[i] = probability[i]; 
     else 
      sumProb[i] = probability[i] + sumProb[i - 1]; 
    } 
    //INTO 0-1 RANGE 
    for (int i = 0; i < 256; i++) 
     newSumProb[i] = sumProb[i]/ sumProb[255]; 

    float finalProb[256] = { 0 }; 
    for (int i = 0; i < 256; i++) { 
     double random = (rand() % 10)/1000000.0 +(rand() % 10)/100000.0 +(rand() % 10)/10000.0 +(rand() % 10)/1000.0 +(rand() % 10)/100.0+ (rand() % 10)/10.0; 
     for (int j = 0; j < 256; j++) { 
      if (random<newSumProb[j]) { 
       finalProb[i] = newSumProb[j]; 
       break; 
      } 
     } 
    } 
    int max = 0; 
    for (int i = 0; i < 256; i++) 
     if (finalProb[max]<finalProb[i]) 
      max = i; 

    for (int i = 0; i < 256; i++) 
     finalProb[i] =(finalProb[i] * 256.0)/ finalProb[max]; 

    for (int i = 0; i < Frame.rows; i++) 
     for (int j = 0; j < Frame.cols; j++) 
      Frame.at<uchar>(i, j) = saturate_cast<uchar>(finalProb[Frame.at<uchar>(i, j)]); 

    imshow("Result", Frame); 
    waitKey(); 
} 

正确的输出: tihs image is correct output with matlab 我的不正确的输出: this image is incorrect output with my code

+1

你尝试使用调试器,来看看你的代码与你的期望偏差? –

+0

是的,我检查每一步的每一个输出!我想我的问题的原因是错误的算法。 –

+0

你是否在正确的范围内添加了噪音?即是图像“0-1”还是“0-255”,是相同比例的高斯噪声? –

回答

1

据我了解,您的代码不高斯噪声的图像添加。
高斯噪声由2个值定义:平均值和标准差。

添加高斯噪声的图像,装置生成新的画面即帧,其中像素强度的分布遵循正态分布的大小,然后加入这对要进行实际的图像嘈杂。

我还没有试图完全理解你的代码,但你在做什么似乎是像素相关的,并且比必要的方式更复杂。

要生成一个像素遵循正态分布的框架,可以使用中心极限定理,该定理指出在相同分布之后求和n个独立变量趋于正态分布。

因此,您可以设置帧的每个像素是:

/* Generate a pixel with a random intensity that follows the normal distribution */ 
int n = 30; 
int sum = 0; 
for(int k = 0; k < n; ++k) 
    sum += rand() % 255; 
pixel_i_j = sum/n; 

/* 
* pixel_i_j at this point follows a normal distribution with 
* parameters : 
* - mean = 256/2 = 128 
* - std = std of uniform law between 0 - 256/sqrt(n) 
* 
* So adapt it to the normal law defined by my parameters */ 
pixel_i_j = ((pixel_i_j - mean)/std) * my_std + my_mean; 
+0

感谢您的帮助,但是在我编辑我的代码是不正常,但真正改变输出(!)看到这个:http://s8.picofile.com/file/8275854300/a.png –

+0

你是否适应它遵循你的法律?适应之前的像素分布是,我相信但维基百科可能会给你一个更好的答案:256/2 = 128和标准是128/sqrt(n)。你需要做到这一点,所以平均值在10左右,而且标准偏低,所以你保持了一个很好的信噪比。 –

+0

std在我以前的评论中是错误的 –