5

I am building an application to do some image analysis tasks. I need to be able to do some image manipulations (i.e. rotate, zoom, change center point, etc.) in order to get a specific section of the image to do the analysis on. I am using wxPython for my gui so the image being displayed needs to be of type wxImage (to scale and then convert to wxBitmap). My image data, though, is a 2-D array of floats. In order to create a wxImage the data needs to be in RGBA format. So, right now, I am converting the image to RGBA and doing the rotations with scipy.interpolate.rotate()(, zoom by cropping the image, etc.) and save all the information for the section I want. I then perform the same operations, with the new-found parameters, on the original float array data once the section has been found.

So, the problem is, rotating the RGBA image is incredibly slow (since the images are around 2000x2000), even using next door neighbor (NDN) interpolation (mode=0). When I interpolate the float array (for the analysis), the speed isn't too bad (as long as I use NDN or linear).

My questions, then, are:

  1. Is there a better way of doing this without all of the data conversions?
  2. If not, then is there a faster way to rotate the RGBA data? (The quality is not a huge concern since I am only displaying the data and finding parameters; I use the untouched float array for analysis).

Any help would be greatly appreciated. Thanks.

SFBA26
  • 870
  • 3
  • 12
  • 24
  • Did you try [Pillow](http://pillow.readthedocs.org/en/latest/#) or PIL (Python Image Library) – furas Jun 20 '14 at 01:48
  • @furas Yes, I have tried using Pillow. The issue is with the conversions back and forth. They are too slow to do between every operation and display. – SFBA26 Jun 20 '14 at 21:30

1 Answers1

3

according to my experiment , OpenCV turned out to be the fastest to perform Image rotation. take a look at the link .

Edit: I should also include the answer here as well :

I am going to focus on three most used libraries for image editing in python namely , Pillow, OpenCV and Scipy.

In the following code you can learn how to import these libraries and how to rotate an image using them. I have defined a function for each library to use it for our experiments

import numpy as np
import PIL
import cv2
import matplotlib.pylab as plt
from PIL import Image
from scipy.ndimage import rotate
from scipy.ndimage import interpolation

def rotate_PIL (image, angel, interpolation):
    '''
    input :
    image           :  image                    : PIL image Object
    angel           :  rotation angel           : int
    interpolation   :  interpolation mode       : PIL.Image.interpolation_mode
    
                                                    Interpolation modes :
                                                    PIL.Image.NEAREST (use nearest neighbour), PIL.Image.BILINEAR (linear interpolation in a 2×2 environment), or PIL.Image.BICUBIC 
                                                    https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.rotate
    returns : 
    rotated image 
    
    '''

    return image.rotate(angel,interpolation)
    
    
def rotate_CV(image, angel , interpolation):

    '''
        input :
        image           :  image                    : ndarray
        angel           :  rotation angel           : int
        interpolation   :  interpolation mode       : cv2 Interpolation object
        
                                                        Interpolation modes :
                                                        interpolation cv2.INTER_CUBIC (slow) & cv2.INTER_LINEAR
                                                        https://theailearner.com/2018/11/15/image-interpolation-using-opencv-python/
                                                        
        returns : 
        rotated image   : ndarray
        
        '''



    #in OpenCV we need to form the tranformation matrix and apply affine calculations
    #
    h,w = image.shape[:2]
    cX,cY = (w//2,h//2)
    M = cv2.getRotationMatrix2D((cX,cY),angel,1)
    rotated = cv2.warpAffine(image,M , (w,h),flags=interpolation)
    return rotated

    

def rotate_scipy(image, angel , interpolation):
    '''
        input :
        image           :  image                    : ndarray
        angel           :  rotation angel           : int
        interpolation   :  interpolation mode       : int
        
                                                        Interpolation modes :
                                                        https://stackoverflow.com/questions/57777370/set-interpolation-method-in-scipy-ndimage-map-coordinates-to-nearest-and-bilinea
                                                        order=0 for nearest interpolation
                                                        order=1 for linear interpolation
        returns : 
        rotated image   : ndarray
        
        '''

    return  scipy.ndimage.interpolation.rotate(image,angel,reshape=False,order=interpolation)

To understand which library is more efficient in rotating and interpolating images, we design a simple experiment at first. We apply a 20 degree rotation using all three libraries on a 200 x 200 pixel 8bit image generated by our function rand_8bit().

def rand_8bit(n):
    im =np.random.rand(n,n)*255
    im = im.astype(np.uint8)
    im[n//2:n//2+n//2,n//2:n//4+n//2]= 0 # a self scaling rectangle 
    im[n//3:50+n//3,n//3:200+n//3]= 0 #  a constant rectangle 
    return im
  
#generate images of 200x200 pixels
im = rand_8bit(200)
#for PIL library we need to first convert the image array into a PIL image object 
image_for_PIL=Image.fromarray(im)
    

%timeit rotate_PIL(image_for_PIL,20,PIL.Image.BILINEAR)
%timeit rotate_CV(im,20,cv2.INTER_LINEAR)
%timeit rotate_scipy(im,20,1)

the result is : 987 µs ± 76 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 414 µs ± 79.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 4.46 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

This means that OpenCV is the most efficient and Scipy is the slowest of them when it comes to image rotation.