Dans le traitement d'image et l'apprentissage profond basé sur l'image, le processus de lecture d'une image se produit fréquemment.
S'il s'agit de centaines de feuilles, il faudra quelques minutes juste pour le lire s'il est à l'échelle de dizaines de milliers, et s'il n'est qu'une seule fois, s'il est lu plusieurs fois pour des expériences, ce sera encore plus rapide.
Ici, nous allons comparer plusieurs bibliothèques et vous montrer comment réduire le temps de chargement.
pickle
ou np.save
** (la taille des données augmentera)
--Utilisez le nouveau protocole pickle
--Enregistrer sous np.uint8
La bibliothèque utilisée et le temps nécessaire pour charger une image (acquérir les données sous numpy.array) sont les suivants.
Bibliothèque | Temps de chargement |
---|---|
OpenCV | 4.23 ms |
matplotlib | 4.37 ms |
keras.preprocessing | 3.49 ms |
skimage | 2.56 ms |
PIL | 2.63 ms |
numpy | 333 µs |
pickle(protocol=1) | 597 µs |
pickle(protocol=2) | 599 µs |
pickle(protocol=3) | 112 µs |
pickle(protocol=4) | 118 µs |
_pickle(protocol=4) | 117 µs |
L'image lue est un fichier png de 512 x 512.
En ce qui concerne numpy et pickle, les images enregistrées en tant que .npy
et .pickle
ont été chargées à l'avance, ce n'est donc pas une comparaison équitable.
** C'est une table que si vous convertissez l'image à l'avance, vous pouvez obtenir cette vitesse **, et vous ne pouvez pas conclure que numpy et pickle sont généralement rapides.
pickle peut spécifier le protocole lorsque pickle.dump
, ** Plus le protocole est récent, plus la lecture est rapide ** C'est vrai, les données d'image sont donc enregistrées pour chaque protocole.
Il existe également une bibliothèque rapide comme accimage, mais je ne l'ai pas utilisée car elle n'était pas compatible avec macOS.
Il existe également une option hdf5, mais elle n'a pas été examinée.
Le code utilisé est le suivant. (Utilisation du notebook Jupyter)
import cv2
import matplotlib.pyplot as plt
import pickle
import numpy as np
from keras.preprocessing import image
from PIL import Image
from skimage import io
import _pickle
def imread1(path):
return cv2.imread(path)
def imread2(path):
return plt.imread(path)
def imread3(path):
img = image.load_img(path)
return image.img_to_array(img)
def imread4(path):
return io.imread(path)
def imread5(path):
img = Image.open(path)
return np.asarray(img)
def numpy_load(path):
return np.load(path)
def pickle_load(path):
with open(path, mode='rb') as f:
return pickle.load(f)
def _pickle_load(path):
with open(path, mode='rb') as f:
return _pickle.load(f)
%timeit img = imread1(img_path)
%timeit img = imread2(img_path)
%timeit img = imread3(img_path)
%timeit img = imread4(img_path)
%timeit img = imread5(img_path)
%timeit img = numpy_load(npy_path)
%timeit img = pickle_load(pickle_path_1)
%timeit img = pickle_load(pickle_path_2)
%timeit img = pickle_load(pickle_path_3)
%timeit img = pickle_load(pickle_path_4)
%timeit img = _pickle_load(pickle_path_4)
La taille d'une image .png de 512x512 enregistrée avec numpy et pickle est la suivante.
Bibliothèque | Type de données | Taille |
---|---|---|
données brutes | - | 236 KB |
numpy | np.uint8 | 820 KB |
pickle(protocol=1) | np.uint8 | 820 KB |
pickle(protocol=2) | np.uint8 | 820 KB |
pickle(protocol=3) | np.uint8 | 787 KB |
pickle(protocol=4) | np.uint8 | 787 KB |
numpy | np.float32 | 3.1 MB |
pickle(protocol=1) | np.float32 | 4.9 MB |
pickle(protocol=2) | np.float32 | 4.8 MB |
pickle(protocol=3) | np.float32 | 3.1 MB |
pickle(protocol=4) | np.float32 | 3.1 MB |
Il a été constaté que même np.uint8 occupe plus de trois fois la capacité des données d'origine.
Si vous disposez de suffisamment d'espace de stockage et que vous souhaitez augmenter la vitesse de lecture autant que possible, il semble préférable de le convertir afin qu'il puisse être lu facilement avec npy ou pickle.
Recommended Posts