I have 2 images, one original and other is reconstructed from the original via some processing. I want to find the PSNR for the reconstructed image The original has a size of (180, 180)
but the reconstructed image has size of (71,81)
. I am using cv2.reshape() to reshape the reconstructed image.
shape = 180
reconstructed = cv2.resize(reconstructed, (shape,shape))
reconstructed = cv2.normalize(reconstructed, None, alpha=0, beta = 255, norm_type= cv2.NORM_MINMAX, dtype=cv2.CV_32F)
original = cv2.normalize(original, None, alpha=0, beta = 255, norm_type= cv2.NORM_MINMAX, dtype=cv2.CV_32F)
MSE = np.mean((original - reconstructed)**2)
PSNR = 10*np.log10(255**2/MSE)
print(PSNR)
Since the sizes do not match and I have to calculate PSNR, I'm afraid that there might be some alignment issues and thus it may give wrong PSNR. What can be done to do calculate the PSNR accurately?
Scaffolding
First, it would be great if you could provide the data next time. Or at least some means to generate something that you feel is close enough to your data, so that the answers are actually useful to you.
Because we have been missing that, I build some little scaffolding to generate an original, and a reconstructed image where one can set the noise level.
Resize instead of reshape
That being out of the way. You want to resize. Since the sizes are different and reshape requires that the total number of elements in the array remains the same. If you reshape an array without keeping the total number of elements constant, it would result in a distorted representation or an error (probably why you get an error when reshaping). Resizing using cv2.resize
is more suitable for this scenario as it interpolates the pixel values to fit the new dimensions, ensuring that the resized image is a meaningful representation of the original image in a different size.
Dealing with Alignment issues
Now that you actually get a PSNR value, you can start thinking about how you want that interpolation of your reconstructed image to happen during resize. This depends on your data and the resize method gives you 5 options to choose from - read the docs. If you don't know which to choose, run an experiment to find out.
My code for anyone who wants to play or build on top of it for another answer.
import numpy as np
import cv2
def generate_dummy_image(size):
return np.random.randint(0, 1, size, dtype=np.uint8)
def add_noise(image, noise_level):
noise = np.random.normal(0, noise_level, image.shape).astype(np.uint8)
noisy_image = cv2.add(image, noise)
return noisy_image
# Generate original image (180, 180)
original_image_size = (180, 180)
original = generate_dummy_image(original_image_size)
# Generate reconstructed image (71, 81) with added noise
reconstructed_image_size = (71, 81)
reconstructed = generate_dummy_image(reconstructed_image_size)
noise_level = 20 # You can adjust the noise level as needed
reconstructed = add_noise(reconstructed, noise_level)
resized_reconstructed_image = cv2.resize(reconstructed, (original.shape[1], original.shape[0]))
# Calculate PSNR
psnr = cv2.PSNR(original, resized_reconstructed_image)
print(f"PSNR: {psnr} dB")
# Display images (optional)
# cv2.imshow('Original Image', original)
# cv2.imshow('Reconstructed Image with Noise', reconstructed)
# cv2.waitKey(0)
# cv2.destroyAllWindows()