簡體   English   中英

OpenCV Python:3通道float32圖像讀取的快速解決方案?

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

我需要類型為float32 3通道RBG排序彩色圖像,其值在每個顏色通道的間隔[0.0, 1.0]中。

這是我目前的解決方案:

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)

之后,在圖像處理程序中,我將BGR更改為RGB排序(因為cv2imread默認以BGR順序讀取圖像)。

對於大型圖像集來說,這個過程非常耗時:我正在加載數千個圖像進行預處理,然后將圖像提供給TensorFlow中實現的一些神經網絡。

有沒有辦法改善這種方法的性能?

通過這種方法,您可以做的不是太多,以加快您的圖像閱讀速度。 我想Matplotlib可能會更快,因為它直接讀取浮點數並按RGB順序讀取,但即使在轉換類型和通道順序后,它也會像OpenCV一樣慢三倍。 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
cv2.imread():13.830177563999314 s
io.imread():29.395271296001738 s
Image.open():26.633562815986807 s

相反,通過讀取所有圖像並將它們保存為更好的讀取格式(即直接從字節讀取)而不是使用圖像讀取器來預處理可能更好。 您可以序列化(泡菜)的圖像轉換成.p.pickle文件,然后直接將數據裝載到一個列表。 這樣你就必須只進行一次慢速加載。 正如DanMašek在評論中所述,腌制文件意味着將它們解壓縮為原始數據,因此文件大小更大。 您可以使用正確的類型和通道順序創建與現在相同的列表(緩沖區),然后選擇列表; 當你需要訓練時,你可以加載泡菜文件; 它的方式更快,超級簡單:

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