Преобразование логического массива numpy в изображение подушки

В настоящее время я работаю с обработкой изображений на Python, используя библиотеку scikit-image. Я пытаюсь создать двоичное изображение с использованием порога sauvola со следующим кодом:

from PIL import Image
import numpy
from skimage.color import rgb2gray
from skimage.filters import threshold_sauvola

im = Image.open("test.jpg")
pix = numpy.array(im)
img = rgb2gray(pix)

window_size = 25
thresh_sauvola = threshold_sauvola(img, window_size=window_size)
binary_sauvola = img > thresh_sauvola

Что дает следующий результат: Преобразование логического массива numpy в изображение подушки

вывод представляет собой массив numpy с типом данных этого изображения - bool

[[ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 ...
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]]

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

image = Image.fromarray(binary_sauvola)

что делает изображение таким:

Преобразование логического массива numpy в изображение подушки

Я также пытался изменить тип данных с bool на uint8, но тогда я получу следующее исключение:

AttributeError: 'numpy.ndarray' object has no attribute 'mask'

Пока я не нашел решения для получения изображения PIL, которое выглядит как результат пороговой обработки.

«Я также пытался изменить тип данных с bool на uint8», пожалуйста, покажите попытку. Он явно не использовал view или astype, поэтому действительно не уверен, что вы сделали.

Mad Physicist 02.05.2018 14:31

Я попробовал следующую строку, чтобы изменить dtype на uint8 image = Image.fromarray(binary_sauvola.astype('uint8'))

R.hagens 02.05.2018 14:37

Затем покажите трассировку стека. Эта ошибка кажется странной. Пожалуйста, отредактируйте вопрос. Не добавляйте в комментарии корову и ошибки, если можете этого избежать.

Mad Physicist 02.05.2018 15:43
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
3
5 346
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Обновлять

Эта ошибка теперь решена в Pillow == 6.2.0. Ссылка на проблему на GitHub - здесь.

Если вы не можете выполнить обновление до новой версии Pillow, см. Ниже.


Функция Image.fromarray PIL имеет ошибку с изображениями в режиме «1». Этот Gist демонстрирует ошибку и показывает несколько обходных путей. Вот два лучших обходных пути:

import numpy as np
from PIL import Image

# The standard work-around: first convert to greyscale 
def img_grey(data):
    return Image.fromarray(data * 255, mode='L').convert('1')

# Use .frombytes instead of .fromarray. 
# This is >2x faster than img_grey
def img_frombytes(data):
    size = data.shape[::-1]
    databytes = np.packbits(data, axis=1)
    return Image.frombytes(mode='1', size=size, data=databytes)

Также см. Ошибка преобразования черно-белых изображений PIL в массивы Numpy.

img_grey не дает мне правильного результата, но img_frombytes дает. Большое спасибо за ваш ответ

R.hagens 02.05.2018 14:51

@ R.hagens С удовольствием! Интересно, что img_grey плохо себя ведет. Я не уверен, почему это происходит, я провел свое исследование по этой теме почти год назад и забыл о мелких деталях. Но я предпочитаю img_frombytes, так как написал его. :)

PM 2Ring 02.05.2018 14:54

ну, если вам интересно, img_grey дал мне следующий результат imgur.com/a/VC3yqs4

R.hagens 02.05.2018 15:04

@ R.hagens Спасибо. По сути, это та же ошибка, но я должен подумать, почему она все еще возникает, несмотря на преобразование шкалы серого, которое выполняет img_grey.

PM 2Ring 02.05.2018 15:15

Эта проблема решена в последней версии Pillow == 6.2.0. Ссылка на выпуск на github: github.com/python-pillow/Pillow/issues/3109

Taro Kiritani 24.10.2019 09:27

Эта опция могла быть недоступна в 2018 году, но в настоящее время

from skimage.io._plugins.pil_plugin import ndarray_to_pil, pil_to_ndarray
ndarray_to_pil(some_binary_image).convert("1")

кажется, делает свое дело.

Другие вопросы по теме