PIL इमेज को एक सुपीरियर एरे में कैसे बदलें?


257

ठीक है, मैं एक पीआईएल छवि ऑब्जेक्ट को आगे और पीछे एक संख्यात्मक सरणी में परिवर्तित करने के साथ कर रहा हूं ताकि मैं पीआईएल की PixelAccessवस्तु की तुलना में पिक्सेल परिवर्तनों द्वारा कुछ तेज पिक्सेल कर सकूं । मुझे लगा है कि कैसे पिक्सेल जानकारी को एक उपयोगी 3 डी संख्यात्मक सरणी में रखा जा सकता है:

pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)

लेकिन मुझे यह पता नहीं लग सकता है कि मैंने अपने सभी भयानक परिवर्तनों को करने के बाद इसे पीआईएल ऑब्जेक्ट में वापस कैसे लोड किया। मैं इस putdata()विधि से वाकिफ हूं , लेकिन इसे व्यवहार में लाने के लिए काफी नहीं लग सकता।


6
ध्यान दें कि pic.size[0]और pic.size[1]बदली किया जाना चाहिए (यानी। reshape(pic.size[1], pic.size[0], 3)), के बाद से sizeहै width x heightया x * yहै, जबकि मैट्रिक्स आदेश है rows x columns
कोहरे

जवाबों:


286

आप यह नहीं कह रहे हैं कि वास्तव putdata()में कैसा व्यवहार नहीं है। मैं मान रहा हूँ आप कर रहे हैं

>>> pic.putdata(a)
Traceback (most recent call last):
  File "...blablabla.../PIL/Image.py", line 1185, in putdata
    self.im.putdata(data, scale, offset)
SystemError: new style getargs format but argument is not a tuple

ऐसा इसलिए है क्योंकि putdataटुपल्स के एक अनुक्रम की उम्मीद है और आप इसे एक सुस्पष्ट सरणी दे रहे हैं। यह

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

काम करेगा लेकिन यह बहुत धीमा है।

पीआईएल 1.1.6 के अनुसार, छवियों और संख्यात्मक सरणियों के बीच परिवर्तित करने का "उचित" तरीका बस है

>>> pix = numpy.array(pic)

हालाँकि परिणामी सरणी आपके (इस मामले में 3-d सरणी या पंक्तियों / स्तंभों / आरजीबी) से भिन्न प्रारूप में है।

फिर, आप सरणी में अपने परिवर्तन करने के बाद, आपको pic.putdata(pix)या तो करने में सक्षम होना चाहिए या एक नई छवि बनाना चाहिए Image.fromarray(pix)


2
सबसे पहले, यह pic.putdata (डेटा) नहीं होना चाहिए? और numpy.asarray (pic) एक आसानी से सरणी का उत्पादन करता है, इसलिए आपको numpy.array (pic) को कॉल करने की आवश्यकता है, और आपने प्रश्न का उत्तर नहीं दिया ... आपके द्वारा दिए गए लिंक से यह pic = Image.fromarray (प्रतीत होता है) pix)। अपना उत्तर ठीक करें और मैं इसे स्वीकार करूंगा।
एक्यूडम

2
इसके लिए धन्यवाद ... Image.fromarrayपीआईएल प्रलेखन (!) में सूचीबद्ध नहीं है, इसलिए मैंने इसे कभी नहीं पाया अगर यह इसके लिए नहीं था।
नाथन रीड

13
उस पृष्ठ numpy.asarray(pic)को रूपांतरित करने के "उचित" तरीके के रूप में सूचीबद्ध किया गया है, नहीं numpy.array(pic)इस उत्तर के अनुसार arrayएक प्रति बनाएगी जबकि asarrayनहीं (लेकिन फिर asarrayपरिणाम केवल-केवल पढ़ा जाएगा)।
आर्थर टाका

