Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does convolution doesn't work with non-normalized images?

I’m trying to sharpen an image using Unsharp masking, but using this technique on a normal greyscale image with pixel values in [0,255] returns a garbled image, however, when I first normalize my image to be in the range of [0,1] I get the expected result.

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter
from google.colab.patches import cv2_imshow
import skimage.io
import skimage.filters
img1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)
# img1=img1/255.0
def first_method(img, alpha, sigma):
  blurred = gaussian_filter(img, sigma=sigma)
  return np.clip(img + alpha * (img - blurred),0,255)

plt.figure(figsize=(8, 10))

best_first = first_method(img1, alpha=0.75, sigma = 1.5)

f, axarr = plt.subplots(1,2,figsize=(20,20)) 

axarr[0].imshow(img1)
axarr[0].set_title('Original')
axarr[1].imshow(best_first)
axarr[1].set_title('Sharpened using the first method')

With normalization

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I don’t understand the effect of normalization by dividing a picture by a constant. A constant factor shouldn’t change anything in the frequency domain. The Fourier transform of the said signal multiplied by a constant would still carry that constant.

>Solution :

The problem occurs in this statement:

return np.clip(img + alpha * (img - blurred), 0, 255)

img - blurred, if both arrays are uint8, will result in underflow, negative values will wrap to positive values. You need to do this operation with a signed output, such as np.subtract(img, blurred, dtype=np.sint16).

You can also rearrange that statement to avoid negative values:

return np.clip((1 + alpha) * img - alpha * blurred, 0, 255)

However, (1 + alpha) * img will produce values that do not fit in a uint8. I think that NumPy automatically promotes this result, depending on the type of 1 + alpha. If so, this should work. But then you also need to cast the result back to uint8 for proper display:

return np.clip((1 + alpha) * img - alpha * blurred, 0, 255).astype(np.uint8)

I think it’s always easiest to just use a floating-point representation for images, which you get by normalizing the image to [0, 1].

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading