Як перетворити нумерований масив у (та відобразити) зображення?


227

Я створив масив таким чином:

import numpy as np
data = np.zeros( (512,512,3), dtype=np.uint8)
data[256,256] = [255,0,0]

Я хочу це зробити - відобразити одну червону крапку в центрі зображення 512x512. (По крайней мере, для початку ... Я думаю, що я можу розібратися з рештою звідти)


1
Дивіться також stackoverflow.com/questions/902761/…, хоча це накладало обмеження, що PIL не може бути використаний.
Пітер Хансен

Чи можете ви подумати про зміну прийнятої відповіді на Пітера ? Це дозволяє уникнути необхідності обертати об'єкт навколо нумерованого масиву і уникає написання тимчасового файлу для відображення зображення.
Йосія Йодер

Відповіді:


224

Ви можете використовувати PIL для створення (і відображення) зображення:

from PIL import Image
import numpy as np

w, h = 512, 512
data = np.zeros((h, w, 3), dtype=np.uint8)
data[0:256, 0:256] = [255, 0, 0] # red patch in upper left
img = Image.fromarray(data, 'RGB')
img.save('my.png')
img.show()

3
Здається, що є помилка. Ви створюєте масив з розміром (w,h,3), але він повинен бути (h,w,3), тому що індексація в PIL відрізняється від індексації в numpy. Існує пов'язаний з цим питання: stackoverflow.com/questions/33725237 / ...
fdermishin

1
@ user502144: Дякую за вказівку на мою помилку. Я повинен був створити масив фігур (h,w,3). (Зараз це виправлено вище.) Довжину першої осі можна вважати як кількість рядків у масиві, а довжину другої осі - кількість стовпців. Так (h, w)відповідає масив "висота" hта "ширина" w. Image.fromarrayперетворює цей масив у зображення висоти hта ширини w.
unutbu

1
img.show()не працюють у зошиті ipython. img_pil = Image.fromarray(img, 'RGB') display(img_pil.resize((256,256), PIL.Image.LANCZOS))
mrgloom

@unutbu цей метод здається спотворювати зображення ... stackoverflow.com/questions/62293077 / ...
Ludovico Верніані

284

Слід працювати:

from matplotlib import pyplot as plt
plt.imshow(data, interpolation='nearest')
plt.show()

Якщо ви використовуєте ноутбук / лабораторію Юпітера, використовуйте цю вбудовану команду перед імпортом matplotlib:

%matplotlib inline 

3
Це точніше, ніж PIL. PIL перераховує / нормалізує значення масиву, тоді як pyplot використовує фактичні значення RGB такими, якими вони є.
GaryO

21
Можливо, добре знати: Якщо ви хочете відобразити зображення в масштабах сірого, бажано plt.gray()один раз зателефонувати у ваш код, щоб переключити всі наступні графіки на сірі. Не те, чого хоче ОП, але все-таки добре знати.
Черно

2
Як зберегти це?
user334639

Файл "<ipython-input-29-29c784f62838>", рядок 39 plt.show () ^ SyntaxError: недійсний синтаксис
Mona Jalal

1
@Cerno Також зображення в масштабах сірого повинні мати форму (h, w), а не (h, w, 1). Ви можете використати squeeze()для усунення третього виміру:plt.imshow(data.squeeze())
Йосія Йодер

51

Найкоротший шлях - це користуватися scipyтаким чином:

from scipy.misc import toimage
toimage(data).show()

Для цього також потрібно встановити PIL або Подушку.

Аналогічний підхід також вимагає PIL або Подушки, але який може викликати іншого глядача :

from scipy.misc import imshow
imshow(data)

Тож цей метод несумісний з python 3.5 ...?
Крістофер

@bordeo, чому це було б несумісне з 3.5? Це лише імпорт та пара функцій дзвінків.
Пітер Хансен

PIL несумісний із 3,5 (не встановлюється)
Крістофер

1
Ftr: це можна додатково скоротити, використовуючи безпосередньо scipy.misc.imshow(data).
dtk

3
toimageбув застарілий у scipy-1.0.0 та видалений у 1.2.0, на користь Подушки Image.fromarray.
Сид

4

Використовуючи пігаму , ви можете відкрити вікно, отримати поверхню у вигляді масиву пікселів і звідти маніпулювати, як вам хочеться. Вам потрібно буде скопіювати свій numpy масив у поверхневий масив, але це буде набагато повільніше, ніж робити фактичні графічні операції на самих поверхнях піггему.


3

Як показати зображення, збережені в numpy масиві на прикладі (працює в блокноті Юпітера)

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

Приклад завантаження

from sklearn.datasets import load_digits
digits = load_digits()
digits.images.shape   #this will give you (1797, 8, 8). 1797 images, each 8 x 8 in size

Відображення масиву одного зображення

digits.images[0]
array([[ 0.,  0.,  5., 13.,  9.,  1.,  0.,  0.],
       [ 0.,  0., 13., 15., 10., 15.,  5.,  0.],
       [ 0.,  3., 15.,  2.,  0., 11.,  8.,  0.],
       [ 0.,  4., 12.,  0.,  0.,  8.,  8.,  0.],
       [ 0.,  5.,  8.,  0.,  0.,  9.,  8.,  0.],
       [ 0.,  4., 11.,  0.,  1., 12.,  7.,  0.],
       [ 0.,  2., 14.,  5., 10., 12.,  0.,  0.],
       [ 0.,  0.,  6., 13., 10.,  0.,  0.,  0.]])

Створіть порожні субплоти 10 x 10 для візуалізації 100 зображень

import matplotlib.pyplot as plt
fig, axes = plt.subplots(10,10, figsize=(8,8))

Складання 100 зображень

for i,ax in enumerate(axes.flat):
    ax.imshow(digits.images[i])

Результат:

введіть тут опис зображення

Що робить axes.flat? Він створює нумерований перелік, щоб ви могли перебирати вісь, щоб малювати на них об'єкти. Приклад:

import numpy as np
x = np.arange(6).reshape(2,3)
x.flat
for item in (x.flat):
    print (item, end=' ')

2

Наприклад, використовуючи подушку з масиву, наприклад:

from PIL import Image
from numpy import *

im = array(Image.open('image.jpg'))
Image.fromarray(im).show()


0

Доповнення для цього з matplotlib. Мені було зручно робити завдання з комп’ютерного зору. Скажімо, ви отримали дані з dtype = int32

from matplotlib import pyplot as plot
import numpy as np

fig = plot.figure()
ax = fig.add_subplot(1, 1, 1)
# make sure your data is in H W C, otherwise you can change it by
# data = data.transpose((_, _, _))
data = np.zeros((512,512,3), dtype=np.int32)
data[256,256] = [255,0,0]
ax.imshow(data.astype(np.uint8))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.