import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
The past lecture covered three related topics: noise, blurs, and edge detection. Let's discuss them and give some examples. Again, we'll work with our favorite cat.
img=mpimg.imread('kitty-cat.jpg')
plt.imshow(img)
plt.show()
It'll be more convenient here if our image is stored in the floating point format, so let's change it to that.
img = img/255
In lecture we learned how to add different types of noises to grayscale images. There's nothing special about grey scale images. Let's practice these noises by applying them to color images:
Salt and Pepper Noise:
.
.
.
.
.
.
.
.
def salt_pepper(img, p1=0.1, p2=0.1):
img = img.copy()
r = np.random.rand(img.shape[0], img.shape[1])
img[r < p1, :] = 0
img[r > 1-p2, :] = 1
return img
plt.imshow(salt_pepper(img))
plt.show()
Gaussian Noise:
.
.
.
.
.
.
.
.
def gauss_noise(img,p=0.5):
img=img.copy()
noise=np.random.randn(img.shape[0],img.shape[1],1)*p*np.var(img)**(0.5)
img = img + noise
img = np.maximum(img, np.zeros(img.shape))
img = np.minimum(img, np.ones(img.shape))
return img
plt.imshow(gauss_noise(img))
plt.show()
I was mistaken on how much you covered in lecture, so this isn't what we're going to be doing for this exercise. I'll leave it here because it will make sense later, though!
If you remember from lecture, to blur an image we take some small matrix (called a filter) and do some special operation (called convolution) with the image matrix. The convolution operation is just that we take our image matrix and multiply each block of the matrix element-wise by our filter and then take the sum.
Let's write the function to apply a filter (the convolution function) ourselves. Normally for something this fundamental, you would want to just use some convolution function from a module. There's two reasons why we aren't going to do that here:
What we will actually be doing is implementing a uniform blur function.
.
.
.
.
.
.
.
.
def apply_blur(mat, blur_size):
new_img = np.zeros([img.shape[0]-2*blur_size,img.shape[1]-2*blur_size,3])
for i in range(new_img.shape[0]):
for j in range(new_img.shape[1]):
grid = img[i:i+2*blur_size+1,j:j+2*blur_size+1,:]
new_img[i,j,:] = np.mean(np.mean(grid, axis=1), axis=0)
return new_img
plt.imshow(apply_blur(img, 10))
plt.show()
Question: When we define the convolution we need to use the elements of an array around a given point. But, if the point we are trying to take is near the boundary, there might not be enough elements near it. What to do in these cases is a common problem using these filters. We chose to just ignore the boundary and make the image smaller, but what else might you want to do?
.
.
.
.
.
.
.
.
Answer: All of these are things that you might want to do, but you might be able to think of others:
Question: It was mentioned in lecture that blurring is a way to reduce the amount of noise in the image. This is true, but what do you expect will happen if we add noise to an image and then blur it a little?
First we'll discuss this with the Gaussian noise and then we'll discuss this with the Salt and Pepper noise, to see if there's a difference.
.
.
.
.
.
.
.
.
noisy_img = gauss_noise(img, 5)
plt.imshow(apply_blur(noisy_img,3))
plt.show()
noisy_img = salt_pepper(img, 0.2, 0.2)
plt.imshow(apply_blur(noisy_img,3))
plt.show()