Saya punya matriks dalam jenis array Numpy. Bagaimana saya menulisnya ke disk sebagai gambar? Semua format berfungsi (png, jpeg, bmp ...). Salah satu kendala penting adalah bahwa PIL tidak ada.
Saya hanya ingin mencatat bahwa beberapa jawaban di bawah ini, dan tentunya beberapa orang yang datang dan menemukan pertanyaan ini, tidak memenuhi batasan yang tercantum di atas tanpa PIL . Karena beberapa penanya dan beberapa jawaban sama-sama menghindari kendala itu, saya mendorong siapa pun yang ada di sini dan tidak keberatan memiliki PIL untuk melihat di bawah, dan jawaban non-PIL (baru atau lama) untuk menyebutkan bahwa mereka adalah PIL-digunakan jenis jawaban, untuk membedakan diri dari jawaban yang memenuhi kendala asli.
Anda bisa menggunakan PyPNG . Ini adalah Python murni (tanpa dependensi) open source PNG encoder / decoder dan mendukung penulisan array NumPy sebagai gambar.
Ingatlah untuk skala nilai ke rentang yang tepat untuk PNG, biasanya 0..255. Rentang nilai dalam jaringan saraf seringkali 0..1 atau -1..1.
Tomáš Gavenčiak
8
PyPNG adalah Python murni, yang mengurangi ketergantungan eksternal, tetapi membuatnya jauh lebih lambat dari PIL dan kelas turunannya. Misalnya, menyimpan gambar 3000x4000 di komputer saya membutuhkan 4,05 detik dengan PyPNG tetapi hanya 0,59 detik dengan scipy.misc.imsave (6x lebih cepat).
Zvika
@ TomášGavenčiak - scipy.misc.imsave sekarang tidak digunakan lagi dalam versi Scipy yang lebih baru. Alternatif beberapa komentar di bawah ini adalah dengan menggunakan imageio.imwrite ('image_file.jpg', array)
Psi-Ed
259
Ini menggunakan PIL, tetapi mungkin beberapa mungkin merasa berguna:
EDIT : Versi saat scipyini mulai menormalkan semua gambar sehingga min (data) menjadi hitam dan maks (data) menjadi putih. Ini tidak diinginkan jika data harus tingkat abu-abu yang tepat atau saluran RGB yang tepat. Solusinya:
imsave tinggal di ... / scipy / misc / pilutil.py yang menggunakan PIL
denis
5
Berhati-hatilah saat mengonversi ke jpg karena itu lossy dan karenanya Anda mungkin tidak dapat memulihkan data yang digunakan untuk menghasilkan gambar.
Feanil
8
Ini sekarang ditinggalkan dalam penggunaan 0,19 scipy - scipy.io.imwrite
g.stevo
6
"imsave sudah ditinggalkan dalam SciPy 1.0.0, dan akan dihapus dalam 1.2.0" ( Scipy 1.1.0 doc )
noobar
15
scipy.misc.imsave sudah usang. gunakan import imageio; imageio.imwrite ('file_name.jpg', nmupy_array)
ChaosPredictor
228
Jawaban menggunakan PIL (kalau-kalau itu berguna).
diberi array numpy "A":
from PIL importImage
im =Image.fromarray(A)
im.save("your_file.jpeg")
Anda dapat mengganti "jpeg" dengan hampir semua format yang Anda inginkan. Lebih detail tentang format di sini
Gambar adalah modul PIL. Lakukan "cetak Gambar .__ file__"
Juh_
10
Sangat membantu bagi kita yang berkeliaran di sini dan memiliki PIL - saya pikir saya akan menggunakan from PIL import Imageuntuk menjernihkan ...
bijak
4
Jika Anda memiliki gambar RGB, Anda bisa mendapatkan gambar menggunakan im = Image.fromarray (A) .convert ('RGB') Info lebih lanjut: stackoverflow.com/questions/4711880/…
Roger Veciana
Menggunakan sumbu ketiga array uint8 untuk mengkode RGB berfungsi dengan metode ini. Modul PIL dapat dipasang menggunakan "pip install pillow".
bli
1
@Ludovico Verniani Ini tidak mengubah gambar, tetapi ia menggunakan pengkodean warna yang agak tidak umum di mana urutan warna adalah BGR daripada RGB.
Bekerja dengan matplotlib 1.3.1, saya tidak tahu tentang versi yang lebih rendah. Dari 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*:AnMxN(luminance),MxNx3(RGB)orMxNx4(RGBA) array.
Menggunakan ini. Tetapi menderita kebocoran memori
SolessChong
matplotlib.imsave () dalam versi yang lebih baru
Vinay Lodha
6
Ada matplotlib.pyplot.imsavedi matplotlib 2+
Aleksei Petrenko
1
@HughPerkins mencoba Bantal sebagai pengganti PIL dengan Python 3
christianbrodbeck
10
import matplotlib.pyplot as pltdan kemudianplt.imsave('name.png', array)
Alessandro Jacopson
62
Pure Python (2 & 3), cuplikan tanpa dependensi pihak ketiga.
Fungsi ini menulis RGBAPNG's terkompresi, warna asli (4 byte per piksel) .
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 harus ditulis langsung ke file yang dibuka sebagai biner, seperti pada:
data = write_png(buf,64,64)with open("my_image.png",'wb')as fh:
fh.write(data)
Ini tampaknya persis apa yang saya cari, tetapi bisakah Anda menambahkan beberapa komentar? Saya tidak melihat bagaimana ini menulis ke file. Apakah Anda harus menulis output di file yang sebelumnya dibuka? Terima kasih!
PhilMacKay
1
@ PhilMacKay, data harus ditulis ke file biner. menambahkan komentar.
ideasman42
1
Bisakah seseorang menentukan format gambar ( buf) yang seharusnya? Tampaknya tidak menjadi array numpy ...
Tidak, untuk antarmuka pyplot, plt.figure () tidak perlu. Selain itu, Anda hanya perlu plt.show () jika Anda ingin melihat jendela gambar juga - dalam hal ini hanya menyimpan file gambar yang diinginkan, jadi tidak perlu memanggil show ().
DopplerShift
7
Perhatikan bahwa file gambar yang dihasilkan akan berisi sumbu dan area abu-abu dari gambar matlplotlib - bukan hanya data piksel.
Dave
1
tidak akan berfungsi jika Anda menjalankan skrip pada host jarak jauh, ssh-ing tanpa skrip antarmuka grafis.
Temak
Jika Anda ingin menampilkan gambar dalam buku catatan, Anda dapat menambahkan yang berikut: >> "dari IPython.display import Image" dan kemudian >> "Image (nama file = nama file)"
Robert
Untuk menghapus poros:plt.axis('off')
yakout
15
Anda dapat menggunakan perpustakaan 'skimage' dengan Python
Contoh:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
def saveAsPNG(array, filename):import struct
if any([len(row)!= len(array[0])for row in array]):raiseValueError,"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()
Bagi mereka yang mencari contoh langsung bekerja penuh:
from PIL importImageimport 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 boxImage.fromarray(img).convert("RGB").save("art.png")# don't need to convert
juga, jika Anda ingin jpeg berkualitas tinggi .save(file, subsampling=0, quality=100)
matplotlib svn memiliki fungsi baru untuk menyimpan gambar hanya sebagai gambar - tidak ada sumbu dll. ini adalah fungsi yang sangat sederhana untuk backport juga, jika Anda tidak ingin menginstal svn (disalin langsung dari image.py di matplotlib svn, hapus docstring for brevity):
Dunia mungkin tidak membutuhkan paket lain untuk menulis array numpy ke file PNG, tetapi bagi mereka yang tidak bisa mendapatkan cukup, saya baru-baru ini memasang numpngwgithub:
Satu-satunya ketergantungan eksternal adalah numpy.
Inilah contoh pertama dari examplesdirektori repositori. Garis dasarnya sederhana saja
write_png('example1.png', img)
dimana imgarray numpy. Semua kode sebelum baris itu adalah pernyataan impor dan kode untuk dibuat 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)
Saya ingin tahu, bagaimana lib Anda berbeda dari yang lain? Apakah ini lebih cepat? Apakah ada fitur mewah?
F Lekschas
Beberapa fitur: (1) Menggunakan array numpy. (2) Ini ditulis hanya menggunakan python dan numpy, sehingga tidak memerlukan pustaka C untuk diinstal. (3) Dapat membuat file PNG animasi. (4) Ini menyediakan kelas untuk menulis animasi matplotlib sebagai file PNG animasi.
Warren Weckesser
Terima kasih! Saya ingin tahu bagaimana membandingkannya dengan stackoverflow.com/a/19174800/981933 dalam hal kinerja yang juga merupakan python murni. Metode sebelumnya di atas 2x lebih cepat dari PIL, yang cukup mengagumkan. Nevermind jika itu bukan tujuan Anda :)
F Lekschas
2
Dengan asumsi Anda menginginkan gambar skala abu-abu:
im =Image.new('L',(width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio adalah perpustakaan Python yang menyediakan antarmuka yang mudah untuk membaca dan menulis berbagai data gambar, termasuk gambar animasi, video, data volumetrik, dan format ilmiah. Ini adalah lintas-platform, berjalan pada Python 2.7 dan 3.4+, dan mudah untuk diinstal.
Ini adalah contoh untuk gambar skala abu-abu:
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)
Jika Anda sudah menggunakan [Py] Qt, Anda mungkin tertarik dengan qimage2ndarray . Dimulai dengan versi 1.4 (baru saja dirilis), PySide didukung juga, dan akan ada imsave(filename, array)fungsi kecil yang mirip dengan scipy's, tetapi menggunakan Qt bukan PIL. Dengan 1.3, cukup gunakan sesuatu seperti berikut:
qImage = array2qimage(image, normalize =False)# create QImage from ndarray
success = qImage.save(filename)# use Qt's image IO functions for saving PNG/JPG/..
(Keuntungan lain dari 1.4 adalah itu adalah solusi python murni, yang membuatnya lebih ringan.)
Rilis 1.4 keluar sekarang. :-) (Saya mengedit jawaban sesuai.)
hans_meine
1
Jika Anda bekerja di lingkungan python Spyder, maka itu tidak bisa lebih mudah daripada mengklik kanan array di explorer variabel, dan kemudian pilih opsi Tampilkan Gambar.
Ini akan meminta Anda untuk menyimpan gambar ke dsik, sebagian besar dalam format PNG.
import cv2
assert mat.shape[2]==1or mat.shape[2]==3,'the third dim should be channel'
cv2.imwrite(path, mat)# note the form of data should be height - width - channel
Jawaban:
Anda bisa menggunakan PyPNG . Ini adalah Python murni (tanpa dependensi) open source PNG encoder / decoder dan mendukung penulisan array NumPy sebagai gambar.
sumber
Ini menggunakan PIL, tetapi mungkin beberapa mungkin merasa berguna:
EDIT : Versi saat
scipy
ini mulai menormalkan semua gambar sehingga min (data) menjadi hitam dan maks (data) menjadi putih. Ini tidak diinginkan jika data harus tingkat abu-abu yang tepat atau saluran RGB yang tepat. Solusinya:sumber
Jawaban menggunakan PIL (kalau-kalau itu berguna).
diberi array numpy "A":
Anda dapat mengganti "jpeg" dengan hampir semua format yang Anda inginkan. Lebih detail tentang format di sini
sumber
from PIL import Image
untuk menjernihkan ...Dengan
matplotlib
:Bekerja dengan matplotlib 1.3.1, saya tidak tahu tentang versi yang lebih rendah. Dari docstring:
sumber
matplotlib.pyplot.imsave
di matplotlib 2+import matplotlib.pyplot as plt
dan kemudianplt.imsave('name.png', array)
Pure Python (2 & 3), cuplikan tanpa dependensi pihak ketiga.
Fungsi ini menulis
RGBA
PNG's terkompresi, warna asli (4 byte per piksel) .... Data harus ditulis langsung ke file yang dibuka sebagai biner, seperti pada:
sumber
buf
) yang seharusnya? Tampaknya tidak menjadi array numpy ...Ada
opencv
untuk python ( dokumentasi di sini ).berguna jika Anda perlu melakukan lebih banyak pemrosesan selain menyimpan.
sumber
np.zeros((10,10))
dengan gambar Anda.cmap="gray"
ketika saya menyimpan gambar menggunakan cv2?Jika Anda memiliki matplotlib, Anda dapat melakukan:
Ini akan menyimpan plot (bukan gambar itu sendiri).
sumber
plt.axis('off')
Anda dapat menggunakan perpustakaan 'skimage' dengan Python
Contoh:
sumber
scipy.misc
memberikan peringatan penghentian tentangimsave
fungsi dan menyarankan penggunaanimageio
sebagai gantinya.sumber
Tambahan untuk jawaban @ ideasman42:
Jadi kamu bisa melakukan:
Memproduksi
test_grid.png
:(Transparansi juga berfungsi, dengan mengurangi byte tinggi dari
0xff
.)sumber
Bagi mereka yang mencari contoh langsung bekerja penuh:
juga, jika Anda ingin jpeg berkualitas tinggi
.save(file, subsampling=0, quality=100)
sumber
matplotlib svn memiliki fungsi baru untuk menyimpan gambar hanya sebagai gambar - tidak ada sumbu dll. ini adalah fungsi yang sangat sederhana untuk backport juga, jika Anda tidak ingin menginstal svn (disalin langsung dari image.py di matplotlib svn, hapus docstring for brevity):
sumber
Dunia mungkin tidak membutuhkan paket lain untuk menulis array numpy ke file PNG, tetapi bagi mereka yang tidak bisa mendapatkan cukup, saya baru-baru ini memasang
numpngw
github:https://github.com/WarrenWeckesser/numpngw
dan di pypi: https://pypi.python.org/pypi/numpngw/
Satu-satunya ketergantungan eksternal adalah numpy.
Inilah contoh pertama dari
examples
direktori repositori. Garis dasarnya sederhana sajadimana
img
array numpy. Semua kode sebelum baris itu adalah pernyataan impor dan kode untuk dibuatimg
.Inilah file PNG yang dibuatnya:
sumber
Dengan asumsi Anda menginginkan gambar skala abu-abu:
sumber
Imageio adalah perpustakaan Python yang menyediakan antarmuka yang mudah untuk membaca dan menulis berbagai data gambar, termasuk gambar animasi, video, data volumetrik, dan format ilmiah. Ini adalah lintas-platform, berjalan pada Python 2.7 dan 3.4+, dan mudah untuk diinstal.
Ini adalah contoh untuk gambar skala abu-abu:
sumber
Jika Anda sudah menggunakan [Py] Qt, Anda mungkin tertarik dengan qimage2ndarray . Dimulai dengan versi 1.4 (baru saja dirilis), PySide didukung juga, dan akan ada
imsave(filename, array)
fungsi kecil yang mirip dengan scipy's, tetapi menggunakan Qt bukan PIL. Dengan 1.3, cukup gunakan sesuatu seperti berikut:(Keuntungan lain dari 1.4 adalah itu adalah solusi python murni, yang membuatnya lebih ringan.)
sumber
Jika Anda bekerja di lingkungan python Spyder, maka itu tidak bisa lebih mudah daripada mengklik kanan array di explorer variabel, dan kemudian pilih opsi Tampilkan Gambar.
Ini akan meminta Anda untuk menyimpan gambar ke dsik, sebagian besar dalam format PNG.
PIL library tidak diperlukan dalam hal ini.
sumber
Gunakan
cv2.imwrite
.sumber
untuk menyimpan array numpy sebagai gambar, U punya beberapa pilihan:
1) terbaik dari yang lain: OpenCV
2) Matplotlib
3) PIL
4) ...
sumber