Mam macierz w rodzaju tablicy Numpy. Jak mam zapisać go na dysku jako obraz? Dowolny format działa (png, jpeg, bmp ...). Jednym ważnym ograniczeniem jest brak PIL.
Chciałbym tylko zauważyć, że niektóre z poniższych odpowiedzi, a na pewno niektórzy ludzie, którzy przychodzą i szukają tego pytania, nie spełniają powyższego ograniczenia bycia bez PIL . Ponieważ niektórzy pytający i niektóre odpowiedzi unikają tego ograniczenia, zachęcam każdego, kto tu jest i nie przeszkadza, że PIL zajrzy poniżej, i wszelkie odpowiedzi inne niż PIL (nowe lub stare), aby wspomnieć, że są używane PIL rodzaj odpowiedzi, aby odróżnić się od odpowiedzi spełniających pierwotne ograniczenie.
Możesz użyć PyPNG . Jest to czysty koder / dekoder PNG typu open source w języku Python (bez zależności) i obsługuje zapisywanie tablic NumPy jako obrazy.
Pamiętaj, aby przeskalować wartości do odpowiedniego zakresu dla PNG, zwykle 0..255. Zakresy wartości w sieciach neuronowych wynoszą często 0..1 lub -1..1.
Tomáš Gavenčiak
8
PyPNG jest czystym Pythonem, co zmniejsza jego zewnętrzne zależności, ale czyni go znacznie wolniejszym niż PIL i jego pochodne klasy. Na przykład zapisanie obrazu 3000x4000 na moim komputerze zajęło 4,05 sekundy z PyPNG, ale tylko 0,59 sekundy z scipy.misc.imsave (6x szybciej).
Zvika
@ TomášGavenčiak - scipy.misc.imsave jest już nieaktualny w nowszych wersjach Scipy. Alternatywą dla kilku komentarzy poniżej jest użycie imageio.imwrite ('image_file.jpg', tablica)
EDYCJA : Obecna scipywersja zaczęła normalizować wszystkie obrazy, dzięki czemu min (dane) stają się czarne, a maks. (Dane) stają się białe. Jest to niepożądane, jeśli dane powinny mieć dokładny poziom szarości lub dokładne kanały RGB. Rozwiązanie:
imsave mieszka w ... / scipy / misc / pilutil.py który wykorzystuje PIL
Denis
5
Zachowaj ostrożność podczas konwersji do formatu jpg, ponieważ jest on stratny i dlatego możesz nie być w stanie odzyskać dokładnych danych użytych do wygenerowania obrazu.
Feanil,
8
To jest teraz przestarzałe w przypadku użycia scipy 0.19 - scipy.io.imwrite
g.stevo
6
„Imsave jest przestarzałe w SciPy 1.0.0 i zostanie usunięte w 1.2.0” ( dokument Scipy 1.1.0 )
noobar
15
scipy.misc.imsave jest przestarzały. użyj importu imageio; imageio.imwrite ('nazwa_pliku.jpg', nmupy_array)
ChaosPredictor
228
Odpowiedź za pomocą PIL (na wypadek, gdyby była przydatna).
biorąc pod uwagę tablicę numpy „A”:
from PIL importImage
im =Image.fromarray(A)
im.save("your_file.jpeg")
możesz zamienić „jpeg” na prawie dowolny format. Więcej informacji o formatach tutaj
Działa z matplotlib 1.3.1, nie wiem o niższej wersji. Z dokumentacji:
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.
@HughPerkins wypróbuj Pillow jako zamiennik PIL w Pythonie 3
christianbrodbeck
10
import matplotlib.pyplot as plta następnieplt.imsave('name.png', array)
Alessandro Jacopson,
61
Czysty Python (2 i 3), fragment bez zależności stron trzecich.
Ta funkcja zapisuje skompresowane RGBApliki PNG o rzeczywistych kolorach (4 bajty na 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'')])
... Dane powinny być zapisane bezpośrednio do pliku otwartego jako plik binarny, jak w:
data = write_png(buf,64,64)with open("my_image.png",'wb')as fh:
fh.write(data)
To wydaje się być dokładnie tym, czego szukam, ale czy mógłbyś dodać jakieś komentarze? Nie widzę, jak to zapisuje do pliku. Czy musisz zapisać dane wyjściowe we wcześniej otwartym pliku? Dzięki!
PhilMacKay
1
@PhilMacKay, dane muszą zostać zapisane w pliku binarnym. dodany komentarz.
ideasman42
1
Czy ktoś może określić, w jakim formacie bufma być image ( )? Nie wydaje się być tablicą numeryczną ...
Dlaczego tablica o rozmiarze 10? Co doprowadziło do wyboru 10 zastosowanych w tym rozwiązaniu?
Gathide,
3
@Gathide Tylko jako przykład zapisania jakiejkolwiek dowolnej macierzy liczbowej do pliku. W prawdziwym życiu zastąp np.zeros((10,10))je swoim wizerunkiem.
Xocoatzin,
5
Jak mogę dodać coś takiego, cmap="gray"kiedy zapisuję obraz za pomocą CV2?
Mona Jalal,
@Xocoatzin Uszkodzony link?
jtlz2,
1
@ jtlz2 Zaktualizowano link.
Xocoatzin,
30
Jeśli masz matplotlib, możesz:
import matplotlib.pyplot as plt
plt.imshow(matrix)#Needs to be in row,col order
plt.savefig(filename)
Spowoduje to zapisanie fabuły (a nie samych obrazów).
Nie, w przypadku interfejsu pyplot plt.figure () jest zbędny. Ponadto potrzebujesz tylko plt.show (), jeśli chcesz zobaczyć okno figury - w tym przypadku pożądane było tylko zapisanie pliku obrazu, więc nie było potrzeby wywoływania show ().
DopplerShift
7
Zauważ, że wynikowy plik obrazu będzie zawierał osie i szary obszar figury matlplotlib - nie tylko dane pikseli.
Dave
1
nie będzie działać, jeśli uruchomisz skrypt na zdalnym hoście, ssh-to na nim bez obsługi interfejsu graficznego.
Temak,
Jeśli chcesz pokazać obraz w notatniku, możesz dodać: >> „z IPython.display import Image”, a następnie >> „Image (nazwa pliku = nazwa pliku)”
Robert
Aby usunąć oś:plt.axis('off')
yakout
15
Możesz używać biblioteki „skimage” w Pythonie
Przykład:
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()
Dla tych, którzy szukają bezpośredniego w pełni działającego przykładu:
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
także, jeśli chcesz wysokiej jakości JPEG .save(file, subsampling=0, quality=100)
matplotlib svn ma nową funkcję zapisywania obrazów jako obrazów - bez osi itp. jest to również bardzo prosta funkcja do backportowania, jeśli nie chcesz instalować svn (skopiowane bezpośrednio z image.py w matplotlib svn, usunęliśmy dokumentacja zwięzłości):
Świat prawdopodobnie nie potrzebuje jeszcze jednego pakietu do zapisania tablicy numpy do pliku PNG, ale dla tych, którzy nie mogą dostać dość, niedawno zdecydowałem się numpngwna github:
Oto pierwszy przykład z exampleskatalogu repozytorium. Zasadnicza linia jest po prostu
write_png('example1.png', img)
gdzie imgjest tablica numpy. Cały kod przed tym wierszem to instrukcje importu i kod do utworzenia 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)
Jestem ciekawy, czym twoja lib różni się od innych? Czy to jest szybsze? Czy ma fantazyjne funkcje?
F Lekschas,
Kilka funkcji: (1) Wykorzystuje tablice numpy. (2) Jest napisany przy użyciu tylko Pythona i Numpy, więc nie wymaga instalacji biblioteki C. (3) Może tworzyć animowane pliki PNG. (4) Zapewnia klasę do pisania animacji matplotlib jako animowanych plików PNG.
Warren Weckesser
Dzięki! Byłbym ciekawy, jak wypada w porównaniu z stackoverflow.com/a/19174800/981933 pod względem wydajności, która jest również czystym pythonem. Pierwsza metoda jest ponad 2x szybsza niż PIL, co jest całkiem niesamowite. Nieważne, czy to nie jest twój cel :)
F Lekschas
2
Zakładając, że chcesz mieć obraz w skali szarości:
im =Image.new('L',(width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
Imageio to biblioteka Python, która zapewnia łatwy interfejs do odczytu i zapisu szerokiej gamy danych obrazu, w tym obrazów animowanych, wideo, danych wolumetrycznych i formatów naukowych. Jest wieloplatformowy, działa w Pythonie 2.7 i 3.4+ i jest łatwy w instalacji.
Oto przykład obrazu w skali szarości:
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)
Jeśli zdarzyło Ci się już używać [Py] Qt, możesz zainteresować się qimage2ndarray . Począwszy od wersji 1.4 (właśnie wydanej), PySide jest również obsługiwany, i będzie mała imsave(filename, array)funkcja podobna do scipy's, ale wykorzystująca Qt zamiast PIL. W wersji 1.3 po prostu użyj czegoś takiego:
qImage = array2qimage(image, normalize =False)# create QImage from ndarray
success = qImage.save(filename)# use Qt's image IO functions for saving PNG/JPG/..
(Kolejną zaletą 1.4 jest to, że jest to rozwiązanie czysto pythonowe, co czyni go jeszcze bardziej lekkim.)
Wersja 1.4 jest już dostępna. :-) (odpowiednio zredagowałem odpowiedź).
hans_meine,
1
Jeśli pracujesz w środowisku Spyder w języku Python, nie może to być łatwiejsze niż kliknięcie tablicy prawym przyciskiem myszy w eksploratorze zmiennych, a następnie wybranie opcji Pokaż obraz.
To poprosi o zapisanie obrazu do dsik, głównie w formacie PNG.
W tym przypadku biblioteka PIL nie będzie potrzebna.
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
Odpowiedzi:
Możesz użyć PyPNG . Jest to czysty koder / dekoder PNG typu open source w języku Python (bez zależności) i obsługuje zapisywanie tablic NumPy jako obrazy.
źródło
Używa PIL, ale może niektórzy mogą się przydać:
EDYCJA : Obecna
scipy
wersja zaczęła normalizować wszystkie obrazy, dzięki czemu min (dane) stają się czarne, a maks. (Dane) stają się białe. Jest to niepożądane, jeśli dane powinny mieć dokładny poziom szarości lub dokładne kanały RGB. Rozwiązanie:źródło
Odpowiedź za pomocą PIL (na wypadek, gdyby była przydatna).
biorąc pod uwagę tablicę numpy „A”:
możesz zamienić „jpeg” na prawie dowolny format. Więcej informacji o formatach tutaj
źródło
from PIL import Image
to wyjaśnić ...Z
matplotlib
:Działa z matplotlib 1.3.1, nie wiem o niższej wersji. Z dokumentacji:
źródło
matplotlib.pyplot.imsave
w Matplotlib 2+import matplotlib.pyplot as plt
a następnieplt.imsave('name.png', array)
Czysty Python (2 i 3), fragment bez zależności stron trzecich.
Ta funkcja zapisuje skompresowane
RGBA
pliki PNG o rzeczywistych kolorach (4 bajty na piksel) .... Dane powinny być zapisane bezpośrednio do pliku otwartego jako plik binarny, jak w:
źródło
buf
ma być image ( )? Nie wydaje się być tablicą numeryczną ...Jest
opencv
dla Pythona ( tutaj dokumentacja ).przydatne, jeśli chcesz wykonać więcej przetwarzania niż zapisywanie.
źródło
np.zeros((10,10))
je swoim wizerunkiem.cmap="gray"
kiedy zapisuję obraz za pomocą CV2?Jeśli masz matplotlib, możesz:
Spowoduje to zapisanie fabuły (a nie samych obrazów).
źródło
plt.axis('off')
Możesz używać biblioteki „skimage” w Pythonie
Przykład:
źródło
scipy.misc
wyświetla przestarzałe ostrzeżenie oimsave
funkcji i sugeruje użycieimageio
zamiast niego.źródło
Dodatek do odpowiedzi @ ideasman42:
Możesz więc zrobić:
Produkcja
test_grid.png
:(Przejrzystość działa również poprzez zmniejszenie wysokiego bajtu od
0xff
.)źródło
Dla tych, którzy szukają bezpośredniego w pełni działającego przykładu:
także, jeśli chcesz wysokiej jakości JPEG
.save(file, subsampling=0, quality=100)
źródło
matplotlib svn ma nową funkcję zapisywania obrazów jako obrazów - bez osi itp. jest to również bardzo prosta funkcja do backportowania, jeśli nie chcesz instalować svn (skopiowane bezpośrednio z image.py w matplotlib svn, usunęliśmy dokumentacja zwięzłości):
źródło
Świat prawdopodobnie nie potrzebuje jeszcze jednego pakietu do zapisania tablicy numpy do pliku PNG, ale dla tych, którzy nie mogą dostać dość, niedawno zdecydowałem się
numpngw
na github:https://github.com/WarrenWeckesser/numpngw
i na pypi: https://pypi.python.org/pypi/numpngw/
Jedyną zależnością zewnętrzną jest numpy.
Oto pierwszy przykład z
examples
katalogu repozytorium. Zasadnicza linia jest po prostugdzie
img
jest tablica numpy. Cały kod przed tym wierszem to instrukcje importu i kod do utworzeniaimg
.Oto plik PNG, który tworzy:
źródło
Zakładając, że chcesz mieć obraz w skali szarości:
źródło
Imageio to biblioteka Python, która zapewnia łatwy interfejs do odczytu i zapisu szerokiej gamy danych obrazu, w tym obrazów animowanych, wideo, danych wolumetrycznych i formatów naukowych. Jest wieloplatformowy, działa w Pythonie 2.7 i 3.4+ i jest łatwy w instalacji.
Oto przykład obrazu w skali szarości:
źródło
Jeśli zdarzyło Ci się już używać [Py] Qt, możesz zainteresować się qimage2ndarray . Począwszy od wersji 1.4 (właśnie wydanej), PySide jest również obsługiwany, i będzie mała
imsave(filename, array)
funkcja podobna do scipy's, ale wykorzystująca Qt zamiast PIL. W wersji 1.3 po prostu użyj czegoś takiego:(Kolejną zaletą 1.4 jest to, że jest to rozwiązanie czysto pythonowe, co czyni go jeszcze bardziej lekkim.)
źródło
Jeśli pracujesz w środowisku Spyder w języku Python, nie może to być łatwiejsze niż kliknięcie tablicy prawym przyciskiem myszy w eksploratorze zmiennych, a następnie wybranie opcji Pokaż obraz.
To poprosi o zapisanie obrazu do dsik, głównie w formacie PNG.
W tym przypadku biblioteka PIL nie będzie potrzebna.
źródło
Zastosowanie
cv2.imwrite
.źródło
do zapisywania tablicy numpy jako obrazu, masz kilka możliwości:
1) najlepsze z innych: OpenCV
2) Matplotlib
3) PIL
4) ...
źródło