В настоящее время я работаю с обработкой изображений на 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 с типом данных этого изображения - 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)
что делает изображение таким:
Я также пытался изменить тип данных с bool на uint8, но тогда я получу следующее исключение:
AttributeError: 'numpy.ndarray' object has no attribute 'mask'
Пока я не нашел решения для получения изображения PIL, которое выглядит как результат пороговой обработки.
Я попробовал следующую строку, чтобы изменить dtype на uint8 image = Image.fromarray(binary_sauvola.astype('uint8'))
Затем покажите трассировку стека. Эта ошибка кажется странной. Пожалуйста, отредактируйте вопрос. Не добавляйте в комментарии корову и ошибки, если можете этого избежать.
Эта ошибка теперь решена в 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 С удовольствием! Интересно, что img_grey
плохо себя ведет. Я не уверен, почему это происходит, я провел свое исследование по этой теме почти год назад и забыл о мелких деталях. Но я предпочитаю img_frombytes
, так как написал его. :)
ну, если вам интересно, img_grey дал мне следующий результат imgur.com/a/VC3yqs4
@ R.hagens Спасибо. По сути, это та же ошибка, но я должен подумать, почему она все еще возникает, несмотря на преобразование шкалы серого, которое выполняет img_grey
.
Эта проблема решена в последней версии Pillow == 6.2.0. Ссылка на выпуск на github: github.com/python-pillow/Pillow/issues/3109
Эта опция могла быть недоступна в 2018 году, но в настоящее время
from skimage.io._plugins.pil_plugin import ndarray_to_pil, pil_to_ndarray
ndarray_to_pil(some_binary_image).convert("1")
кажется, делает свое дело.
«Я также пытался изменить тип данных с bool на uint8», пожалуйста, покажите попытку. Он явно не использовал
view
илиastype
, поэтому действительно не уверен, что вы сделали.