Numpy diziyi bir görüntüye nasıl dönüştürürüm (ve görüntülerim)?


228

Böylece bir dizi oluşturduk:

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

Bunu yapmak istediğim 512x512 görüntünün ortasında tek bir kırmızı nokta göstermektir. (En azından başlamak için ... Sanırım gerisini oradan anlayabilirim)


1
Ayrıca bkz. Stackoverflow.com/questions/902761/…, ancak PIL'in kullanılamadığı kısıtlamasını dayattı.
Peter Hansen

Peter'a kabul edilen cevabı değiştirmeyi düşünür müsün ? Hem nesneyi numpy dizisinin etrafına sarma ihtiyacını ortadan kaldırır hem de görüntüyü görüntülemek için geçici bir dosya yazmayı önler.
Josiah Yoder

Yanıtlar:


225

Bir görüntü oluşturmak (ve görüntülemek) için PIL kullanabilirsiniz:

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
Görünüşe göre bir hata var. Boyutlu bir dizi oluşturursunuz (w,h,3), ancak olması gerekir (h,w,3), çünkü PIL'deki dizinleme numpy'deki dizinlemeden farklıdır. İlgili soru var: stackoverflow.com/questions/33725237/…
fdermishin

1
@ user502144: Hatamı belirttiğin için teşekkürler. Bir şekil dizisi oluşturmalıydım (h,w,3). (Şimdi düzeltildi, yukarıda.) İlk eksenin uzunluğu, dizideki satır sayısı ve ikinci eksenin uzunluğu, sütun sayısı olarak düşünülebilir. Yani (h, w)"yükseklik" hve "genişlik" dizisine karşılık gelir w. Image.fromarraybu diziyi yükseklik hve genişlik görüntüsüne dönüştürür w.
unutbu

1
img.show()ipython not defterinde çalışma. img_pil = Image.fromarray(img, 'RGB') display(img_pil.resize((256,256), PIL.Image.LANCZOS))
mrgloom

@unutbu bu yöntem görüntüleri bozuyor gibi görünüyor ... stackoverflow.com/questions/62293077/…
Ludovico Verniani

285

Aşağıdakiler işe yaramalıdır:

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

Jupyter dizüstü bilgisayar / laboratuvar kullanıyorsanız, matplotlib dosyasını içe aktarmadan önce bu satır içi komutu kullanın:

%matplotlib inline 

3
Bu PIL'den daha doğrudur. PIL dizi değerlerini yeniden ölçeklendirir / normalleştirir, oysa pyplot gerçek RGB değerlerini oldukları gibi kullanır.
GaryO

21
Bilmek iyi olabilir: Gri tonlamalı görüntüleri görüntülemek istiyorsanız, plt.gray()aşağıdaki tüm grafikleri gri tonlamaya geçirmek için kodunuzda bir kez aramanız önerilir . OP'nin istediği değil, yine de bilmek iyi.
Cerno

2
Nasıl kaydedilir?
user334639

"<ipython-input-29-29c784f62838>" dosyası, satır 39 plt.show () ^ Sözdizimi Hatası: geçersiz sözdizimi
Mona Jalal

1
@Cerno Ayrıca, gri tonlamalı görüntülerde (h, w, 1) yerine şekil (h, w) olmalıdır. squeeze()Üçüncü boyutu ortadan kaldırmak için kullanabilirsiniz :plt.imshow(data.squeeze())
Josiah Yoder

51

En kısa yol şu şekilde kullanılır scipy:

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

Bunun için PIL veya Yastık da takılmalıdır.

PIL veya Yastık gerektiren ancak farklı bir izleyiciyi çağırabilecek benzer bir yaklaşım :

from scipy.misc import imshow
imshow(data)

Peki bu yöntem python 3.5 ile uyumsuz ...?
Christopher

@bordeo, neden 3.5 ile uyumsuz olsun ki? Sadece bir ithalat ve birkaç işlev çağrısı.
Peter Hansen

PIL 3.5 (uyumsuz) ile uyumsuz
Christopher

1
Ftr: Bunu kullanarak doğrudan daha da kısaltabilirsiniz scipy.misc.imshow(data).
dtk

3
toimagescipy-1.0.0'da kullanımdan kaldırılmış ve Pillow'un lehine 1.2.0'da kaldırılmıştır Image.fromarray.
Sid

4

Pygame kullanarak bir pencere açabilir, yüzeyi piksel dizisi olarak alabilir ve oradan istediğiniz gibi değiştirebilirsiniz. Numpy dizinizi yüzey dizisine kopyalamanız gerekir, ancak bu, pygame yüzeylerinde gerçek grafik işlemleri yapmaktan çok daha yavaş olacaktır.


3

Numpy dizisinde depolanan görüntüler örnekle nasıl gösterilir (Jupyter not defterinde çalışır)

Daha basit cevaplar olduğunu biliyorum, ancak bu size görüntülerin aslında numpy dizisinden nasıl boğulduğunu anlayacaktır.

Yükleme örneği

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

Bir görüntünün ekran dizisi

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.]])

100 görüntüyü görselleştirmek için boş 10 x 10 alt grafikler oluşturun

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

100 resim çizme

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

Sonuç:

resim açıklamasını buraya girin

Ne yapar axes.flat? Numpy numaralandırıcı oluşturur, böylece üzerlerine nesne çizmek için eksen üzerinde yineleme yapabilirsiniz. Misal:

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

2

Örneğin, yastığın fromarray kullanımı:

from PIL import Image
from numpy import *

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


0

Matplotlib ile bunu yapmak için ek. Bilgisayar görme görevlerini yaparken kullanışlı buldum. Diyelim ki dtype = int32 ile veri aldınız

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))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.