简体   繁体   English

OpenCV Python:3通道float32图像读取的快速解决方案?

[英]OpenCV Python: fast solution for 3-channel float32 image reading?

I need 3-channel RBG-ordered color images of type float32 with their values in the interval [0.0, 1.0] for each color channel. 我需要类型为float32 3通道RBG排序彩色图像,其值在每个颜色通道的间隔[0.0, 1.0]中。

This is my current solution: 这是我目前的解决方案:

def read_images(imagelist):
    buffer = list()
    for f in imagelist:
        # load single image, convert to float32
        img = cv2.imread(f).astype(np.float32)
        # change interval from [0, 255] to [0.0, 1.0]
        img /= 255.0
        # leave out alpha channel, if any
        if img.shape[2] == 4:
           img = img[:, :, 0:3]
        buffer.append(img)
    return np.array(buffer)

Afterwards, in an image handler, I change BGR to RGB ordering (because cv2 's imread reads images in BGR order by default). 之后,在图像处理程序中,我将BGR更改为RGB排序(因为cv2imread默认以BGR顺序读取图像)。

This procedure is quite time consuming for large image sets: I am loading thousands of images for pre-processing and then feed the images to some neural networks implemented in TensorFlow. 对于大型图像集来说,这个过程非常耗时:我正在加载数千个图像进行预处理,然后将图像提供给TensorFlow中实现的一些神经网络。

Is there a way of improving the performance of this approach? 有没有办法改善这种方法的性能?

With this approach, there's probably not too much you can do to speed up your image reading. 通过这种方法,您可以做的不是太多,以加快您的图像阅读速度。 I thought maybe Matplotlib would be faster, since it reads directly as a float and in RGB order, but it is thrice as slow as OpenCV, even after converting the type and channel order. 我想Matplotlib可能会更快,因为它直接读取浮点数并按RGB顺序读取,但即使在转换类型和通道顺序后,它也会像OpenCV一样慢三倍。 PIL is a bit faster than Matplotlib, but still twice as slow as OpenCV so that doesn't help, and scikit-image is about the same speed as PIL: PIL比Matplotlib快一点,但速度仍然是OpenCV的两倍,所以没有帮助,scikit-image与PIL速度大致相同:

import matplotlib.image as mpimg
import cv2
import numpy as np
from skimage import io
from PIL import Image

import timeit
times = range(1000)

# matplotlib
start_time = timeit.default_timer()
for t in times:
    img = mpimg.imread('img1.png')
print("mpimg.imread(): ", timeit.default_timer() - start_time, "s")

# OpenCV
start_time = timeit.default_timer()
for t in times:
    img = cv2.cvtColor(
        cv2.imread('img1.png'), cv2.COLOR_BGR2RGB).astype(np.float32)/255.0
print("cv2.imread(): ", timeit.default_timer() - start_time, "s")

# scikit-image
start_time = timeit.default_timer()
for t in times:
    img = io.imread('img1.png').astype(np.float32)/255.0
print("io.imread(): ", timeit.default_timer() - start_time, "s")

# PIL
start_time = timeit.default_timer()
for t in times:
    img = np.asarray(Image.open('img1.png')).astype(np.float32)/255.0
print("Image.open(): ", timeit.default_timer() - start_time, "s")

mpimg.imread(): 37.68960806101677 s mpimg.imread():37.68960806101677 s
cv2.imread(): 13.830177563999314 s cv2.imread():13.830177563999314 s
io.imread(): 29.395271296001738 s io.imread():29.395271296001738 s
Image.open(): 26.633562815986807 s Image.open():26.633562815986807 s

Instead it might be better to preprocess by reading through all the images and saving them to a better format for reading (that is, directly reading from bytes) instead of using image readers. 相反,通过读取所有图像并将它们保存为更好的读取格式(即直接从字节读取)而不是使用图像读取器来预处理可能更好。 You can serialize (pickle) your images into .p or .pickle files, and then load the data directly into a list. 您可以序列化(泡菜)的图像转换成.p.pickle文件,然后直接将数据装载到一个列表。 That way you just have to do the slow loading once and once only. 这样你就必须只进行一次慢速加载。 As Dan Mašek notes below in the comments, pickling your files means uncompressing them into raw data, so the files sizes will be far larger. 正如DanMašek在评论中所述,腌制文件意味着将它们解压缩为原始数据,因此文件大小更大。 You can create your same list as you have now (your buffer) with the correct type and channel ordering, and then pickle the list; 您可以使用正确的类型和通道顺序创建与现在相同的列表(缓冲区),然后选择列表; when it comes time to train you can load the pickle file; 当你需要训练时,你可以加载泡菜文件; it's way faster, and super simple: 它的方式更快,超级简单:

with open(training_file, mode='rb') as f:
    training_data = pickle.load(f)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM