एक छवि के रूप में एक Numpy सरणी को सहेजना


260

मेरे पास एक Numpy सरणी के प्रकार में एक मैट्रिक्स है। मैं इसे एक छवि के रूप में डिस्क करने के लिए कैसे लिखूंगा? कोई भी प्रारूप काम करता है (png, jpeg, bmp ...)। एक महत्वपूर्ण बाधा यह है कि पीआईएल मौजूद नहीं है।


12
मैं केवल यह ध्यान रखना चाहता हूं कि नीचे दिए गए कुछ उत्तर, और निश्चित रूप से कुछ लोग जो इस सवाल को लेकर आ रहे हैं और इस सवाल का पता लगा रहे हैं, वे PIL के बिना होने के ऊपर सूचीबद्ध बाधा को पूरा नहीं करते हैं । चूँकि कुछ पूछने वाले और कुछ जवाब देने वाले दोनों उस बाधा से बचते हैं, मैं किसी को भी प्रोत्साहित करता हूँ जो यहाँ नहीं है और नीचे देखने के लिए पीआईएल का मन नहीं करता है, और किसी भी गैर-पीआईएल उत्तर (नए या पुराने) का उल्लेख करने के लिए कि वे एक पीआईएल-उपयोग हैं उत्तर का प्रकार, मूल बाधा से मिलने वाले उत्तरों से खुद को अलग करने के लिए।
lindes

लगता है संबंधित: stackoverflow.com/questions/33480297/viewing-npy-images
xxx ---

जवाबों:


54

आप PyPNG का उपयोग कर सकते हैं । यह एक शुद्ध पायथन (कोई निर्भरता नहीं) खुला स्रोत PNG एनकोडर / डिकोडर है और यह इमेज के रूप में NumPy सरणियों को लिखने का समर्थन करता है


4
पीएनजी के लिए मानों को सही सीमा में स्केल करना याद रखें, आमतौर पर 0..255। तंत्रिका नेटवर्क में मूल्य सीमाएं अक्सर 0..1 या -1..1 होती हैं।
टॉम गैविएक

8
PyPNG शुद्ध पायथन है, जो इसकी बाहरी निर्भरता को कम करता है, लेकिन यह PIL और इसके व्युत्पन्न वर्गों की तुलना में बहुत धीमा बनाता है। उदाहरण के लिए, मेरी मशीन पर 3000x4000 की छवि को सहेजने में PyPNG के साथ 4.05 सेकंड का समय लगा, लेकिन scipy.misc.imsave (6x तेज़) के साथ केवल 0.59 सेकंड।
झ्विका

@ TomášGavenčiak - scipy.misc.imsave अब Scipy के नए संस्करणों में पदावनत किया गया है। नीचे कुछ टिप्पणियों के लिए एक विकल्प है imageio.imwrite ('image_file.jpg', सरणी) का उपयोग करना
Psi-Ed

258

यह पीआईएल का उपयोग करता है, लेकिन हो सकता है कि कुछ को यह उपयोगी लगे:

import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)

EDIT : वर्तमान scipyसंस्करण ने सभी छवियों को सामान्य करना शुरू कर दिया ताकि मिनट (डेटा) काला हो जाए और अधिकतम (डेटा) सफेद हो जाए। यह अवांछित है यदि डेटा सटीक ग्रे स्तर या सटीक RGB चैनल होना चाहिए। समाधान:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')

19
imsave में रहता है ... / scipy / misc / pilutil.py जो PIL का उपयोग करता है
denis

5
जब यह हानिपूर्ण हो जाए तो jpg में कनवर्ट करते समय सावधान रहें और इसलिए आप छवि बनाने के लिए उपयोग किए गए सटीक डेटा को पुनर्प्राप्त नहीं कर पाएंगे।
फेनिल

8
यह अब scipy 0.19 उपयोग में लिया गया है - scipy.io.imwrite
g.stevo

