( a, resize = 1.5, angle = 20., interpolation = "linear", blocks = (16,16,1)  )
return output
Rotates the array. The new array has the new size and centers the
    picture in the middle.
    
    a             - array (2-dim)
    resize        - new_image w/old_image w
    angle         - degrees to rotate the image
    interpolation - "linear" or None
    blocks        - given to the kernel when run


    returns: a new array with dtype=uint8 containing the rotated image
Rotates the array. The new array has the new size and centers the
    picture in the middle.
    
    a             - array (2-dim)
    resize        - new_image w/old_image w
    angle         - degrees to rotate the image
    interpolation - "linear" or None
    blocks        - given to the kernel when run
Rotates the array . The new array has the new size and centers the picture in the middle . a - array ( 2 - dim ) resize - new_image w / old_image w angle - degrees to rotate the image interpolation - linear or None blocks - given to the kernel when run
def rotate_image( a, resize = 1.5, angle = 20., interpolation = "linear", blocks = (16,16,1)  ):
    """
    Rotates the array. The new array has the new size and centers the
    picture in the middle.
    
    a             - array (2-dim)
    resize        - new_image w/old_image w
    angle         - degrees to rotate the image
    interpolation - "linear" or None
    blocks        - given to the kernel when run


    returns: a new array with dtype=uint8 containing the rotated image
    """
    angle = angle/180. *pi
    
    # Convert this image to float. Unsigned int texture gave 
    # strange results for me. This conversion is slow though :(
    a = a.astype("float32")

    # Calculate the dimensions of the new image
    calc_x = lambda x_y: (x_y[0]*a.shape[1]/2.*cos(angle)-x_y[1]*a.shape[0]/2.*sin(angle))
    calc_y = lambda x_y1: (x_y1[0]*a.shape[1]/2.*sin(angle)+x_y1[1]*a.shape[0]/2.*cos(angle))

    xs = [ calc_x(p) for p in [ (-1.,-1.),(1.,-1.),(1.,1.),(-1.,1.) ] ]
    ys = [ calc_y(p) for p in [ (-1.,-1.),(1.,-1.),(1.,1.),(-1.,1.) ] ]

    new_image_dim = (
        int(numpy.ceil(max(ys)-min(ys))*resize),
        int(numpy.ceil(max(xs)-min(xs))*resize),
    )
    
    # Now generate the cuda texture
    cuda.matrix_to_texref(a, texref, order="C")
    
    # We could set the next if we wanted to address the image
    # in normalized coordinates ( 0 <= coordinate < 1.)
    # texref.set_flags(cuda.TRSF_NORMALIZED_COORDINATES)
    if interpolation == "linear":
        texref.set_filter_mode(cuda.filter_mode.LINEAR)

    # Calculate the gridsize. This is entirely given by the size of our image. 
    gridx = new_image_dim[0]/blocks[0] if \
            new_image_dim[0]%blocks[0]==1 else new_image_dim[0]/blocks[0] +1
    gridy = new_image_dim[1]/blocks[1] if \
            new_image_dim[1]%blocks[1]==0 else new_image_dim[1]/blocks[1] +1

    # Get the output image
    output = numpy.zeros(new_image_dim,dtype="uint8")
    
    # Call the kernel
    copy_texture_func(
        numpy.float32(resize), numpy.float32(angle),
        numpy.uint16(a.shape[1]), numpy.uint16(a.shape[0]),
        numpy.uint16(new_image_dim[1]), numpy.uint16(new_image_dim[0]),
            cuda.Out(output),texrefs=[texref],block=blocks,grid=(gridx,gridy))
    
    return output
def rotate_image ( a , resize = 1.5 , angle = 20. , interpolation = "linear" , blocks = ( 16 , 16 , 1 ) ) : angle = angle / 180. * pi # Convert this image to float. Unsigned int texture gave  # strange results for me. This conversion is slow though :( a = a . astype ( "float32" ) # Calculate the dimensions of the new image calc_x = lambda x_y : ( x_y [ 0 ] * a . shape [ 1 ] / 2. * cos ( angle ) - x_y [ 1 ] * a . shape [ 0 ] / 2. * sin ( angle ) ) calc_y = lambda x_y1 : ( x_y1 [ 0 ] * a . shape [ 1 ] / 2. * sin ( angle ) + x_y1 [ 1 ] * a . shape [ 0 ] / 2. * cos ( angle ) ) xs = [ calc_x ( p ) for p in [ ( - 1. , - 1. ) , ( 1. , - 1. ) , ( 1. , 1. ) , ( - 1. , 1. ) ] ] ys = [ calc_y ( p ) for p in [ ( - 1. , - 1. ) , ( 1. , - 1. ) , ( 1. , 1. ) , ( - 1. , 1. ) ] ] new_image_dim = ( int ( numpy . ceil ( max ( ys ) - min ( ys ) ) * resize ) , int ( numpy . ceil ( max ( xs ) - min ( xs ) ) * resize ) , ) # Now generate the cuda texture cuda . matrix_to_texref ( a , texref , order = "C" ) # We could set the next if we wanted to address the image # in normalized coordinates ( 0 <= coordinate < 1.) # texref.set_flags(cuda.TRSF_NORMALIZED_COORDINATES) if interpolation == "linear" : texref . set_filter_mode ( cuda . filter_mode . LINEAR ) # Calculate the gridsize. This is entirely given by the size of our image.  gridx = new_image_dim [ 0 ] / blocks [ 0 ] if new_image_dim [ 0 ] % blocks [ 0 ] == 1 else new_image_dim [ 0 ] / blocks [ 0 ] + 1 gridy = new_image_dim [ 1 ] / blocks [ 1 ] if new_image_dim [ 1 ] % blocks [ 1 ] == 0 else new_image_dim [ 1 ] / blocks [ 1 ] + 1 # Get the output image output = numpy . zeros ( new_image_dim , dtype = "uint8" ) # Call the kernel copy_texture_func ( numpy . float32 ( resize ) , numpy . float32 ( angle ) , numpy . uint16 ( a . shape [ 1 ] ) , numpy . uint16 ( a . shape [ 0 ] ) , numpy . uint16 ( new_image_dim [ 1 ] ) , numpy . uint16 ( new_image_dim [ 0 ] ) , cuda . Out ( output ) , texrefs = [ texref ] , block = blocks , grid = ( gridx , gridy ) ) return output