Вы можете считывать прекрасные маленькие изображения JPEG / PNG / JP2 в память в виде байтов и сохранять их там сжатыми с тем же размером, что и на диске, а затем распаковывать их из памяти, когда они вам нужны.
Во-первых, давайте посмотрим на память, необходимую для изображения RGB888 размером 1280x1024 - это колоссальные 3,9 МБ:
# Decompressed image in memory takes 3.9MB memory
im = np.zeros([1280,1024,3], dtype=np.uint8)
# print(im.nbytes) => 3932160
Теперь давайте посмотрим на JPEG такого же размера:
![enter image description here](https://i.stack.imgur.com/3rcja.jpg)
Вот оно на диске, с ls -l
:
-rw-r--r--@ 1 mark staff 47276 2 Apr 17:13 image.jpg
И здесь он все еще сжимается в памяти, также на 47 КБ или всего 1,2% от размера:
# Same image as JPEG takes 47kB of memory
with open('image.jpg','rb') as f:
jpg = f.read()
# print(len(jpg)) => 47276
Теперь, когда вам нужно изображение, распакуйте его из памяти, а не с диска
# Read with 'imageio'
from io import BytesIO
import imageio
numpyArray = imageio.imread(BytesIO(jpg))
# print(numpyArray.shape) =>(1024, 1280, 3)
# Or, alternatively, and probably faster, read with OpenCV
import cv2
numpyArray = cv2.imdecode(np.frombuffer(jpg,dtype=np.uint8), -1)
# print(numpyArray.shape) =>(1024, 1280, 3)
Другой, совершенно другой вариант, который будет декодировать мили быстрее, но уменьшит объем памяти только в 3 раза, - это палитрация изображений. Вы уменьшаете количество цветов до 256 уникальных цветов и сохраняете палитру с 256 цветами. В каждом месте пикселя вы сохраняете один байт, который является индексом в палитре, а не 3 байта RGB. Это уменьшит использование памяти с 3,9 МБ / изображение до 1,3 МБ / изображение. Это не потребует никакого декодирования. но может привести к незначительной потере точности цветопередачи и / или полос - что может быть или не быть проблемой в зависимости от качества вашей камеры / изображений.
Это выглядит примерно так (не проверено):
from PIL import Image
import numpy as np
im = Image.open('image.jpg')
# Make into Numpy array - size is 3.9MB
a = np.array(im)
# Now make a 256 colour palletised version
p = im.convert('P',palette=Image.ADAPTIVE)
# Make into Numpy array - size is now only 1.3MB
a = np.array(p)