Як зберегти зображення за допомогою PIL?


119

Я щойно зробив деяку обробку зображень за допомогою бібліотеки зображень Python (PIL), використовуючи допис, який я знайшов раніше, щоб здійснити перетворення зображень фур'є, і я не можу змусити функцію збереження працювати. Весь код працює добре, але він просто не збереже отримане зображення:

from PIL import Image
import numpy as np

i = Image.open("C:/Users/User/Desktop/mesh.bmp")
i = i.convert("L")
a = np.asarray(i)
b = np.abs(np.fft.rfft2(a))
j = Image.fromarray(b)
j.save("C:/Users/User/Desktop/mesh_trans",".bmp")

Я отримую помилку така:

save_handler = SAVE[string.upper(format)] # unknown format
    KeyError: '.BMP'

Як зберегти зображення за допомогою Pythons PIL?

Відповіді:


144

Помилка щодо розширення файлу була оброблена, ви або використовуєте BMP(без крапки) або передаєте ім'я виводу вже з розширенням. Тепер, щоб вирішити помилку, вам потрібно правильно змінити свої дані в частотній області, яку потрібно зберегти як ціле зображення, PILговорить про те, що він не приймає плаваючі дані для збереження як BMP.

Ось пропозиція (з іншими незначними модифікаціями, на зразок використання fftshiftта numpy.arrayзамість них numpy.asarray) щодо перетворення для правильної візуалізації:

import sys
import numpy
from PIL import Image

img = Image.open(sys.argv[1]).convert('L')

im = numpy.array(img)
fft_mag = numpy.abs(numpy.fft.fftshift(numpy.fft.fft2(im)))

visual = numpy.log(fft_mag)
visual = (visual - visual.min()) / (visual.max() - visual.min())

result = Image.fromarray((visual * 255).astype(numpy.uint8))
result.save('out.bmp')

1
Ей, велике спасибі це працює ідеально зараз! Тепер все, що я повинен зробити, - це зрозуміти всі кроки, але це не буде занадто погано. велике дякую за допомогу
user1999274

@ user1999274 Основна відмінність полягає у використанні fft2замість того, що rfft2для дискретних даних я не бачу сенсу використовувати пізніше. Решта суто косметична, тобто ви не зможете належним чином візуалізувати перетворення Фур'є, не застосувавши до нього фактор журналу. Тоді нормалізація полягає в тому, щоб просто зробити речі для перетворення в діапазон [0, 255].
mmgp

1
visual = (visual - visual.min()) / (visual.max() - visual.min())буде за замовчуванням, якщо visualне буде різниці (навряд чи, але варто вловлювати)

1
Я намагався використовувати цей код для своєї проблеми, але отримую звичайні чорні зображення. Хтось має про це уявлення? stackoverflow.com/questions/24266000 / ...
user961627

32

Ви повинні мати можливість просто дозволити PIL отримати розширення файлів, тобто використовувати:

j.save("C:/Users/User/Desktop/mesh_trans.bmp")

1
Дякуємо за вклад. однак, коли я намагаюся дозволити функції збереження отримати тип файлу, як ви запропонували вище, я отримую таку помилку: IOError: не можу записати режим F як BMP. будь-яка порада?
user1999274

1
Так, ви повинні перетворити масив у numpy.uint8dtype, а не плавати.
Вім

6

Спробуйте видалити .до цього .bmp(він не відповідає BMPочікуваному). Як видно з помилки, save_handlerверхній шрифт надається formatвами, а ви шукаєте відповідність SAVE. Однак відповідний ключ у цьому об’єкті є BMP(замість .BMP).

Я не знаю багато про що PIL, але з швидкого пошуку навколо здається, що це проблема із modeзображенням. Зміна визначення jна:

j = Image.fromarray(b, mode='RGB')

Здається, це працює для мене (однак зауважте, що я дуже мало знаю PIL, тому я б запропонував використовувати рішення @ mmgp, оскільки він / він чітко знає, що вони роблять :)). Для типів modeя використовував цю сторінку - сподіваюся, один із варіантів, який ви там буде, допоможе вам.


Я спробував видалити .bmp на користь bmp, і він все ще не працював. помилка, яку я тепер отримую, це: IOError: не можна записати режим F як BMP. Я перевірив сторінки PIL на документацію, і він сказав, що використовувати .bmp так загалом, я все ще не маю уявлення, чому це не працює.
user1999274

@ user1999274 Опублікував оновлення, яке, здавалося, працює для мене (вибачте за відсутність деталей - складання його разом, коли я йду разом :)).
RocketDonkey

@RocketDonkey це трохи розумніше, тому що перетворення результатів перетворення Фур'є в кольоровий простір RGB дасть безглузде зображення. Тільки тому, що це більше не спричиняє винятку, це не означає, що результат правильний.
mmgp

@mmgp Погодився - тому я поставив +1 вашому і сподіваюся, що ОП це сприймає :)
RocketDonkey

4

Я знаю, що це старе, але я виявив, що (під час використання Подушки) відкриття файлу за допомогою open(fp, 'w')та збереження файлу спрацює. Наприклад:

with open(fp, 'w') as f:
    result.save(f)

fp будучи шлях файлу, звичайно.


1
У документації Подушки говориться, що formatпараметр слід використовувати, якщо використовується файл-об'єкт save. Це не потрібно?
Роб Роуз

@RobRose під час мого тестування, коли я опублікував відповідь, я не знайшов нічого подібного необхідним. Однак це може бути і зараз. Якщо будь-яке тестування у вас виявиться необхідним, повідомте мене, і я відредагую свою відповідь
necko
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.