Image warping in Python or PIL

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Image warping in Python or PIL

Son Hua-2
Hi,

Can anybody show me some hints on how to implement an image warping
function efficiently in Python or PIL? Suppose we have a function f(x,
y) -> (x', y') that warps a pixel location (x, y) to (x', y'). Because
(x', y') may end up to be non-integer, and many (x, y) can map to the
same (x', y'), reverse mapping is used. That is at every destination
pixel (x', y'), we go and find the original pixel location (x, y) by
taking (x, y) = f_1(x', y'), where f_1 is the inverse function of f.

Suppose the inverse function f_1 is given. So, for each pixel in the
destination image, we can map to a non-integer pixel in the source
image. Therefore, we must bilinear interpolate at the source location
for the color.

I know that doing this pixel per pixel in Python is very slow. For example:

for i in xrange(height):
     for j in xrange(width):
         (x, y) = f_1(j, i)
         # 1. Check if (x, y) is inside the source image. If out of
boundary, skip.
         # 2. Bilinear sampling at (x, y) at the source image to obtain
color C
         # 3. Paste the color C into (i, j) location in the destination
image.
         # next...

I'm doing this warping as the final stage of an image mosaicking
program. The size of the image is quite big, about 8000x2000.

So, any ideas about how to make it fast, except implementing the whole
thing in C? As I also used the dictionary data structure available in
Python, so integrating C here may be painful.

Thank you in advance.

Best regards,
SH.


_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig
Reply | Threaded
Open this post in threaded view
|

Re: Image warping in Python or PIL

Fredrik Lundh
On Sat, May 8, 2010 at 5:58 AM, Son Hua <[hidden email]> wrote:

> Hi,
>
> Can anybody show me some hints on how to implement an image warping function
> efficiently in Python or PIL? Suppose we have a function f(x, y) -> (x', y')
> that warps a pixel location (x, y) to (x', y'). Because (x', y') may end up
> to be non-integer, and many (x, y) can map to the same (x', y'), reverse
> mapping is used. That is at every destination pixel (x', y'), we go and find
> the original pixel location (x, y) by taking (x, y) = f_1(x', y'), where f_1
> is the inverse function of f.
>
> Suppose the inverse function f_1 is given. So, for each pixel in the
> destination image, we can map to a non-integer pixel in the source image.
> Therefore, we must bilinear interpolate at the source location for the
> color.

The transform(MESH) operation might be what you need.

    http://effbot.org/tag/PIL.Image.Image.transform

Instead of mapping between individual pixels, cover the output image
with a grid, and calculate the source pixels for the corners of each
grid rectangle (forming a quadrilateral area).  Pass in the resulting
list of (grid rectangle, quadrilateral) pairs to transform(MESH), and
it'll take care of the rest.

(you can use a generator to produce mesh pairs on the fly)

The result is (usually) an approximation, with the maximum error
controlled by the grid resolution.

</F>
_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig
Reply | Threaded
Open this post in threaded view
|

Re: Image warping in Python or PIL

Oliver Tonnhofer-4

On 08.05.2010, at 13:49, Fredrik Lundh wrote:
> The transform(MESH) operation might be what you need.
>
>    http://effbot.org/tag/PIL.Image.Image.transform
>
> Instead of mapping between individual pixels, cover the output image
> with a grid, and calculate the source pixels for the corners of each
> grid rectangle (forming a quadrilateral area).  Pass in the resulting
> list of (grid rectangle, quadrilateral) pairs to transform(MESH), and
> it'll take care of the rest.

That's what I used to transform maps/aerial images from one coordinate system to another.
http://bitbucket.org/olt/mapproxy/src/142/mapproxy/core/image.py#cl-553 

> The result is (usually) an approximation, with the maximum error
> controlled by the grid resolution.

I did tests with 1500x1500px and there where no improvements beyond 8x8. The performance is really great. Even faster than GDAL which is a C library for exactly this kind of image processing.

Regards,
Oliver
_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig