What does negative value of PSNR indicate?

I am computing the PSNR value between an image and its filtered version and getting a negative value.
I understand tht since there is log, if the number is less than 1, I will be getting a negative value.
But what does the negative value actually imply??

 Accepted Answer

Hi,
According to the definition of PSNR as mentioned here , it cannot be negative. You can check if the range in both images is same as in if both images are of datatype unit8 then range should be [0,255]. Also, if you are converting one image to be in range [0,1] and the other image is in range [0,255] then this behavior can occur. Finally, if you are using your own implementation for psnr then I would suggest using built-in function psnr for calculating the same.
The only reason I can think of is a big mismatch between the range of values in the image.
Hope this helps!

9 Comments

This is not correct. psnr is based on log10() and log10() can be negative if the quantity whose log is being taken is less than 1. In particular, when the noise is more than the signal, PSNR can be negative.
Hi,
But if you see the actual definition of the PSNR it is the ratio between the quantities such as Peak value in an image and the Mean squared error while comparing with a reference image. Since the mean squared value can never exceed the peak value in the target image if range of both the images is similar, that is why I suggested that negative PSNR is only possible when the two images have different range which have orders of magnitude gap.
More information about peakvalue is given here.
As for the second part about noise more than signal, it can always be assumed that the noise is the actual information present in the image (because it is not explicitiely mentioned that one signal is noise and other is the actual information).
Thanks Raunak and Walter!!
@Raunak - Both the images were converted to the same type - double
Hi,
For double class, the inbuilt function psnr takes the maximum value of 1 instead of 255 that you have taken while calculating the psnr manually. By default the double image ranges between 0 and 1, so converting a uint8 image into double image by typecasting will not rescale the value into 0 and 1. This is I guess the main issue as you explained using the manual implementation gets you the correct value. If both the images are in double, you can rescale them into [0,1] by dividing the values with 255. Passing these rescaled images into psnr will give correct results.
More information about peakvalue is given here.
Hope this clarifies!
Thanks Raunak !! I went through the link..
Since I have converted both the images to double, Is it right to use 255^2 in the numerator of PSNR formula
PSNR1 = 10 * log10( 255^2 / mse1);
Hi,
If the images are converted to double using typecasting and the values in image are in range [0,255], then its correct to use peak value 255.
But if you want to pass double class data to builtin function psnr, since the peakvalue will be chosen as 1 (by default), the image range also needs to be in [0,1] to give correct result.
Ok..Will check out..Thanks again..
@ Raunak, I think the error in the computation of PSNR is due to the difference in the range of the values as you had mentioned earlier.
In my code, I read an image that is uint8 and the max value it can take is 255. When I convert it to double, the range of the variable changes between 0 to 1.
Then I am computing wavelet coefficients, w1 using an inbuilt function. The wavelet coefficients are of type double and I expected the values to lie between 0 and 1. However, one of the subbands have a maximum value equal to 330. Why is this so?
I am then computing the PSNR between the orginal image and the image obtained after transformation by using the formula for PSNR rather than the inbuilt function, I am first computing the MSE as below, where I convert both the original and the filtered images to double as shown below
squaredErrorImage1 = (double(Input_img) - double(Filtered_Img)) .^ 2;
double(Input_img) - has values between 0 and 1
double(Filtered_Img) - has values beyond 255 (maximum value is around 330).
Shouldn't the double(Filtered_Img) also have a value between 0 and 1.
The error in the PSNR value is because of this variation. How can it be overcome?
How can we keep track of the range of value of the variable at each stage?

Sign in to comment.

More Answers (1)

1 Comment

Further to the same question, I used the formula of PSNR instead of the inbuilt function as below
PSNR1 = 10 * log10( 255^2 / mse1); where
mse1 = mean square error computed as
squaredErrorImage1 = (double(Input_img) - double(Filtered_Img)) .^ 2;
mse1 = sum(sum(squaredErrorImage1)) / (r1 * c1); where
r1,c1 = row and col size of the input image and boht the input and filtererd image are of type double
Hope I am right..
I am getting a positive value using this formula but a negative value using the inbuilt function of matlab 'psnr'
Can you please help me figure out why there is a difference between the two?

Sign in to comment.

Categories

Find more on Images in Help Center and File Exchange

Products

Release

R2019b

Asked:

on 10 Nov 2020

Commented:

on 23 Nov 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!