Import required modules


In [1]:
# manipulate arrays and have math
import numpy as np
# plot results
import matplotlib.pyplot as plt
# plot them inline in jupyter
%matplotlib inline
# make matplotlib load images
import matplotlib.image as mpimg

Load test images


In [2]:
sharp_image = mpimg.imread('picture.png')
soft_image = mpimg.imread('picture_gaussian_10.png')

Display the raw images


In [3]:
plt.imshow(sharp_image)
print 'sharp image'
plt.show()
plt.imshow(soft_image)
print 'soft image'
plt.show()


sharp image
soft image

Extract smaller region from images


In [4]:
sharp_test = sharp_image[1000:1400,2000:2400].copy()
soft_test = soft_image[1000:1400,2000:2400].copy()

Display said regions


In [5]:
plt.imshow(sharp_test)
print 'sharp image'
plt.show()
plt.imshow(soft_test)
print 'soft image'
plt.show()


sharp image
soft image

Again extract smaller region from image, now adding noise and small shift

(hoping to mimick some differences when taking pictures)


In [6]:
sharp_test_noise = sharp_image[1000:1400,2000:2400].copy()
soft_test_noise = soft_image[1005:1405,2012:2412].copy()

In [7]:
# add noise
def noise(data, noise_value):
    noisy_data = data + noise_value * np.random.random([400,400,3]) - noise_value/2
    # shift values to be within bounds
    tmp_data = noisy_data.copy()
    noisy_data[tmp_data < 0] = np.abs(tmp_data[tmp_data < 0])
    noisy_data[tmp_data > 1] = -tmp_data[tmp_data > 1] + 2
    
    return noisy_data

Display those images


In [8]:
sharp_test_noise = noise(sharp_test_noise, 0.2)
soft_test_noise = noise(soft_test_noise, 0.2)
plt.imshow(sharp_test_noise)
plt.show()
plt.imshow(soft_test_noise)
plt.show()


Check gradients of test images


In [9]:
# compute a gradients measure that should prefer an edgy result, thus a sharper one
def gradient_sharpness_metric(data):
    # limit gradients to one colour channel (greyscale, remember)
    gy, gx = np.gradient(data[:,:,0], 2)
    # get norm of the gradients, thus looking at both directions simultaneously
    gnorm = np.sqrt(gx**2 + gy**2)
    # and produce a single number
    metric = np.mean(gnorm)
    
    return metric

Inspect clean images first:


In [10]:
print '    metric (sharp) :', gradient_sharpness_metric(sharp_test)
print '    metric  (soft) :', gradient_sharpness_metric(soft_test)


    metric (sharp) : 0.023001
    metric  (soft) : 0.00670288

Now inspect 'realistic' images:


In [11]:
print '    metric (sharp) :', gradient_sharpness_metric(sharp_test_noise)
print '    metric  (soft) :', gradient_sharpness_metric(soft_test_noise)


    metric (sharp) : 0.0353338227318
    metric  (soft) : 0.0212094832647

Check robustness of metric, looking at the ratio of things

A higher ratio should hint towards a clearer identification (or so the idea)


In [12]:
print '    ratio/cleanliness of results:', \
gradient_sharpness_metric(sharp_test_noise)/gradient_sharpness_metric(soft_test_noise)


    ratio/cleanliness of results: 1.66594453485

In [ ]: