ฉันจะแปลงอาเรย์ numpy เป็น (และแสดง) ภาพได้อย่างไร?


228

ฉันได้สร้างอาร์เรย์ดังนี้:

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 ไม่สามารถใช้ได้
Peter Hansen

คุณจะพิจารณาเปลี่ยนคำตอบที่ยอมรับให้เปโตรได้ไหม? ทั้งสองหลีกเลี่ยงความจำเป็นในการล้อมวัตถุรอบอาร์เรย์ numpy และหลีกเลี่ยงการเขียนไฟล์ temp เพื่อแสดงภาพ
โยสิยาห์ Yoder

คำตอบ:


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 นั้นแตกต่างจากการสร้างดัชนีในจำนวนที่กำหนด มีคำถามที่เกี่ยวข้อง: 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 Verniani

285

ต่อไปนี้ควรทำงาน:

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

หากคุณใช้ Jupyter notebook / lab ให้ใช้คำสั่ง inline นี้ก่อนที่จะอิมพอร์ต matplotlib:

%matplotlib inline 

3
นี่แม่นยำกว่า PIL PIL rescales / normalizes ค่าอาร์เรย์ในขณะที่ pyplot ใช้ค่า RGB ที่แท้จริงเช่นเดียวกับพวกเขา
GaryO

21
อาจจะเป็นการดีที่ควรทราบ: หากคุณต้องการแสดงภาพระดับสีเทาแนะนำให้โทรplt.gray()หนึ่งครั้งในรหัสของคุณเพื่อสลับกราฟทั้งหมดต่อไปนี้เป็นสีเทา ไม่ใช่สิ่งที่ OP ต้องการ แต่เป็นการดีที่จะรู้
Cerno

2
จะบันทึกได้อย่างไร?
user334639

ไฟล์ "<ipython-input-29-29c784f62838>", บรรทัด 39 plt.show () ^ SyntaxError: ไวยากรณ์ที่ไม่ถูกต้อง
Mona Jalal

1
@Cerno รูปภาพระดับสีเทาควรมีรูปร่าง (h, w) มากกว่า (h, w, 1) คุณสามารถใช้squeeze()เพื่อกำจัดมิติที่สาม:plt.imshow(data.squeeze())
โยสิยาห์ Yoder

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? เป็นเพียงการนำเข้าและการเรียกใช้ฟังก์ชันสองสามอย่าง
Peter Hansen

PIL เข้ากันไม่ได้กับ 3.5 (จะไม่ติดตั้ง)
Christopher

1
ftr: scipy.misc.imshow(data)คุณสามารถลดระยะนี้ต่อไปโดยใช้โดยตรง
dtk

3
toimageได้รับการคัดค้านใน SciPy-1.0.0 และลบออกใน 1.2.0 Image.fromarrayในความโปรดปรานของหมอน
Sid

4

ใช้pygameคุณสามารถเปิดหน้าต่างรับพื้นผิวเป็นอาร์เรย์พิกเซลและจัดการตามที่คุณต้องการ คุณจะต้องคัดลอกอาร์เรย์ numpy ลงใน array surface ซึ่งจะช้ากว่าการใช้งานกราฟิกจริงบน pygame surface


3

วิธีแสดงรูปภาพที่เก็บไว้ในอาร์เรย์แบบ numpy ด้วยตัวอย่าง (ทำงานในสมุดบันทึก Jupyter)

ฉันรู้ว่ามีคำตอบที่ง่ายกว่านี้ แต่อันนี้จะทำให้คุณเข้าใจว่าภาพนั้นจมอยู่ในความเป็นจริงได้อย่างไร

โหลดตัวอย่าง

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ทำอย่างไร มันสร้างตัวแจงนับ numpy เพื่อให้คุณสามารถวนซ้ำแกนเพื่อวาดวัตถุบนพวกเขา ตัวอย่าง:

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

2

ใช้ fromarray ของหมอนตัวอย่างเช่น:

from PIL import Image
from numpy import *

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

1

ถ่ายภาพห้องสมุดหลามสามารถแสดงภาพโดยใช้อาร์เรย์ Numpy ลองดูที่หน้านี้เพื่อดูโค้ดตัวอย่าง:

แก้ไข: ดังที่บันทึกที่ด้านล่างของหน้าพูดว่าคุณควรตรวจสอบบันทึกประจำรุ่นล่าสุดซึ่งทำให้ง่ายกว่านี้มาก:

http://effbot.org/zone/pil-changes-116.htm


สิ่งนี้ไม่ตอบคำถาม
john ktejik

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))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.