6
"imsave SciPy 1.0.0 में पदावनत है, और 1.2.0 में हटा दिया जाएगा" (
Scipy

15
scipy.misc.imsave पदावनत है। आयात छवि का उपयोग करें; imageio.imwrite ('file_name.jpg', nmupy_array)
ChaosPredictor

228

PIL का उपयोग कर एक उत्तर (बस मामले में यह उपयोगी है)।

"ए" को एक सुव्यवस्थित सारणी दी गई है:

from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")

आप "जेपीईजी" को अपने इच्छित किसी भी प्रारूप से बदल सकते हैं। यहाँ स्वरूपों के बारे में अधिक जानकारी


5
चित्र पीआईएल का एक मॉड्यूल है। "प्रिंट इमेज .__ file__" करें
Juh_

10
हममें से बहुत से लोग जो यहां-वहां भटकते हैं और पीआईएल करते हैं - मुझे लगता है कि मैं from PIL import Imageइसे स्पष्ट रखने के लिए उपयोग करूंगा ...
ऋषि

4
यदि आपको RGB छवि मिली है, तो आप im = Image.fromarray (A) .convert ('RGB') का उपयोग करके चित्र प्राप्त कर सकते हैं: अधिक जानकारी: stackoverflow.com/questions/4711880/…
रोजर वेकियाना 1

इस विधि के साथ RGB काम करने के लिए uint8 के एक सरणी के तीसरे अक्ष का उपयोग करना। मॉड्यूल पीआईएल "पाइप इंस्टॉल तकिया" का उपयोग करके स्थापित किया जा सकता है।
ब्लि

1
@ लॉडोविको वर्नियानी यह छवियों को विकृत नहीं करता है, लेकिन यह कुछ हद तक असामान्य रंग एन्कोडिंग का उपयोग करता है जिसमें रंगों का क्रम आरजीबी के बजाय बीजीआर है।
ज़्विका

87

के साथ matplotlib:

import matplotlib

matplotlib.image.imsave('name.png', array)

Matplotlib 1.3.1 के साथ काम करता है, मुझे कम संस्करण के बारे में पता नहीं है। डॉकस्ट्रिंग से:

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.

यहां छवि विवरण दर्ज करें


इसका उपयोग करना। लेकिन स्मृति रिसाव से पीड़ित
SolessChong

matplotlib.imsave () नए संस्करणों में
विनय लोढ़ा

6
यह matplotlib.pyplot.imsaveMatplotlib 2+ में
अलेक्सी पेट्रेंको

1
@HughPerkins कोशिश तकिया अजगर 3 में जनहित याचिका स्थानापन्न के रूप में
christianbrodbeck

10
import matplotlib.pyplot as pltऔर फिरplt.imsave('name.png', array)
एलेसेंड्रो जैकप्सन

61

शुद्ध पायथन (2 और 3), 3 पार्टी पर निर्भरता के बिना एक स्निपेट।

यह फ़ंक्शन कंप्रेस्ड, ट्रू-कलर (4 बाइट्स प्रति पिक्सेल) RGBAपीएनजी की लिखता है ।

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)


2
यह वही प्रतीत होता है जो मैं देख रहा हूं, लेकिन क्या आप कुछ टिप्पणियां जोड़ सकते हैं? मैं यह नहीं देखता कि यह फाइल में कैसे लिखता है। क्या आपको पहले से खोली गई फ़ाइल में आउटपुट लिखना है? धन्यवाद!
फिलमकैके

1
@PhilMacKay, डेटा को केवल एक बाइनरी फ़ाइल में लिखा जाना है। टिप्पणी जोड़ा गया।
विचारमेन .42

1
क्या कोई निर्दिष्ट कर सकता है कि छवि ( buf) को किस प्रारूप में होना चाहिए? यह एक महत्वपूर्ण सरणी नहीं लगती ...
क्रिश्चियनब्रोडेक

