Как я могу загрузить изображение в Python, но сохранить его сжатым? - PullRequest
1 голос
/ 02 апреля 2019

У меня есть серия изображений, все они доступны как в JP2, так и в PNG, и мне нужно загрузить это изображение в программу на Python, чтобы показать их в последовательности.Теперь мне нужно показать только часть последовательности, например:

один раз от кадра12 до кадра24, второй раз от кадра2 до кадра7, * ​​1003 * и т. Д.

загрузка всех изображений занимает у меня слишком много памяти и загружается каждый раз, когда новая последовательность - долгая задача.
есть функция / метод для загрузки изображения в программе, но держать сжатым?Могу ли я сохранить эти изображения в памяти, чтобы они были готовы к использованию, но с небольшим объемом памяти?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

Вы можете считывать прекрасные маленькие изображения 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

Вот оно на диске, с 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)
0 голосов
/ 02 апреля 2019

PIL - это библиотека изображений Python, которая предоставляет интерпретатору python возможности редактирования изображений.

Windows: Загрузите соответствующий пакет Pillow в соответствии с вашей версией Python. Обязательно загрузите в соответствии с имеющейся у вас версией Python.

Чтобы импортировать модуль Image, наш код должен начинаться со следующей строки:

    from PIL import Image

    Open a particular image from a path
    #img  = Image.open(path)      
    # On successful execution of this statement, 
    # an object of Image type is returned and stored in img variable) 

    try:  
        img  = Image.open(path)  
    except IOError: 
    pass

# Use the above statement within try block, as it can  
# raise an IOError if file cannot be found,  
# or image cannot be opened.

Извлечение размера изображения. Созданные экземпляры класса Image имеют много атрибутов, одним из его полезных атрибутов является размер.

from PIL import Image 

filename = "image.png"
with Image.open(filename) as image: 
    width, height = image.size 
#Image.size gives a 2-tuple and the width, height can be obtained 

Некоторые другие атрибуты: Image.width, Image.height, Image.format, Image.info и т. Д.

Сохранение изменений в изображении. Чтобы сохранить любые изменения, внесенные вами в файл изображения, нам необходимо указать путь и формат изображения.

img.save(path, format)     
# format is optional, if no format is specified,  
#it is determined from the filename extension

 from PIL import Image  

def main(): 
    try: 
     #Relative Path 
    img = Image.open("picture.jpg") 
    width, height = img.size 

    img = img.resize((width/2, height/2)) 

    #Saved in the same relative location 
    img.save("resized_picture.jpg")  
except IOError: 
    pass

if __name__ == "__main__": 
    main() 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...