how to deform an image deforming the coordinates
<p>I would like to see how an image get deformed if I know how its coordinates are deformed.</p>

<p>for example: here I draw a circle</p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt
from math import *

plane_side = 500.0 #arcsec

y_l, x_l, = np.mgrid[-plane_side:plane_side:1000j, -plane_side:plane_side:1000j]

r = np.sqrt(y_l**2 + x_l**2)

indexes1 = np.where(r&lt;150.0)
indexes2 = np.where(r&gt;160.0)

image = r.copy()
image[:,:] = 1.0
image[indexes1] = 0.0
image[indexes2] = 0.0

imgplot = plt.imshow(image,cmap="rainbow")
plt.colorbar()
plt.show()
</code></pre>

<p>If I want to deform the coordinates like this:</p>

<pre><code>y_c = y_lense**3
x_c = x_lense**2
</code></pre>

<p>and plot the image distorted, what should I do?</p>

<p>In general (without using a dedicated library), you should apply an inverse transformation to the coordinates of the new image. Than, you interpolate values from the original image at the calculated coordinates.</p>

<p>For example, if you want to apply the following transformation:</p>

<pre><code>x_new = x**2
y_new = y**2
</code></pre>

<p>you would do something like that:</p>

<pre><code>import numpy as np
# some random image
image = np.random.rand(10,10)

# new interpolated image - actually not interpolated yet :p
# TODO: in some cases, this image should be bigger than the original image. You can calculate optimal size from the original image considering the transformation used.
image_new = np.zeros(image.shape)

# get the coordinates
x_new, y_new = np.meshgrid( range(0,image_new.shape[1]), range(0,image_new.shape[0]) )
x_new = np.reshape(x_new, x_new.size) 
y_new = np.reshape(y_new, y_new.size) 

# do the inverse transformation
x = np.sqrt(x_new)
y = np.sqrt(y_new)

# TODO: here you should check that all x, y coordinates fall inside the image borders

# do the interpolation. The simplest one is nearest neighbour interpolation. For better image quality, bilinear interpolation should be used.
image_new[y_new,x_new] = image[np.round(y).astype(np.int) , np.round(x).astype(np.int)]
</code></pre>

python python-2.7 numpy matplotlib