Ask Your Question
0

How to add noise to color image, so that the MSE becomes square of the standard deviation of the noise?

asked 2016-06-07 06:19:44 -0600

Hossain Md Shakhawat gravatar image

I have added noise to color image. But when I am calculating the MSE, it is very low compared to the added noise. For std=20, the MSE is below 200. But I think MSE should be close to square of standard deviation of the added random noise(if std=20 then MSE around 400).

edit retag flag offensive close merge delete

Comments

I suspect you are computing the MSE in the wrong way! Can you add your code?

Balaji R gravatar imageBalaji R ( 2016-06-07 07:42:14 -0600 )edit

//For gray level image

for(int y = 0; y < width; y++){ for(int x = 0; x < height;x++){

        difference = (original.at<double>(x,y) - ref.at<double>(x,y));
        sum = sum + difference*difference;
    }
}
mse = (float)sum /(width*height);
printf("MSE =%.3f\n",mse);
Hossain Md Shakhawat gravatar imageHossain Md Shakhawat ( 2016-06-07 09:06:42 -0600 )edit

1 answer

Sort by » oldest newest most voted
0

answered 2016-06-07 07:55:41 -0600

Here is a Sample Program to reproduce the same!

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>

using namespace cv;
using namespace std;

bool AddGaussianNoise(const Mat mSrc, Mat &mDst,double Mean=0.0, double StdDev=10.0)
{
    if(mSrc.empty())
    {
        cout<<"[Error]! Input Image Empty!";
        return 0;
    }
    Mat mSrc_16SC;
    Mat mGaussian_noise = Mat(mSrc.size(),CV_16SC3);
    randn(mGaussian_noise,Scalar::all(Mean), Scalar::all(StdDev));

    mSrc.convertTo(mSrc_16SC,CV_16SC3);
    addWeighted(mSrc_16SC, 1.0, mGaussian_noise, 1.0, 0.0, mSrc_16SC);
    mSrc_16SC.convertTo(mDst,mSrc.type());

    return true;
}

double GetPSNR(const Mat& I1, const Mat& I2,double &MSE) 
{ 
    Mat s1; 
    absdiff(I1, I2, s1);       // |I1 - I2| 
    s1.convertTo(s1, CV_32F);  // cannot make a square on 8 bits 
    s1 = s1.mul(s1);           // |I1 - I2|^2 
    Scalar s = sum(s1);         // sum elements per channel 
    double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels 

    if( sse <= 1e-10) // for small values return zero 
        return 0; 
    else 
    { 
        double  mse =sse /(double)(I1.channels() * I1.total()); 
        MSE= mse;        
        double psnr = 10.0*log10((255*255)/mse); 

        return psnr; 
    } 
} 


int main(int argc, const char* argv[])
{
    Mat mScene= imread("input.png",1);  
    imshow("Source Image",mScene);

    Mat mNoise(mScene.size(),mScene.type());
    double Mean=0.0,StdDev=20.0;

    AddGaussianNoise(mScene,mNoise,Mean,StdDev);

    imshow("mNoise",mNoise);

    double PSNR=0.0,MSE=0.0;

    PSNR= GetPSNR(mScene,mNoise,MSE);

    cout<< "PSNR : "<<PSNR<<" \n MSE :"<<MSE <<"\n";

    waitKey();
    return 0;
}
edit flag offensive delete link more

Comments

I am calculating MSE for M-pixel gray level images MSE=1/M ∑_(j=1)^M [ I_target (j)- I_reference (j) ] ^2

where I_target is the degraded image and I_reference is the original image

Hossain Md Shakhawat gravatar imageHossain Md Shakhawat ( 2016-06-07 08:53:16 -0600 )edit

I am getting the same value as yours while considering the three channels.

Hossain Md Shakhawat gravatar imageHossain Md Shakhawat ( 2016-06-07 09:12:46 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-06-07 06:19:44 -0600

Seen: 235 times

Last updated: Jun 07 '16