Created
October 4, 2012 15:51
-
-
Save pierre-haessig/3834536 to your computer and use it in GitHub Desktop.
Shake an image to get kind of XKCD-style lines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: UTF-8 -*- | |
""" Shake an image | |
in relation to the discussion about xkcd-style graphs on matplotlib-users ML | |
ref: http://mathematica.stackexchange.com/questions/11350/xkcd-style-graphs | |
Pierre Haessig — October 2012 | |
""" | |
from os.path import splitext | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from scipy.misc import imread, imsave | |
from scipy.ndimage.interpolation import map_coordinates | |
from scipy.ndimage.filters import gaussian_filter | |
### Read the input image | |
img_name = 'grid_image.png' | |
print('Reading "%s"...' % img_name) | |
img = imread(img_name) | |
N,P = img.shape[0:2] | |
print('image shape: %dx%d px' % (P,N)) | |
# 1) Create the indexing grid coordinates: | |
x,y = np.mgrid[0:N,0:P] | |
# 1a) Create a displacement noise: | |
x_noise = np.random.randn(N,P) | |
y_noise = np.random.randn(N,P) | |
# 1b) Smooth the noise | |
radius = 3 # in [px] | |
x_noise = gaussian_filter(x_noise, radius) | |
y_noise = gaussian_filter(y_noise, radius) | |
# 1c) normalize the standard deviation | |
noise_std = (x_noise.std() + y_noise.std())/2 | |
x_noise /= noise_std | |
y_noise /= noise_std | |
# 1d) Add the noise to create a shaken grid | |
scale = .5 # in [px] | |
x = x + x_noise * scale | |
y = y + y_noise * scale | |
# 2) Resample the image on the new shaken grid, channel per channel | |
coords = np.array([x,y]) | |
imgR = map_coordinates(img[:,:,0], coords, cval=255) | |
imgG = map_coordinates(img[:,:,1], coords, cval=255) | |
imgB = map_coordinates(img[:,:,2], coords, cval=255) | |
# note: is there a way to process all channels at once? | |
# 3) Reconstruct the image: | |
img2 = np.array([imgR, imgG, imgB]) | |
img2 = np.rollaxis(img2, 0, 3) | |
## Plot before and after images | |
#fig, (ax1, ax2) = plt.subplots(2,1) | |
#ax1.imshow(img, interpolation='nearest') | |
#ax2.imshow(img2, interpolation='nearest') | |
#plt.show() | |
### Save the output image ### | |
out_name = splitext(img_name)[0] + '-shaken' + splitext(img_name)[1] | |
print('saving the shaken image in "%s"' % out_name) | |
imsave(out_name, img2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment