سؤال

حسنا، أنا بحاجة مع تحويل كائن صورة PIL ذهابا وإيابا إلى صفيف Numpy حتى أتمكن من القيام ببعض البكسل بشكل أسرع بواسطة تحويلات بكسل من Pil PixelAccess سوف يسمح الكائن. لقد اكتشفت كيفية وضع معلومات البكسل في صفيف Numpy 3D مفيدة عن طريق:

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

لكنني لا يبدو لي أن معرفة كيفية تحميلها مرة أخرى في كائن PIS بعد أن قمت بتحويلاتي رهيبة. أنا على علم putdata() الطريقة، ولكن لا يمكن أن يبدو أن تحصل عليه أن تتصرف.

هل كانت مفيدة؟

المحلول

أنت لا تقول كيف بالضبط 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 تتوقع سلسلة من tuples وأنت تعطيها صفيف numpy. هذه

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

سوف تعمل ولكنها بطيئة جدا.

اعتبارا من pil 1.1.6، طريقة "مناسبة" للتحويل بين الصور وصفوفات Numpy هو ببساطة

>>> pix = numpy.array(pic)

على الرغم من أن الصفيف الناتج هو بتنسيق مختلف عنك (صفيف 3-D أو صفوف / أعمدة / RGB في هذه الحالة).

بعد ذلك، بعد إجراء تغييراتك على الصفيف، يجب أن تكون قادرا على القيام بذلك pic.putdata(pix) أو إنشاء صورة جديدة مع Image.fromarray(pix).

نصائح أخرى

افتح I كصفيف:

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

تفعل بعض الأشياء ل I, ، ثم، قم بتحويله إلى صورة:

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

تصفية الصور Numpy مع FFT، Python

إذا كنت ترغب في القيام بذلك بشكل صريح لسبب ما، فهناك وظائف Pils2array () و Array2pil () باستخدام GetData () هذه الصفحة في الارتباط.zip.

أنا أستخدم وسادة 4.1.1 (خليفة PIL) في بيثون 3.5. التحويل بين الوسادة والحنمة واضحة.

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 هو العمود الرئيسية بينما نمط numpy im2arr هو الصف الرئيسي. ومع ذلك، وظيفة Image.fromarray يأخذ بالفعل هذا في الاعتبار. إنه، arr2im.size == im.size و arr2im.mode == im.mode في المثال أعلاه.

يجب أن نعتني بتنسيق بيانات HXWXC عند معالجة صفيفات Numpy المحولة، على سبيل المثال im2arr = np.rollaxis(im2arr, 2, 0) أو im2arr = np.transpose(im2arr, (2, 0, 1)) في شكل cxhxw.

تحتاج إلى تحويل صورتك إلى صفيف Numpy بهذه الطريقة:

import numpy
import PIL

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

المثال، لقد استخدمت اليوم:

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)

إذا تم تخزين صورتك بتنسيق Blob (أي في قاعدة بيانات)، فيمكنك استخدام نفس التقنية الموضحة بواسطة Billal Begueradj لتحويل صورتك من النقط إلى صفيف بايت.

في حالتي، كنت بحاجة إلى صوري حيث يتم تخزينها في عمود Blob في جدول 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

بعد ذلك، كنت قادرا على استخدام Bytearrays في شبكتي العصبية.

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

يمكنك تحويل الصورة إلى Numpy عن طريق تحليل الصورة في وظيفة Numpy () بعد تسكيف الميزات (غير الحظرية)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top