2

I am trying to add Gaussian noise to my image using opencv-python. I have created the noise function but adding the noise function to the image is producing unexpected results.

I have created a noise function using normal Gaussian distribution from the numpy.random. Then after resizing the noise function I added it to my image.I tried printing the array. There sum is in the interval [0, 255] but then also parts of the image are washed out. I also tried printing the data types of the array. The initial was uint8 while later was float64 (I don't think that will make any difference).

import numpy as np
import cv2

fast = cv2.imread('Fast8.jpg', 0)

row, col = fast.shape
noise = np.random.normal(0, 1, (row, col))
fast = fast + noise
cv2.namedWindow('Noisy', cv2.WINDOW_NORMAL)
cv2.imshow('Noisy', fast)
cv2.waitKey(0)
cv2.destroyAllWindows()

In the result of the above code I am getting a washed out image with only some areas slightly visible.

5
  • Your code doesn't use the noise variable at all. Commented May 22, 2019 at 13:20
  • Oh Yes, I actually missed that line of code while writing my question. Thank you for pointing out that. I have rectified it. Can you figure out the problem now? Commented May 22, 2019 at 13:35
  • What if you change the 1 to 0.1? Commented May 22, 2019 at 13:37
  • fast is a floating point array. cv2.imshow expects floating point arrays to have values in the range [0, 1]. Try cv2.imshow('Noisy', fast/fast.max()). Commented May 22, 2019 at 13:52
  • Also note that np.random.normal(0, 1, (row, col)) will include negative values, which means fast + noise could have negative values. Is that what you want? Commented May 22, 2019 at 13:54

1 Answer 1

1

You are loading the image as uint8, but when summing float you get a float out. In order to see the result you need to cast it as int again.

Try this

cv2.imshow('Noisy', fast.astype(np.uint8))

Of course you will get a change in value only when the noise is big enough to make the pixel value jump from one integer to the next.

As an alternative you could work in the range [0,1] or [-1, 1] using scikit-image, which often uses these other conventions.

[Extra clarification] cv2.imshow works as explained in this stack overflow thread -> LINK So, you should decide if using float images in the range [0, 1] or uint8 images in the range [0, 255] or uint16/uint32 images with a bigger integer range. Since stochastic functions often generate on a small float range around 0, I suggest you to convert your image by dividing it by 255.0 to get it in the range [0, 1] float and work from there.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, it solved the problem. But can't I see images using just the numpy array of datatype float? Please clarify.
imshow works as explained in this thread -> stackoverflow.com/questions/48331211/…. So you should decide if using float images in the range [0, 1] or uint8 images in the range [0, 255] or uint16/uint32 images with a bigger integer range. Since stochastic functions generate on the float range [0, 1] I suggest you to convert your image by dividing it by 255.0 to get it in the range [0, 1] float and work from there

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.