কীভাবে একটি পিআইএল চিত্রটিকে একটি ন্যালি অ্যারে রূপান্তর করবেন?


256

ঠিক আছে, আমি একটি পিআইএল ইমেজ অবজেক্টটিকে পিছনে পিছনে একটি অদ্ভুত অ্যারে রূপান্তর করে যাচ্ছি যাতে আমি পিআইএল এর PixelAccessঅবজেক্টের অনুমতি দেওয়ার চেয়ে পিক্সেল ট্রান্সফর্মেশন দিয়ে আরও দ্রুত পিক্সেল করতে পারি । আমি কীভাবে পিক্সেল তথ্যকে একটি দরকারী 3D নম্পি অ্যারে রাখার উপায় বের করেছি:

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)

কাজ করবে তবে এটি খুব ধীর।

পিআইএল ১.১..6 অনুসারে, চিত্রগুলি এবং আঙ্কুল অ্যারেগুলির মধ্যে রূপান্তর করার "যথাযথ" উপায়টি কেবল সহজ

>>> pix = numpy.array(pic)

যদিও ফলস্বরূপ অ্যারে আপনার চেয়ে আলাদা ফর্ম্যাটে রয়েছে (3-ডি অ্যারে বা সারি / কলাম / এই ক্ষেত্রে আরজিবি)।

তারপরে, অ্যারেতে আপনার পরিবর্তনগুলি করার পরে, আপনি হয় তা করতে সক্ষম হন pic.putdata(pix)বা দিয়ে একটি নতুন চিত্র তৈরি করতে সক্ষম হন Image.fromarray(pix)


2
প্রথমত, এটি পিক.পুটদাটা (ডেটা) হওয়া উচিত নয়? এবং numpy.asarray (পিক) একটি পঠনযোগ্য অ্যারে উত্পাদন করে, তাই আপনাকে numpy.array (পিক) কল করতে হবে, এবং আপনি প্রশ্নের উত্তর দিলেন না ... আপনি যে লিঙ্কটি দিয়েছিলেন সেটি থেকে ছবি = চিত্র.ফ্রোমারে হিসাবে প্রদর্শিত হচ্ছে ( , pix)। আপনার উত্তর ঠিক করুন এবং আমি এটি গ্রহণ করব।
অ্যাকডম

2
এর জন্য ধন্যবাদ ... Image.fromarrayপিআইএল ডকুমেন্টেশনে তালিকাভুক্ত নয় (!) সুতরাং এটি যদি না থাকতাম তবে আমি কখনই এটি পেতাম না।
নাথান রিড

13
এই পৃষ্ঠাটি numpy.asarray(pic)রূপান্তর করার "যথাযথ" উপায় হিসাবে তালিকাবদ্ধ করে, নয় numpy.array(pic)। অনুযায়ী এই উত্তরটি array একটি কপি যেহেতু করতে হবে asarray(কিন্তু তারপর করা হবে না asarrayশুধুমাত্র পাঠযোগ্য ফলাফলের হবে)।
আর্থার ট্যাকা

1
এখানে একটি সতর্কতা (আমার নিজের ভুল থেকে): আপনার পাশাপাশি ডেটার স্কেল এবং ব্যাপ্তিগুলিও বিবেচনা করা উচিত। অনেকগুলি ব্যবহারের ক্ষেত্রে আপনি ০-২৫৫ বাইটের সাথে চিত্রগুলি রেন্ডার করতে পারেন, তবে আপনি আশা করতে পারেন যে এগুলি রূপান্তরিত হবে উদাহরণস্বরূপ নমুনা অ্যারেতে 0.0-1.0। Uint8 থেকে কিছু ইউনিট রূপান্তরগুলি এটি করে তবে এই ক্ষেত্রে এটি তা হয় না .. তাই এটি পরীক্ষা করে দেখুন :)
BjornW

দ্বিতীয় উত্তরটি আরও ভাল।
নাথান

193

Iঅ্যারে হিসাবে খুলুন :

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

এর জন্য কিছু স্টাফ করুন I, তারপরে এটিকে কোনও চিত্রে রূপান্তর করুন:

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

এফএফটি, পাইথন দিয়ে ন্যালি চিত্রগুলি ফিল্টার করুন