1
यहां एक चेतावनी (मेरी अपनी गलती से): आपको डेटा के पैमाने और सीमाओं पर भी विचार करने की आवश्यकता है। कई usecases में आप 0-255 बाइट्स के साथ छवियां प्रस्तुत करेंगे, लेकिन आप उम्मीद कर सकते हैं कि ये उदाहरण के लिए 0.0-1.0 के लिए परिवर्तित हो जाएं। Uint8 से कुछ यूनिट रूपांतरण ऐसा करते हैं, लेकिन इस मामले में, यह नहीं है .. इसलिए इसे जांचें :)
BjornW

दूसरा उत्तर बेहतर है।
नाथन

193

Iएक सरणी के रूप में खोलें :

>>> I = numpy.asarray(PIL.Image.open('test.jpg'))

कुछ सामान करें I, फिर उसे एक छवि में बदलें:

>>> im = PIL.Image.fromarray(numpy.uint8(I))

एफएफटी, पायथन के साथ संख्यात्मक छवियों को फ़िल्टर करें

यदि आप इसे किसी कारण से स्पष्ट रूप से करना चाहते हैं, तो इस पृष्ठ पर पाइलटैरे () और एरे २ पिल () फ़ंक्शंस का उपयोग कर रहे हैं। सहसंबंध में ।


2
@ArditS .: क्या आपने import Imageपहले? क्या आपके पास पीआईएल स्थापित है?
एंडोलिथ

5
क्या uint8रूपांतरण आवश्यक है?
नील ट्राफ

4
numpy.asarray(Image.open(filename)).jpg छवियों के लिए काम करने लगता है लेकिन .png के लिए नहीं। परिणाम के रूप में प्रदर्शित करता है array(<PngImagePlugin.PngImageFile image mode=LA size=500x500 at 0x3468198>, dtype=object)PngImagePlugin.PngImageFileइसे हल करने के लिए वस्तु के स्पष्ट रूप से नामित तरीके प्रतीत नहीं होते हैं । मुझे लगता है कि मुझे यह एक नया सवाल पूछना चाहिए लेकिन यह इस धागे के लिए बहुत प्रासंगिक है। किसी को भी समझ में आ रहा है कि यहाँ क्या गलत हो रहा है?
jez

3
@Rebs: यहाँ कारण यह है कि यह बहुत तेज़ है: getdata()ऑब्जेक्ट की तरह एक अनुक्रम लौटाता है ( pillow.readthedocs.io/en/3.4.x/reference/… ), लेकिन एक तकिया छवि लागू होती है __array_interface__जिसका numpyउपयोग कच्ची बाइट्स तक पहुँचने के लिए कर सकते हैं एक इमेजर के बिना एक इटरेटर से गुजरने के लिए (देखें github.com/python-pillow/Pillow/blob/… और docs.scipy.org/doc/numpy/reference/arrays.inrface.html )। तुम भी बस का उपयोग कर सकते हैंnumpy.array(PIL.Image.open('test.jpg'))
tdp2110

3
@ जाज जाँचें कि क्या छवि ऑब्जेक्ट बंद होने से पहले आपको इसे बदलने के लिए है। मेरे साथ भी ऐसा ही हुआ और मैंने पाया कि मैंने इमेज ऑब्जेक्ट को कहीं बंद कर दिया है।
शौहु ली

65

मैं पायथन 3.5 में पिलो 4.1.1 (पीआईएल का उत्तराधिकारी) का उपयोग कर रहा हूं। तकिया और सुन्न के बीच रूपांतरण सीधा है।

from PIL import Image
import numpy as np
im = Image.open('1.jpg')
im2arr = np.array(im) # im2arr.shape: height x width x channel
arr2im = Image.fromarray(im2arr)

एक बात जो ध्यान देने वाली है, वह यह है कि पिलो-स्टाइल imकॉलम-मेजर है जबकि सुपी-स्टाइल im2arrरो-मेजर है। हालांकि, फ़ंक्शन Image.fromarrayपहले से ही इसे ध्यान में रखता है। वह है, arr2im.size == im.sizeऔरarr2im.mode == im.mode उपरोक्त उदाहरण में।

