50

मुझे एक साधारण समस्या है लेकिन इसका कोई अच्छा समाधान नहीं मिल रहा है।Numpy array को PIL छवि में बदलने के लिए कैसे करें matplotlib colormap

मैं एक numpy 2 डी सरणी लेना चाहता हूं जो एक ग्रेस्केल छवि का प्रतिनिधित्व करता है, और इसे matplotlib colormaps में से कुछ लागू करते समय इसे एक आरजीबी पीआईएल छवि में परिवर्तित करना चाहता है।

मैं 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 का उपयोग कर जनहित याचिका छवि प्राप्त करते हैं), मुझे आश्चर्य है कि वहाँ है अगर ऐसा करने का एक आसान तरीका नहीं है, क्योंकि यह छवि दृश्यता की एक बहुत ही प्राकृतिक समस्या प्रतीत होता है। मान लें, इस तरह कुछ:

colored_PIL_image = magic_function(array, cmap) 

पढ़ने के लिए धन्यवाद!

+0

पूरी तरह से काम करने वाले कोड के लिए, आप रेफरी कर सकते हैं: [क्या पाइथन की पीआईएल का उपयोग करके ग्रे-स्केल छवि को रंगीन लोगों में बदलने के लिए कोई अच्छा रंग नक्शा है?] (Http://stackoverflow.com/questions/43457308/is-there-any- अच्छा-रंग-नक्शा-टू-कन्वर्ट-ग्रे-स्केल-इमेज-टू-रंगीन-एक-उपयोग-पी) – Adam

उत्तर

99

काफी व्यस्त एक लाइनर, लेकिन यहाँ यह है:

  1. सबसे पहले सुनिश्चित करें कि आपकी numpy सरणी, myarray, 1.0 पर अधिकतम मूल्य के साथ सामान्यीकृत है।
  2. कोलोरैप को सीधे myarray पर लागू करें।
  3. 0-255 रेंज पर पुनर्विक्रय करें।
  4. np.uint8() का उपयोग करके पूर्णांक में कनवर्ट करें।
  5. Image.fromarray() का उपयोग करें।

और आपका काम हो गया:

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

plt.savefig() साथ:

enter image description here

im.save() साथ:

enter image description here

+4

"रंगमंच को सीधे 'मयरेरे' पर लागू करें" भाग सीधे दिल में कटौती करें! मुझे नहीं पता था कि यह संभव था, धन्यवाद! – heltonbiker

+0

@heltonbiker - हाँ, यह बहुत अच्छा है;) – fraxel

+27

LinearSegmentedColormap के बारे में दस्तावेज़ों का अध्ययन करना (जिसमें से cm.gist_earth एक उदाहरण है), मैंने पाया कि इसे "बाइट्स" तर्क के साथ कॉल करना संभव है जो पहले से ही इसे uint8 में परिवर्तित कर देता है। फिर, एक-लाइनर बहुत शांत हो जाता है: 'im = image.fromarray (cm.gist_earth (myarray, बाइट्स = ट्रू)) ' – heltonbiker