I have written the following matlab code for producing a noisy image corrupted by Cauchy noise but when I compute the psnr value of the noisy image using psnr function in matlab, it returns a negetive value while according to the paper that I have implemented its results, the psnr value for the cameraman test image of size 256 by 256 and 0.02 of Cauchy noise must be around 19. I appreciate it if someone could please help me to solve this problem.
refimg = im2double(imread('cameraman.png')); % original image
img_height = size(refimg,1);
img_width = size(refimg,2);
refimg = refimg(1:img_height,1:img_width);
rng(0);
r1 = random('Normal',0, 1,[img_height img_width]);
r2 = random('Normal',0, 1,[img_height img_width]);
n = 0.02; % the noise level
u0 = refimg n.*(r1./r2);
figure(1); imshow(u0);
PSNR_noisy = psnr(refimg,u0)
CodePudding user response:
The psnr
function outputs the signal-to-noise ratio in decibels (that is, logarithtmic units). This is stated in the documentation (but I think it should be indicated more clearly, perhaps in the description section). Also, a quick look at psnr
's code confirms that the outputs are given in decibels:
peaksnr = 10*log10(peakval.^2/err);
snr = 10*log10(mean(ref(:).^2)/err);
Therefore the result can be negative, meaning there is more noise power than signal power.
Note, however, that the concept of noise power cannot be applied to a Cauchy distribution. So I’m not sure it makes sense to use psnr
in this case.
CodePudding user response:
As Luis Mendo nicely stated, you cannot compute the power of noise taken from a Cauchy distribution. This is because the distribution doesn't have a mean or a variance. You can get infinitely large (or small) values from this distribution. Because the distribution is unbounded, it doesn't make sense as a noise model for an image. However, if we were to clamp the values of the image after applying noise, then we would be able to sensibly compute statistics.
This is OP's code, slightly simplified and amended to clamp the image values to the [0,1] range after adding the noise:
refimg = im2double(imread('cameraman.tif')); % original image
sz = size(refimg);
rng(0);
r1 = randn(sz); % (using randn because I don't have the statistics toolbox)
r2 = randn(sz);
n = 0.02; % the noise level
u0 = refimg n.*(r1./r2);
u0 = min(u0,1); % clamp large values to 1
u0 = max(u0,0); % clamp small values to 0
PSNR_noisy = psnr(u0,refimg)
The output now is 19.1419.
Note that the function psnr
expects the reference image to be the second input, even though the switch doesn't affect the output in this case.
Please read my opinion here on using PSNR: https://www.crisluengo.net/archives/490/