วิธีการแปลงอาร์เรย์ NumPy เป็นภาพ PIL โดยใช้ matplotlib colormap


134

ฉันมีปัญหาง่ายๆ แต่ไม่สามารถหาวิธีแก้ปัญหาที่ดีได้

ฉันต้องการใช้อาร์เรย์ NumPy 2D ซึ่งแสดงถึงภาพสีเทาและแปลงเป็นภาพ RGB PIL ในขณะที่ใช้ colormaps ของ matplotlib

ฉันสามารถรับเอาต์พุต PNG ที่เหมาะสมได้โดยใช้pyplot.figure.figimageคำสั่ง:

dpi = 100.0
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi
fig = plt.figure(figsize=(w,h), dpi=dpi)
fig.figimage(sub, cmap=cm.gist_earth)
plt.savefig('out.png')

แม้ว่าฉันจะปรับสิ่งนี้เพื่อให้ได้สิ่งที่ต้องการ (อาจใช้ StringIO เพื่อรับภาพ PIL) แต่ฉันสงสัยว่าไม่มีวิธีที่ง่ายกว่านี้ในการทำเช่นนั้นเนื่องจากดูเหมือนว่าจะเป็นปัญหาที่เป็นธรรมชาติมากในการสร้างภาพ สมมติว่าสิ่งนี้:

colored_PIL_image = magic_function(array, cmap)

คำตอบ:


222

ค่อนข้างยุ่งหนึ่งซับ แต่นี่คือ:

  1. ครั้งแรกให้แน่ใจว่าอาร์เรย์ NumPy ของคุณเป็นปกติที่มีค่าสูงสุดที่myarray1.0
  2. myarrayสมัครตารางสีโดยตรง
  3. ปรับขนาดใหม่เป็น0-255ช่วง
  4. แปลงเป็นจำนวนเต็มโดยใช้np.uint8().
  5. ใช้Image.fromarray().

และเสร็จแล้ว:

from PIL import Image
from matplotlib import cm
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))

กับplt.savefig():

ใส่คำอธิบายภาพที่นี่

กับim.save():

ใส่คำอธิบายภาพที่นี่


7
ส่วน "ใช้ colormap โดยตรงกับmyarray" ตัดตรงใจ! ฉันไม่รู้ว่ามันเป็นไปได้ขอบคุณ!
heltonbiker

34
จากการศึกษาเอกสารเกี่ยวกับ LinearSegmentedColormap (ซึ่ง cm.gist_earth เป็นอินสแตนซ์) ฉันพบว่าเป็นไปได้ที่จะเรียกมันด้วยอาร์กิวเมนต์ "ไบต์" ซึ่งแปลงเป็น uint8 แล้ว จากนั้นซับเดียวเงียบกว่ามาก:im = Image.fromarray(cm.gist_earth(myarray, bytes=True))
heltonbiker

1
@CiprianTomoiaga รูปร่างของอาร์เรย์ควรเป็นขนาดภาพที่คุณต้องการ ตัวอย่างเช่นภาพ VGA จะถูกสร้างขึ้นจากอาร์เรย์ที่มีรูปร่าง (1024,768) คุณควรสังเกตว่าสิ่งนี้ใช้กับภาพขาวดำ สิ่งนี้มีความสำคัญเนื่องจากโดยปกติเมื่อคุณแปลงภาพ RGB เป็นอาร์เรย์รูปร่างของมันคือ (1024,768,3) เนื่องจากมีสามช่องสัญญาณ
heltonbiker

5
ฉันได้รับข้อผิดพลาดNameError: name 'cm' is not defined
rnso

10
@msofrom matplotlib import cm
Quantum7

10
  • input = numpy_image
  • np.unit8 -> แปลงเป็นจำนวนเต็ม
  • แปลง ('RGB') -> แปลงเป็น RGB
  • Image.fromarray -> ส่งคืนวัตถุรูปภาพ

    from PIL import Image
    import numpy as np
    
    PIL_image = Image.fromarray(np.uint8(numpy_image)).convert('RGB')
    
    PIL_image = Image.fromarray(numpy_image.astype('uint8'), 'RGB')

5
หวังว่ามันจะแก้ปัญหาได้ แต่โปรดเพิ่มคำอธิบายรหัสของคุณด้วยเพื่อให้ผู้ใช้เข้าใจได้อย่างสมบูรณ์แบบที่เขา / เธอต้องการจริงๆ
Jaimil Patel

1
ดีคำตอบที่อัปเดต คนก่อนหน้านี้มาจากหลายปีที่แล้ว
Catalina Chircu

7

วิธีการที่อธิบายไว้ในคำตอบที่ยอมรับไม่ได้ผลสำหรับฉันแม้ว่าจะใช้การเปลี่ยนแปลงที่กล่าวถึงในความคิดเห็นแล้วก็ตาม แต่รหัสง่ายๆด้านล่างใช้งานได้:

import matplotlib.pyplot as plt
plt.imsave(filename, np_array, cmap='Greys')

np_array อาจเป็นอาร์เรย์ 2 มิติที่มีค่าตั้งแต่ 0..1 ลอยตัว o2 0..255 uint8 และในกรณีนี้จำเป็นต้องใช้ cmap สำหรับอาร์เรย์ 3 มิติ cmap จะถูกละเว้น

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