2016-11-23 144 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在我以前的評論中是錯誤的 –