Вопрос с PIL.putdata () и для l oop, чтобы добавить измененные изображения в новый список - PullRequest
1 голос
/ 19 апреля 2020

У меня есть изображение, которое я хочу сделать 5 копий.

import PIL
from PIL import Image

image=Image.open("image.gif")
image=image.convert('RGB')
images=[]
for i in range(1, 6):
    images.append(image)

После внесения некоторых изменений в интенсивность каждого цвета в диапазоне RGB я хочу загрузить эти данные на эти 5 изображений (каждый элемент в списке «RGB_band» представляет собой кортеж, содержащий различные модификации пикселей и каждый кортеж уникален) показывает пиксельные данные изification_2, et c), но вместо этого все 5 изображений в списке «new_images» являются исходным изображением из списка «images» (без изменений). Тем не менее, во время «For» l oop, если у меня это так:

for i in range(len(images)):
    images[i].putdata(RGB_band[i])
    new_images.append(images[i])
    new_images[i].show()

Тогда изображение, показанное во время каждой итерации, имеет правильный цвет (т.е. 5 изображений показаны с 5 различными цветами)

Может кто-нибудь сказать мне, в чем проблема? Я пытался по-другому в "For" l oop, но изображения в списке "new_images" по-прежнему получались такими же.

1 Ответ

0 голосов
/ 19 апреля 2020

Я не знаю, что вы пытаетесь сделать, но я думаю, что вы не поняли, что Python объекты должны быть скопированы , чтобы быть уникальными объектами с собственной выделенной памятью.

Сравните это, когда каждое изображение в списке делится памятью с другими элементами:

image=Image.open("image.png").convert('RGB') 
images=[]
for i in range(1, 6):
    images.append(image) 

Если вы сейчас посмотрите на список - в частности, на адресах справа вы можете видеть, что они все это одно и то же:

print(images)

[<PIL.Image.Image image mode=RGB size=1000x300 at 0x1084C3C10>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1084C3C10>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1084C3C10>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1084C3C10>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1084C3C10>]

И если мы проверим, разделяют ли они память:

print(images[0] is images[4])
True

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

Uimages=[]
for i in range(1, 6):
    Uimages.append(image.copy()) 

Теперь посмотрите на список и увидите, что адреса разные:

print(Images)
[<PIL.Image.Image image mode=RGB size=1000x300 at 0x108797790>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x108797F50>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1087973D0>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x108797510>,
 <PIL.Image.Image image mode=RGB size=1000x300 at 0x1084DB450>]

И проверьте, не являются ли они одним и тем же объектом:

print(Uimages[0] is Uimages[4])
False

В общем, если вы начинаете обрабатывать изображения как списки пикселей, вы, вероятно, уже ошиблись. Это неэффективно и медленно. Попробуйте использовать Numpy или OpenCV и использовать векторизованный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...