用C ++

时间:2016-11-23 17:39:38

标签: c++ opencv image-processing

我想用高斯噪声PDF(概率分布函数)将高斯噪声添加到输入图像中,我写了这段代码并检查了很多次但是输出不正确,我很困惑!

    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 :(得分: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;