In [2]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from skimage.filters import threshold_adaptive
IMAGE = 'penguin.jpg'
block_size = 40
image = np.array(Image.open(IMAGE).convert('L'))
image = threshold_adaptive(image, block_size, offset=10)
image_scaled = (image * 2) - 1
plt.gray()
plt.imshow(image_scaled)
plt.colorbar()
plt.show()
In [3]:
noise = 2*np.random.randn(image.shape[0]*image.shape[1]).reshape(image.shape)
#noise = np.random.randint(-1,2,image.shape)
#noise = np.zeros(image.shape)
#noise[300:350] = 1
#noisey_image = np.clip(image + noise, 0, 1)
#noisey_image = (noisey_image * 2) - 1
noisey_image = (image_scaled + noise)
plt.gray()
plt.imshow(noisey_image)
plt.colorbar()
plt.show()
plt.bar
plt.imshow(noise)
plt.colorbar()
plt.show()
plt.bar
Out[3]:
In [18]:
# Helper functions for the updates
def convolve(matrix, weights):
directions = [-1, 0, 1]
h, w = matrix.shape
conv = np.zeros((h, w))
for i in range(h):
for j in range(w):
for step_one in directions:
for step_two in directions:
x = step_one + i
y = step_two + j
if (x >= 0) and (y >= 0) and (x < h) and (y < w):
conv[i, j] += weights[step_one + 1, step_two + 1] * matrix[x, y]
return conv
def fast_convolve(matrix, weights):
h, w = matrix.shape
conv = np.zeros((h, w))
matrix = np.pad(matrix,((1, 1), (1, 1)),mode='constant')
for i in range(h):
for j in range(w):
conv[i, j] = (matrix[i:i + 3,j:j + 3] * weights).sum()
return conv
def prob(img, mu, sigma):
# this is an optimisation
res = np.exp(-((img - mu)**2 / (2 * sigma**2)))
res = res / (sigma * np.sqrt(2 * np.pi))
return res
def logprob(img, sigma):
log_plus = np.log(prob(img, 1, sigma))
log_minus = np.log(prob(img,-1, sigma))
return log_plus - log_minus
def update(mu, weights, L):
weighted_mu = fast_convolve(mu, weights)
new_mu = np.tanh(weighted_mu + 0.5 * L)
return new_mu
In [19]:
# Set model paramters and run updates
steps = np.arange(5)
mu = noisey_image
weights = np.ones((3, 3))
weights[1,1] = 0
decay = 1
sigma = 2
L = logprob(noisey_image, sigma)
for i in steps:
mu = (1 - decay)*mu + (decay * update(mu, weights, L))
plt.gray()
plt.imshow(mu)
plt.colorbar()
plt.show()
plt.gray()
plt.imshow(image_scaled)
plt.colorbar()
plt.show()
In [26]:
# Some tests on convolution speeds
image_size = 1000
%time convolve(np.random.rand(image_size,image_size),np.random.rand(3,3))
%time fast_convolve(np.random.rand(image_size,image_size),np.random.rand(3,3))
Out[26]:
In [ ]: