Blurring and Noise

In [1]:
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.

In [2]:
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.

In [3]:
img = img/255

Noise

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:

.

.

.

.

.

.

.

.

In [4]:
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:

.

.

.

.

.

.

.

.

In [5]:
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()

Blurring

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:

  1. Writing something yourself once is good practice and will help you understand how it works.
  2. NumPy doesn't actually have a function for this! It does have a convolution function, but it doesn't do what we want (it works on vectors, not matrices). The module SciPy has this function, but we haven't learned SciPy yet.

What we will actually be doing is implementing a uniform blur function.

.

.

.

.

.

.

.

.

In [6]:
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:

  • Ignore the boundary of the image and make the image smaller (what we did).
  • Ignore the points in the filter that don't correspond to points in the image.
  • Do the above and rescale the filter so that it still adds to 1
  • Pretend that the pixels outside the image are some set value (such as 0 or 1)
  • Pretend the image wraps around and use points on the other side.

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.

.

.

.

.

.

.

.

.

In [7]:
noisy_img = gauss_noise(img, 5)
plt.imshow(apply_blur(noisy_img,3))
plt.show()
In [8]:
noisy_img = salt_pepper(img, 0.2, 0.2)
plt.imshow(apply_blur(noisy_img,3))
plt.show()