1
@christianmbrodbeck, bytearray (RGBARGBA ...)
ideasman42

1
धन्यवाद @ ideasman42 मैंने इस कोड को ब्लेंडर में उपयोग के लिए पोर्ट किया था ।
Emackey

57

नहीं है opencv(अजगर के लिए यहाँ प्रलेखन )।

import cv2
import numpy as np

cv2.imwrite("filename.png", np.zeros((10,10)))

यदि आपको बचत के अलावा अन्य प्रसंस्करण करने की आवश्यकता है तो उपयोगी है।


1
आकार 10 की सरणी क्यों? क्या इस समाधान में इस्तेमाल 10 की पसंद के लिए नेतृत्व किया?
गाथाईड

3
@Gathide फाइल करने के लिए कुछ मनमाने ढंग से मैट्रिक्स लिखने के उदाहरण के रूप में। वास्तविक जीवन np.zeros((10,10))में अपनी छवि के साथ बदलें ।
Xocoatzin

5
cmap="gray"जब मैं छवि को cv2 का उपयोग करके सहेजता हूं तो मैं कुछ कैसे जोड़ सकता हूं ?
मोना जलाल

@Xocoatzin टूटी हुई कड़ी?
jtlz2

1
@ jtlz2 अपडेटेड लिंक।
Xocoatzin

30

यदि आपके पास माटाप्लोटिब है, तो आप कर सकते हैं:

import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)

यह भूखंड को बचाएगा (न कि स्वयं चित्र)। यहां छवि विवरण दर्ज करें


10
नहीं, pyplot इंटरफ़ेस के लिए, plt.figure () शानदार है। इसके अलावा, आपको केवल plt.show () की आवश्यकता है यदि आप एक आकृति विंडो भी देखना चाहते हैं - इस मामले में केवल एक छवि फ़ाइल को सहेजना वांछित था, इसलिए शो () को कॉल करने की आवश्यकता नहीं थी।
डॉप्लरशिफ्ट

7
ध्यान दें कि परिणामी छवि फ़ाइल में मैटलप्लोटलिब आकृति के अक्ष और ग्रे क्षेत्र होंगे - न कि केवल पिक्सेल डेटा।
डेव

1
काम नहीं करेगा यदि आप स्क्रिप्ट को दूरस्थ होस्ट पर चलाते हैं, तो ssh-ing इसे बिना ग्राफ़िकल इंटरफ़ेस समर्थन के।
तैराक

यदि आप एक नोटबुक में छवि दिखाना चाहते हैं, तो आप निम्नलिखित जोड़ सकते हैं: >> "IPython.display आयात छवि से" और फिर >> "छवि (फ़ाइल नाम = फ़ाइल नाम)"
रॉबर्ट

धुरी को हटाने के लिए:plt.axis('off')
yakout

15

आप पायथन में 'स्किमेज' लाइब्रेरी का उपयोग कर सकते हैं

उदाहरण:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)

15

scipy.miscimsaveफ़ंक्शन के बारे में पदावनति की चेतावनी देता है और imageioइसके बजाय उपयोग का सुझाव देता है ।

import imageio
imageio.imwrite('image_name.png', img)

12

Addendum @ @ 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।)


8

प्रत्यक्ष प्रत्यक्ष काम करने वाले उदाहरण की तलाश करने वालों के लिए:

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)


6

matplotlib svn के पास छवियों को बचाने के लिए एक नया फ़ंक्शन है - कोई कुल्हाड़ी आदि नहीं। यह बैकपोर्ट के लिए भी एक बहुत ही सरल कार्य है, यदि आप svn को स्थापित नहीं करना चाहते हैं (matplotlib svn में image.py से सीधे कॉपी किया गया, हटा दिया गया) संक्षिप्तता के लिए 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)

3

