Удаление пространственной интерполяции или сжатия в GIF-файлах, созданных с помощью imageio или PIL
Я пытаюсь создать GIF с использованием imageio. Это довольно просто; Однако качество изображений оставляет желать лучшего. Они кажутся интерполированными. Смотрите рисунки ниже.
Я создаю GIF с помощью кода, показанного ниже. Я попытался проследить, как изображение создается внутри исходного кода, и проблема, похоже, исходит от PIL.
from PIL import Image
import imageio
import numpy as np
import matplotlib.pyplot as plt
outdir = r"where/you/want/it/to/go.gif"
frames = np.round(100+20*np.random.randn(10, 40, 40)).astype(np.uint8)
# Create single gif frame with PIL
im = Image.fromarray(frames[0])
im.save(outdir)
# Create gif with imageio
imageio.mimsave(outdir, frames)
Я хочу GIF, который выглядит как изображение сверху (без интерполяции), который я сделал с matplotlib
, Изображение внизу представляет собой один кадр, созданный с использованием imageio
,
1 ответ
Я попытался воспроизвести проблему, но, насколько я могу судить, внутри ImageIO или Pillow интерполяции не происходит:
from PIL import Image
import imageio as iio
import numpy as np
import io
for _ in range(100):
expected_frames = np.round(100+20*np.random.randn(10, 40, 40)).astype(np.uint8)
# test writing with pillow
pil_buffer = io.BytesIO()
im = Image.fromarray(expected_frames[0])
gif_bytes = im.save(pil_buffer, format="GIF")
actual_pil = iio.v3.imread(pil_buffer, mode="L")
assert np.all(actual_pil == expected_frames[0])
# test writing with ImageIO
gif_bytes = iio.v3.imwrite("<bytes>", expected_frames, format="GIF")
actual_iio = iio.v3.imread(gif_bytes, index=None, mode="L")
assert np.all(actual_iio == expected_frames)
print("No roundtrip modified any pixels.")
Так что я думаю, что либо
- Возможно, была ошибка в Pillow или ImageIO, которая с тех пор была исправлена (прошло 3 года)
- Инструмент/приложение, которое вы использовали для отображения второго изображения, интерполирует при увеличении изображения (поскольку это изображение имеет размер 200x200 пикселей, а не 40x40 пикселей).