हमें ट्रांसफ़ॉर्म किए गए सुन्न सरणियों को संसाधित करते समय HxWxC डेटा प्रारूप का ध्यान रखना चाहिए, जैसे ट्रांसफ़ॉर्म im2arr = np.rollaxis(im2arr, 2, 0)या im2arr = np.transpose(im2arr, (2, 0, 1))CxHxW प्रारूप में।


2
यह सबसे साफ उदाहरण के बारे में है, जिसमें आयात विवरण (उस विस्तार के लिए धन्यवाद) शामिल है। दृश्यता बढ़ाने के लिए इस उत्तर को वोट दें।
डेविड पार्क्स

मैंने पाया कि जब मैंने पीआईएल तैयार की गई छवि को एक खस्ता सरणी में बदल दिया, तो सरणी पर matplotlib imshow का उपयोग करते हुए, इसे np.flipudठीक करने के लिए उल्टा दिखाया । यद्यपि मेरी पीआईएल छवि का उपयोग खरोंच से किया गया था ImageDraw.Draw। मुझे लगता है कि किसी को सावधान रहना चाहिए कि उनके निर्देशांक की उत्पत्ति कहां से होती है।
CMCDragonkai

तुम्हें आशीर्वाद देते हैं!! मैं आधे दिन से इस जवाब की तलाश में हूं। यह मूल छवि को मूल छवि को पुनर्स्थापित करने की मेरी समस्या को हल करता है।
टिंकरबेल

16

आपको अपनी छवि को इस तरह से एक शानदार सरणी में बदलने की आवश्यकता है:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 

रूपांतरण का यह तरीका छवि को बनाए रखता है लेकिन परिणामस्वरूप रंगों का नुकसान होता है। वैसे भी रंग के नुकसान से बचने के लिए?
मूंदड़ा

7
@moondra अगर मैं अपने प्रश्न को समझते हैं, आप की जगह ले सकता .convert("L") द्वारा.convert("RGB")
Billal Begueradj

3

उदाहरण, मैंने आज उपयोग किया है:

import PIL
import numpy
from PIL import Image

def resize_image(numpy_array_image, new_height):
    # convert nympy array image to PIL.Image
    image = Image.fromarray(numpy.uint8(numpy_array_image))
    old_width = float(image.size[0])
    old_height = float(image.size[1])
    ratio = float( new_height / old_height)
    new_width = int(old_width * ratio)
    image = image.resize((new_width, new_height), PIL.Image.ANTIALIAS)
    # convert PIL.Image into nympy array back again
    return array(image)

0

यदि आपकी छवि एक ब्लॉब प्रारूप (यानी एक डेटाबेस में) में संग्रहीत है, तो आप बिलल बेगुएरडज द्वारा बताई गई उसी तकनीक का उपयोग करके अपनी छवि को ब्लब्स से बाइट सरणी में बदल सकते हैं।

मेरे मामले में, मुझे अपनी छवियों की आवश्यकता थी जहाँ एक db तालिका में एक बूँद कॉलम में संग्रहीत किया गया था:

def select_all_X_values(conn):
    cur = conn.cursor()
    cur.execute("SELECT ImageData from PiecesTable")    
    rows = cur.fetchall()    
    return rows

फिर मैंने अपने डेटासेट को np.array में बदलने के लिए एक सहायक फ़ंक्शन बनाया:

X_dataset = select_all_X_values(conn)
imagesList = convertToByteIO(np.array(X_dataset))

def convertToByteIO(imagesArray):
    """
    # Converts an array of images into an array of Bytes
    """
    imagesList = []

    for i in range(len(imagesArray)):  
        img = Image.open(BytesIO(imagesArray[i])).convert("RGB")
        imagesList.insert(i, np.array(img))

    return imagesList

इसके बाद, मैं अपने न्यूरल नेटवर्क में बाइट्स का उपयोग करने में सक्षम था।

plt.imshow(imagesList[0])


-1
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

आप छवि को सुन्न () फ़ंक्शन में पार्स करने के बाद छवि को संख्यात्मक में बदल सकते हैं (सुविधाओं का अपव्यय)

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