PIL interpolation access

Caleb Hattingh caleb1 at telkomsa.net
Tue Nov 30 21:57:19 EST 2004


Hi

I can't help you directly, but I am also finding im.putpixel to be  
extremely slow - as the docs recommend, can you try using the  
pixel-placing method of Draw?  This is what I am going to try for my  
application (resampling algorithms).

Thx
Caleb

On 30 Nov 2004 11:18:40 -0800, irond_will <irond_will at yahoo.com> wrote:

> Does anyone know how I might directly access PIL's bicubic
> interpolator?  I have an arbitrary array of points for which I need to
> find interpolated color values.  Unfortunately, I have no clue how to
> acceess the bicubic filter in the PIL module, and my NumArray solution
> is very slow and clunky.
>
> I've hacked together a very very very slow solution that involves the
> following steps:
>
> 1) import Image
> 2) translate Image to NumArray object (fairly slow)
> 3) find interpolated values for pixel array (breathtakingly slow)
> 4) translate interpolated color values (NumArray) into Image structure
> (way too slow)
>
> If anyone knows any way to perform items 2,3 or 4 with any facility,
> please please please respond.  The code I have now is extremely
> clunky, largely due to my lack of facility with Python, Numarray and
> PIL.  Some is below:
>
> I know I could speed up the algorithm by being smarter with vectors.
> I don't really want to mess with this, though, if there's already a
> better extant solution.
>
> Thanks,
>
> -Wm.
>
> def bicub_interp(r,X):
>     from numarray import *
>     import Image
>     #r is the 2d array point in X space; this should be generalized to
> take in an array of size [2,xspan,yspan]
>     #X is the graphic array.  Its specifications are:
>     # dim 1 = x axis
>     # dim 2 = y axis
>     # dim 3 = [RGB] axis
>     # Each pixel of the X array is assumed to exist at the discrete
> intersection of integer count.
>     # For instance, the bottom left point is X[0,0,:]
>
>     c_r_x = r.shape[1]
>     c_r_y = r.shape[2]
>     c_X_x = X.shape[0]
>     c_X_y = X.shape[1]
>     Y = zeros((c_r_x, c_r_y, 3))
>     for n_x in range(c_r_x):
>         for n_y in range(c_r_y):
>            r_x = r[0,n_x,n_y]
>             r_y = r[1,n_x,n_y]
>             r_i = int(r_x)
>             r_j = int(r_y)
>             r_dx = r_x - r_i
>             r_dy = r_y - r_y
>            if ( (0 < r_i < (c_X_x-2)) & (0 < r_j < (c_X_y-2)) ):
>                 for n_m in range(-1,3):
>                     for n_n in range(-1,3):
>                         Y[n_x,n_y,:] += (X[r_i,r_j,:]
>                                          * Rfunc(n_m - r_dx)
>                                          * Rfunc(r_dy - n_n))
>     return Y
>
> def Rfunc(X):
>     ##For use in bicub_interp()
>     R = (1.0/6.0)*(1.0 * ((ramp(X+2.0))**3) -
>                    4.0 * ((ramp(X+1.0))**3) +
>                    6.0 * ((ramp(X    ))**3) -
>                    4.0 * ((ramp(X-1.0))**3))
>     return R
>
> def ramp(X):
>     if (X<0): X = 0.0
>     return X
>
> def image_to_array(im):
>
>     #This function returns an array of RGB pixel values
>     #The dimensions correspond as follows:
>     #Dim 1 = column or x value
>     #Dim 2 = row or y value
>     #Dim 3 = color value or [R,G,B] for [0, 1, 2]
>
>     #X.transpose operations can change the order of the axes if
> desired.
>    X =  
> vect_math.array_flip(transpose(reshape(array(im.getdata()),(im.size[1],im.size[0],3)),(1,0,2)),1)
>    return X
>
> def array_to_image(X):
>     #SLOW method of mapping array of spects defined in image_to_array
> into
>     #an image structure
>
>     #There is probably a faster way using im.putdata(), but I can't
> figure out how to get the array structure
>     #oriented in such a fashion as to perform a direct put.
>
>     im = Image.new('RGB',(X.shape[0], X.shape[1]))
>     X=vect_math.array_flip(X,1)
>     for x in range(0,X.shape[0]):
>         for y in range(0,X.shape[1]):
>             im.putpixel((x,y),tuple(X[x,y,:]))
>     return im




More information about the Python-list mailing list