ฉันมีเมทริกซ์ในประเภทของ Numpy array ฉันจะเขียนมันลงในดิสก์เป็นรูปภาพได้อย่างไร รูปแบบใดก็ได้ที่ทำงาน (png, jpeg, bmp ... ) ข้อ จำกัด ที่สำคัญอย่างหนึ่งคือไม่มี PIL
ฉันมีเมทริกซ์ในประเภทของ Numpy array ฉันจะเขียนมันลงในดิสก์เป็นรูปภาพได้อย่างไร รูปแบบใดก็ได้ที่ทำงาน (png, jpeg, bmp ... ) ข้อ จำกัด ที่สำคัญอย่างหนึ่งคือไม่มี PIL
คำตอบ:
คุณสามารถใช้PyPNG มันเป็นงูหลามบริสุทธิ์ (ไม่มีการพึ่งพา) โอเพนซอร์ส PNG เข้ารหัส / ถอดรหัสและสนับสนุนการเขียนอาร์เรย์ NumPy เป็นภาพ
สิ่งนี้ใช้ PIL แต่บางทีบางคนอาจเห็นว่ามีประโยชน์:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
แก้ไข : scipy
รุ่นปัจจุบันเริ่มที่จะทำให้ปกติทุกภาพเพื่อให้ min (data) กลายเป็นสีดำและ max (data) กลายเป็นสีขาว สิ่งนี้ไม่พึงประสงค์หากข้อมูลควรเป็นระดับสีเทาหรือช่อง RGB ที่แน่นอน การแก้ไขปัญหา:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
คำตอบที่ใช้PIL (ในกรณีที่มีประโยชน์)
รับอาร์เรย์ numpy "A":
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
คุณสามารถแทนที่ "jpeg" ด้วยเกือบทุกรูปแบบที่คุณต้องการ รายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบที่นี่
from PIL import Image
เพื่อให้ชัดเจน ...
ด้วยmatplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
ทำงานร่วมกับ matplotlib 1.3.1 ฉันไม่รู้เกี่ยวกับเวอร์ชั่นที่ต่ำกว่า จาก docstring:
Arguments:
*fname*:
A string containing a path to a filename, or a Python file-like object.
If *format* is *None* and *fname* is a string, the output
format is deduced from the extension of the filename.
*arr*:
An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
matplotlib.pyplot.imsave
อยู่ใน matplotlib 2+
import matplotlib.pyplot as plt
และจากนั้นplt.imsave('name.png', array)
Pure Python (2 & 3) ตัวอย่างข้อมูลที่ไม่มีการอ้างอิงจากบุคคลที่สาม
ฟังก์ชั่นนี้เขียนไฟล์บีบอัด, สีจริง (4 ไบต์ต่อพิกเซล) RGBA
PNG ของ
def write_png(buf, width, height):
""" buf: must be bytes or a bytearray in Python3.x,
a regular string in Python2.x.
"""
import zlib, struct
# reverse the vertical line order and add null bytes at the start
width_byte_4 = width * 4
raw_data = b''.join(
b'\x00' + buf[span:span + width_byte_4]
for span in range((height - 1) * width_byte_4, -1, - width_byte_4)
)
def png_pack(png_tag, data):
chunk_head = png_tag + data
return (struct.pack("!I", len(data)) +
chunk_head +
struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))
return b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
png_pack(b'IEND', b'')])
... ข้อมูลควรถูกเขียนโดยตรงไปยังไฟล์ที่เปิดเป็นไบนารีเช่นเดียวกับใน:
data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fh:
fh.write(data)
buf
) ที่ควรจะเป็น ดูเหมือนว่ามันจะไม่ใช่อาร์เรย์ที่มีค่ามาก ...
มีopencv
ไว้สำหรับหลาม ( เอกสารประกอบที่นี่ )
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
มีประโยชน์ถ้าคุณต้องการทำการประมวลผลอื่นนอกเหนือจากการบันทึก
np.zeros((10,10))
ด้วยภาพของคุณ
cmap="gray"
เมื่อฉันบันทึกภาพโดยใช้ cv2
หากคุณมี matplotlib คุณสามารถทำได้:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
plt.axis('off')
คุณสามารถใช้ไลบรารี 'skimage' ใน Python
ตัวอย่าง:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
scipy.misc
ให้คำเตือนการเลิกใช้งานเกี่ยวกับimsave
ฟังก์ชันและแนะนำการใช้งานimageio
แทน
import imageio
imageio.imwrite('image_name.png', img)
ภาคผนวกคำตอบของ @ ideasman42:
def saveAsPNG(array, filename):
import struct
if any([len(row) != len(array[0]) for row in array]):
raise ValueError, "Array should have elements of equal size"
#First row becomes top row of image.
flat = []; map(flat.extend, reversed(array))
#Big-endian, unsigned 32-byte integer.
buf = b''.join([struct.pack('>I', ((0xffFFff & i32)<<8)|(i32>>24) )
for i32 in flat]) #Rotate from ARGB to RGBA.
data = write_png(buf, len(array[0]), len(array))
f = open(filename, 'wb')
f.write(data)
f.close()
ดังนั้นคุณสามารถทำได้:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
ผลิตtest_grid.png
:
(ความโปร่งใสยังทำงานได้โดยลดไบต์สูงจาก0xff
)
สำหรับผู้ที่กำลังมองหาตัวอย่างการทำงานโดยตรงอย่างสมบูรณ์:
from PIL import Image
import numpy
w,h = 200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8) # has to be unsigned bytes
img[:] = (0,0,255) # fill blue
x,y = 40,20
img[y:y+30, x:x+50] = (255,0,0) # 50x30 red box
Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert
นอกจากนี้หากคุณต้องการ jpeg คุณภาพสูง
.save(file, subsampling=0, quality=100)
matplotlib svn มีฟังก์ชั่นใหม่ในการบันทึกภาพเป็นเพียงภาพ - ไม่มีแกน ฯลฯ มันเป็นฟังก์ชั่นที่ง่ายมากสำหรับ backport เช่นกันหากคุณไม่ต้องการติดตั้ง svn (คัดลอกโดยตรงจาก image.py ใน matplotlib svn ลบ docstring สำหรับความกะทัดรัด):
def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
canvas = FigureCanvas(fig)
fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
fig.savefig(fname, dpi=1, format=format)
โลกอาจไม่จำเป็นต้องมีแพ็คเกจอื่นสำหรับการเขียนอาเรย์ numpy ไปยังไฟล์ PNG แต่สำหรับคนที่ไม่พอฉันเพิ่งวางnumpngw
GitHub:
https://github.com/WarrenWeckesser/numpngw
และใน pypi: https://pypi.python.org/pypi/numpngw/
การพึ่งพาจากภายนอกเพียงอย่างเดียวคือจำนวนมาก
นี่คือตัวอย่างแรกจากexamples
ไดเรกทอรีของที่เก็บ เส้นสำคัญคือ
write_png('example1.png', img)
ที่img
เป็นอาร์เรย์ numpy img
ทั้งหมดรหัสก่อนที่จะสายว่าเป็นงบการนำเข้าและรหัสในการสร้าง
import numpy as np
from numpngw import write_png
# Example 1
#
# Create an 8-bit RGB image.
img = np.zeros((80, 128, 3), dtype=np.uint8)
grad = np.linspace(0, 255, img.shape[1])
img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127
write_png('example1.png', img)
นี่คือไฟล์ PNG ที่สร้างขึ้น:
สมมติว่าคุณต้องการภาพระดับสีเทา:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageioเป็นห้องสมุด Python ที่ให้อินเตอร์เฟซที่ใช้งานง่ายในการอ่านและเขียนข้อมูลรูปภาพที่หลากหลายรวมถึงภาพเคลื่อนไหววิดีโอข้อมูลปริมาตรและรูปแบบทางวิทยาศาสตร์ เป็นแพลตฟอร์มข้ามรันบน Python 2.7 และ 3.4+ และติดตั้งง่าย
นี่คือตัวอย่างสำหรับภาพระดับสีเทา:
import numpy as np
import imageio
# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])
# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4, 4)).astype('uint8')
# save image
imageio.imwrite('pic.jpg', data)
หากคุณเกิดขึ้นกับการใช้งาน [Py] Qt แล้วคุณอาจจะสนใจในqimage2ndarray เริ่มต้นด้วยรุ่น 1.4 (เพิ่งวางจำหน่ายแล้ว) รองรับ PySide เช่นกันและจะมีimsave(filename, array)
ฟังก์ชั่นเล็ก ๆคล้ายกับ scipy แต่ใช้ Qt แทน PIL ด้วย 1.3 เพียงใช้สิ่งต่อไปนี้:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..
(ข้อดีอีกข้อที่ 1.4 ก็คือมันเป็นโซลูชันของงูหลามที่บริสุทธิ์ซึ่งทำให้สิ่งนี้มีน้ำหนักเบายิ่งขึ้น)
หากคุณกำลังทำงานในสภาพแวดล้อมของงูหลาม Spyder แล้วมันจะไม่ง่ายไปกว่าการคลิกขวาที่อาร์เรย์ในตัวสำรวจตัวแปรแล้วเลือกตัวเลือกแสดงภาพ
วิธีนี้จะขอให้คุณบันทึกภาพเป็น dsik ซึ่งส่วนใหญ่อยู่ในรูปแบบ PNG
ไม่จำเป็นต้องใช้ไลบรารี PIL ในกรณีนี้
cv2.imwrite
ใช้
import cv2
assert mat.shape[2] == 1 or mat.shape[2] == 3, 'the third dim should be channel'
cv2.imwrite(path, mat) # note the form of data should be height - width - channel
สำหรับการบันทึกอาร์เรย์แบบ numpy เป็นอิมเมจคุณมีหลายทางเลือก:
1) อื่น ๆ ที่ดีที่สุด: OpenCV
import cv2 cv2.imwrite('file name with extension(like .jpg)', numpy_array)
2) Matplotlib
from matplotlib import pyplot as plt plt.imsave('file name with extension(like .jpg)', numpy_array)
3) PIL
from PIL import Image image = Image.fromarray(numpy_array) image.save('file name with extension(like .jpg)')
4) ...