1

我需要知道在 Python 中旋转图像的最快方法是什么。

在 Stack Overflow 中,没有根据我的知识提出或回答这样的问题,所以我决定进行一个实验并找出答案。这就是为什么我想与您分享结果:

#we will compare which method is faster for rotating a 2D image 
#there are four major libraries for image handling and manipulation 
#PIL 
#OpenCV
#SciPy
#skimage 

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
import scipy
from skimage.transform import rotate




#get data :
PIL_image = Image.open('cat.jpg')
#image = cv2.imread('bambi.jpg') #read gray scale
array_image = np.array(PIL_image)

为每个模块定义一个函数:

def rotate_PIL (image, angel, interpolation):
    #PIL.Image.NEAREST (use nearest neighbour), PIL.Image.BILINEAR (linear interpolation in a 2×2 environment), or PIL.Image.BICUBIC 


    return image.rotate(angel,interpolation)
    
    
def rotate_CV(image, angel , interpolation):
    #in OpenCV we need to form the tranformation matrix and apply affine calculations
    #interpolation cv2.INTER_CUBIC (slow) & cv2.INTER_LINEAR
    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):
    return  scipy.ndimage.interpolation.rotate(image,angel,reshape=False,order=interpolation)

使用 timeit 找出最快的,PIL,Open CV 或 Scipy:

%timeit rotate_PIL(PIL_image,20,PIL.Image.NEAREST)
%timeit rotate_CV(array_image,20,cv2.INTER_LINEAR)
%timeit rotate_scipy(array_image,20,0)

结果是:

975 µs ± 203 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.5 ms ± 634 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
36.4 ms ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

不过有一个转折点——这是一个 jpeg 文件,而 PIL 只是粉碎了其他两个库。但是我主要使用 TIFF 格式的大型原始图像,所以我还决定测试 TIFF 文件:

#test for TIFF image 
#get data :
PIL_image = Image.open('TiffImage.tif')
#image = cv2.imread('bambi.jpg') #read gray scale
array_image = np.array(PIL_image)

%timeit rotate_PIL(PIL_image,20,PIL.Image.NEAREST)
%timeit rotate_CV(array_image,20,cv2.INTER_LINEAR)
%timeit rotate_scipy(array_image,20,0)

65.1 ms ± 9.35 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
38.6 ms ± 6.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
344 ms ± 43.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

这意味着 OpenCV 在 TIFF 文件格式方面的表现要好于我们在 JPEG 文件方面的明显赢家。

如果有人碰巧知道原因,或者如果有人有类似的实验,请在这里分享。我认为这将是一个很好的公开文件进行比较。

另外,如果您认为我的实验无效,或者出于任何原因可以改进,请告诉我。

4

1 回答 1

0

首先,感谢您的所有评论。它帮助我以更好的方式思考问题,并考虑我在实验中犯的错误。

我做了一个更好且可重复的实验,我使用不同大小的 numpy 数组生成图像,并使用 Pillow、OpenCV 和 Scipy 三个库使用相同的插值函数旋转它们。答案可以总结在下图中。要重复实验或看看我是如何得出这个结论的,请参考此链接,如果您认为可以改进,请发表评论。

Python中三个图像处理库的运行时比较

于 2021-11-15T11:28:37.620 回答