PIL 이미지를 numpy 배열로 변환하는 방법은 무엇입니까?


257

PIL 이미지 객체를 numpy 배열로 앞뒤로 변환하여 PIL PixelAccess객체가 허용하는 것 보다 픽셀 단위로 더 빠른 픽셀 변환을 수행 할 수 있습니다. 픽셀 정보를 유용한 3D numpy 배열에 배치하는 방법을 알아 냈습니다.

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

그러나 멋진 변환을 모두 마친 후에 PIL 객체에 다시로드하는 방법을 알 수없는 것 같습니다. 나는 그 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.
— foges

답변:


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튜플 시퀀스를 기대하고 numpy 배열을 제공하기 때문입니다. 이

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

작동하지만 매우 느립니다.

PIL 1.1.6부터 이미지와 numpy 배열 사이를 변환 하는 "적절한"방법 은 간단합니다.

>>> pix = numpy.array(pic)

결과 배열은 귀하의 형식과 다릅니다 (이 경우 3 차원 배열 또는 행 / 열 / rgb).

그런 다음 배열을 변경 한 후을 pic.putdata(pix)사용하여 새 이미지를 만들거나 새 이미지를 만들 수 있어야합니다 Image.fromarray(pix).


2
먼저 pic.putdata (data)가되어서는 안됩니까? 그리고 numpy.asarray (pic)는 읽기 전용 배열을 생성하므로 numpy.array (pic)를 호출해야하며 질문에 대답하지 않았습니다 ... 제공 한 링크에서 pic = Image.fromarray ( pix). 답변을 수정하면 수락하겠습니다.
— akdom

2
이것에 감사드립니다 ... Image.fromarrayPIL 문서 (!)에 나열되어 있지 않으므로 이것을 찾지 못했다면 결코 찾지 못했습니다.
— Nathan Reed

13
이 페이지에는 numpy.asarray(pic)전환이 아닌 '적절한'전환 방법이 표시됩니다 numpy.array(pic). 당 이 답변 array 사본 반면 만들 asarray수 없습니다 (그러나 그 asarray결과가됩니다 읽기 전용).
— Arthur Tacca

1
여기 내 경고 (내 실수로) : 데이터의 규모와 범위도 고려해야합니다. 많은 유스 케이스에서 0-255 바이트의 이미지를 렌더링하지만 numpy 배열에서 예를 들어 0.0-1.0으로 변환 될 것으로 예상 할 수 있습니다. uint8에서 일부 단위 변환은이 작업을 수행하지만이 경우에는 그렇지 않습니다. 확인하십시오 :)
— BjornW

두 번째 답변이 더 좋습니다.
— 나단

193

I배열로 엽니 다 :

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

에 몇 가지 작업을 수행 I한 다음 이미지로 다시 변환하십시오.

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

FFT, Python으로 numpy 이미지 필터링

어떤 이유로 명시 적으로 수행하려는 경우 correlation.zip 의이 페이지 에서 getdata ()를 사용하는 pil2array () 및 array2pil () 함수가 있습니다.


2
@ArditS .: import Image먼저 했습니까 ? PIL이 설치되어 있습니까?
— endolith

5
는 IS uint8변환이 필요?
— Neil Traft

4
numpy.asarray(Image.open(filename)).jpg 이미지에서는 작동하지만 .png에서는 작동하지 않는 것 같습니다. 결과는로 표시됩니다 array(<PngImagePlugin.PngImageFile image mode=LA size=500x500 at 0x3468198>, dtype=object). 이 PngImagePlugin.PngImageFile문제를 해결하기 위해 분명히 명명 된 방법이없는 것 같습니다 . 나는 이것을 새로운 질문으로해야한다고 생각하지만 그것은이 스레드와 매우 관련이 있습니다. 아무도 여기서 무슨 일이 일어나고 있는지 이해합니까?
— jez December

3
@Rebs : 이것이 훨씬 더 빠른 이유 입니다 : getdata()object ( pillow.readthedocs.io/en/3.4.x/reference/… ) 와 같은 시퀀스를 반환 하지만 베개 이미지 는 원시 바이트에 액세스하는 데 사용할 수 있는 __array_interface__것을 구현합니다 numpy반복자를 거치지 않고 이미지의 이미지 ( github.com/python-pillow/Pillow/blob/… 및 docs.scipy.org/doc/numpy/reference/arrays.interface.html 참조 ) 당신은 심지어 사용할 수 있습니다numpy.array(PIL.Image.open('test.jpg'))
— tdp2110

3
@jez numpy로 변환하기 전에 Image 객체가 닫혀 있는지 확인하십시오. 나에게도 똑같은 일이 있었고 이미지 객체를 어딘가에서 닫았습니다.
— Shaohua Li

65

Python 3.5에서 Pillow 4.1.1 (PIL의 후속 버전)을 사용하고 있습니다. Pillow와 numpy 간의 변환은 간단합니다.

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상술 한 예이다.

변환 된 numpy 배열을 처리 할 때 HxWxC 데이터 형식을 처리해야합니다 (예 : 변환 im2arr = np.rollaxis(im2arr, 2, 0)또는im2arr = np.transpose(im2arr, (2, 0, 1)) CxHxW 형식으로).


2
이것은 import 문을 포함하여 가장 깨끗한 예에 관한 것입니다 (세부 사항에 대한 감사). 이 답변에 투표하여 가시성을 높이십시오.
— David Parks

PIL 그린 이미지를 numpy 배열로 변환 할 때 matplotlib imshow를 배열에 사용할 때 뒤집어 야하는 np.flipud것을 수정 해야한다는 것을 알았습니다. 내 PIL 이미지는을 사용하여 처음부터 작성되었지만 ImageDraw.Draw. 좌표의 원점이 어디에서 오는지주의해야한다고 생각합니다.
— CMCDragonkai

축복합니다!! 나는 반나절 동안이 답변을 찾고 있습니다. 플롯 이미지 후 원래 축을 원래 축으로 복원하는 문제를 해결합니다.
— Tinkerbell 2016 년

16

이 방법으로 이미지를 numpy 배열로 변환해야합니다.

import numpy
import PIL

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

이 변환 방법은 이미지를 유지하지만 색상이 손실됩니다. 어쨌든 색 손실을 피하기 위해?
— Moondra

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

이미지가 Blob 형식 (예 : 데이터베이스)으로 저장된 경우 Billal Begueradj에서 설명한 것과 동일한 기술을 사용하여 이미지를 Blob에서 바이트 배열로 변환 할 수 있습니다.

필자의 경우 db 테이블의 blob 열에 저장된 이미지가 필요했습니다.

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

0

Numpy to PIL이미지 변환PIL to Numpy

import numpy as np
from PIL import Image

def pilToNumpy(img):
    return np.array(img)

def NumpyToPil(img):
    return Image.fromarray(img)

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

기능을 지정한 후 이미지를 numpy () 함수로 구문 분석하여 이미지를 numpy로 변환 할 수 있습니다 (정규화)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.