আপনি যদি কিছু কারণে এটি স্পষ্টভাবে করতে চান তবে এই পৃষ্ঠায় রিলেশন.জেপ-এ getdata () ব্যবহার করে পাইল 2 ব্যয় () এবং অ্যারে 2 পিল () ফাংশন রয়েছে ।


2
@ আরডিটস: আপনি কি 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/references/arrays.interface.html দেখুন )। আপনি কেবল ব্যবহার করতে পারেনnumpy.array(PIL.Image.open('test.jpg'))
tdp2110

3
@ জেজ চেক করুন আপনি চিত্রটি অবজেক্টে রূপান্তরিত করার আগে চিত্র অবজেক্টটি বন্ধ আছে কিনা। আমার ক্ষেত্রেও একই ঘটনা ঘটেছিল এবং আমি দেখতে পেলাম যে কোথাও আমি চিত্রটির অবজেক্টটি বন্ধ করে দিয়েছি।
শাহুয়া লি

64

আমি পাইথন ৪.৩.৪ তে বালিশ ৪.১.১ (পিআইএল এর উত্তরসূরী) ব্যবহার করছি। বালিশ এবং নিম্পির মধ্যে রূপান্তরটি সোজা।

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
এটি আমদানির বিবৃতি সহ (এই বিবরণের জন্য ধন্যবাদ) সহ পরিষ্কার উদাহরণ সম্পর্কে। আসুন দৃশ্যমানতা বাড়াতে এই উত্তরে ভোট দিন।
ডেভিড পার্কস

আমি দেখতে পেলাম যে যখন আমি একটি পিআইএল টানা চিত্রটি একটি আঙ্কুল অ্যারেতে রূপান্তরিত করেছি, অ্যারেতে ম্যাটপ্লোটিলেব চিত্র ব্যবহার করার সময় এটি np.flipudঠিক করার জন্য এটি উল্টোদিকে দেখিয়েছিল । যদিও আমার পিআইএল চিত্রটি ব্যবহার করে তৈরি করা হয়েছিল ImageDraw.Draw। আমি মনে করি যে তাদের স্থানাঙ্কের উত্স কোথা থেকে এসেছে সেদিকে অবশ্যই সতর্ক থাকতে হবে।
সিএমসিডিগ্রাগনকাই

তোমার মঙ্গল হোক!! আমি অর্ধদিন ধরে এই উত্তরটি খুঁজছি। এটি প্লট চিত্রটি আসলটির পরে মূল অক্ষটি পুনঃস্থাপনের আমার সমস্যার সমাধান করে।
টিঙ্কারবেল

16

আপনাকে এইভাবে আপনার চিত্রটিকে একটি নমপি অ্যারে রূপান্তর করতে হবে:

import numpy
import PIL

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

রূপান্তরকরণের এই উপায়টি চিত্রটি ধরে রাখে তবে ফলাফলগুলি রঙ হারাতে পারে। যাইহোক রঙের ক্ষতি এড়াতে?
মুন্দ্রা

7
@moondra তাহলে আমি তোমার প্রশ্ন বুঝতে, আপনি প্রতিস্থাপন করতে পারেন .convert("L") দ্বারা.convert("RGB")
বিল্লাল 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

যদি আপনার চিত্রটি একটি ব্লব ফর্ম্যাটে সংরক্ষণ করা হয় (অর্থাত্ একটি ডাটাবেসে) আপনি বিল্লাল বেগ্রেডজ দ্বারা ব্যাখ্যা করা একই কৌশলটি ব্যবহার করতে পারেন আপনার ছবিটি ব্লব থেকে একটি বাইট অ্যারে রূপান্তর করতে।

আমার ক্ষেত্রে, আমার ছবিগুলির দরকার যেখানে ডিবি টেবিলের একটি ব্লব কলামে সঞ্চিত ছিল:

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

তারপরে আমি আমার ডেটাসেটকে এনপি.আরে রূপান্তর করতে একটি সহায়ক ফাংশন তৈরি করেছি:

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()

বৈশিষ্ট্যগুলি বাদ দেওয়ার পরে (অস্বাভাবিককরণ) ইমেজটিকে নম্পি () ফাংশনে ভাগ করে আপনি চিত্রটিকে নম্পিতে রূপান্তর করতে পারেন un

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.