दुनिया को शायद PNG फ़ाइल के लिए एक शानदार सरणी लिखने के लिए किसी अन्य पैकेज की आवश्यकता नहीं है, लेकिन उन लोगों के लिए जो पर्याप्त नहीं प्राप्त कर सकते हैं, मैंने हाल ही में जीथब numpngwपर रखा है :

https://github.com/WarrenWeckesser/numpngw

और pypi पर: https://pypi.python.org/pypi/numpngw/

केवल बाहरी निर्भरता सुन्न है।

यहां examplesरिपॉजिटरी की निर्देशिका से पहला उदाहरण दिया गया है। आवश्यक लाइन बस है

write_png('example1.png', img)

जहां imgएक सुन्न सरणी है। उस लाइन से पहले का सभी कोड आयात स्टेटमेंट और बनाने के लिए कोड होता है 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 फ़ाइल है जो इसे बनाता है:

example1.png


मैं जिज्ञासु हूं, आपका दायित्व दूसरों से अलग कैसे है? क्या यह तेज है? क्या इसमें फैंसी विशेषताएं हैं?
F Lekschas

कुछ विशेषताएं: (1) यह सुन्न सरणियों का उपयोग करता है। (2) यह सिर्फ अजगर और सुन्न का उपयोग करके लिखा गया है, इसलिए इसे स्थापित करने के लिए सी लाइब्रेरी की आवश्यकता नहीं है। (3) यह एनिमेटेड पीएनजी फाइलें बना सकता है। (4) यह एनिमेटेड PNG फ़ाइलों के रूप में matplotlib एनिमेशन लिखने के लिए एक वर्ग प्रदान करता है।
वॉरेन वीकेसर

धन्यवाद! मुझे उत्सुकता होगी कि यह प्रदर्शन के मामले में stackoverflow.com/a/19174800/981933 से तुलना कैसे करता है जो शुद्ध अजगर भी है। पूर्व विधि पीआईएल की तुलना में 2 गुना अधिक तेज है, जो कि बहुत बढ़िया है। अगर आपका लक्ष्य नहीं है तो कुछ भी न करें :)
F Lekschas


2

Imageio एक 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)

1

यदि आप पहले से ही [Py] Qt का उपयोग करते हैं, तो आप qimage2ndarray में रुचि ले सकते हैं । संस्करण 1.4 (अभी जारी) के साथ, PySide के रूप में अच्छी तरह से समर्थित है, और imsave(filename, array)scipy के समान एक छोटे से कार्य होगा , लेकिन PIL के बजाय Qt का उपयोग करना। 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 का एक अन्य लाभ यह है कि यह एक शुद्ध अजगर समाधान है, जो इसे और भी हल्का बनाता है।)


1.4 रिलीज अब बाहर है। :-) (मैंने तदनुसार उत्तर संपादित किया।)
hans_meine

1

यदि आप अजगर पर्यावरण स्पाइडर में काम कर रहे हैं, तो यह केवल चर एक्सप्लोरर में सरणी पर राइट क्लिक करने से ज्यादा आसान नहीं हो सकता है, और फिर शो इमेज विकल्प चुनें।

यहां छवि विवरण दर्ज करें

यह आपको dsik में इमेज सेव करने के लिए कहेगा, ज्यादातर PNG फॉर्मेट में।

इस मामले में पीआईएल लाइब्रेरी की जरूरत नहीं होगी।


1

का उपयोग करें 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  

0

छवि के रूप में एक सुदूर सरणी को बचाने के लिए, यू के पास कई विकल्प हैं:

1) अन्य का सबसे अच्छा: OpenCV

 import cv2   
 cv2.imwrite('file name with extension(like .jpg)', numpy_array)

2) माटपोटलिब

  from matplotlib import pyplot as plt
  plt.imsave('file name with extension(like .jpg)', numpy_array)

3) पीआईएल

  from PIL import Image
  image = Image.fromarray(numpy_array)
  image.save('file name with extension(like .jpg)')

4) ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.