Изображение, преобразованное из массива Scikit в фотоизображение PIL, искажается - PullRequest
3 голосов
/ 28 апреля 2019

Я пытаюсь добавить изображение, обработанное scikit-image и scipy, в графический интерфейс пользователя tkinter. Чтобы добавить его на холст, его нужно либо сохранить в формате png, либо преобразовать в PIL изображение. Однако, когда я пытаюсь использовать ImageTk Image.fromarray(), это сильно искажает изображение. Я бы предпочел не сохранять его как png, потому что это всего лишь промежуточный шаг для создания меток данных.

Я попытался проверить формы массивов, и они одинаковы. Я попытался распечатать изображения, и заполненные объекты - это правильное изображение, а im искажено. Так что это не проблема в интерфейсе Tkinter. Кроме того, если я не использую np.asarray(), он выдает тот же результат.

def generateCanny(imageName):
    #imagename should be a path to the image, created with os path join
    img = skimage.io.imread(imageName)
    print('orig {}'.format(img.shape))

    gray = np.sqrt((img*img).sum(-1))
    #converts the image to greyscale

    edges = skimage.feature.canny(gray, sigma=3)

    fill = scipy.ndimage.binary_fill_holes(edges)
    return fill

imageName = os.path.join(imagePath, imageStr)
filled_objects = generateCanny(imageName)
a = np.asarray(filled_objects)
im = PIL.Image.fromarray(a)

Вот два изображения, im слева и filled_objects справа

scikit to PIL image conversion distortion

Я бы подумал, что вы могли бы просто конвертировать его, потому что filled_objects - это просто массив, но Image.fromarray() должен выполнять некоторую обработку.

Ответы [ 2 ]

2 голосов
/ 28 апреля 2019

Проблема в том, что fromarray неправильно интерпретирует логический массив a. Если вы конвертируете a обратно в RGB с:

# Extend the array into 3 dimensions, repeating the data:
a = np.repeat(a[...,None],3,axis=2).astype(np.uint8)
# Scale to 0-255:
a = 255*a
im = PIL.Image.fromarray(a)

, затем im.show() отобразит правильное изображение.

0 голосов
/ 28 апреля 2019

Преобразование результата в NumPy's uint8 поможет:

from skimage import data, color, feature, util
import tkinter as tk
import numpy as np
from PIL import ImageTk, Image
from scipy.ndimage import binary_fill_holes

rgb = data.hubble_deep_field()
gray = color.rgb2grey(rgb)
edges = feature.canny(gray, sigma=3)
filled_objects = binary_fill_holes(edges)

img_bool = Image.fromarray(filled_objects)
img_uint8 = Image.fromarray(util.img_as_ubyte(filled_objects))

root = tk.Tk()
photo_bool = ImageTk.PhotoImage(img_bool)
photo_uint8 = ImageTk.PhotoImage(img_uint8)
label_bool = tk.Label(root, image=photo_bool).grid(row=1, column=1)
label_uint8 = tk.Label(root, image=photo_uint8).grid(row=1, column=2)
root.mainloop()

result

...