개요
np.array(pic)
를 실행하면 PIL Image 객체가 NumPy 배열로 변환되는데, 이는 단순해 보이지만 내부적으로 복잡한 메커니즘이 작동합니다[1][2]. 이 과정은 JPEG 파일의 디코딩부터 메모리 공유까지 여러 단계를 거치게 됩니다.
JPEG 파일에서 PIL Image 객체로의 변환
JPEG 디코딩 과정
JPEG 파일이 PIL Image 객체로 로드될 때, 먼저 복잡한 디코딩 과정을 거칩니다[3][4]. JPEG는 실제로는 압축 알고리즘이며, 우리가 보는 .jpg 파일은 대부분 JFIF(JPEG File Interchange Format) 형식입니다[3][4].
JPEG 디코딩 과정은 다음과 같습니다[3]:
- 8×8 블록 단위 처리: JPEG는 이미지를 8×8 픽셀 블록(MCU, Minimum Coding Units)으로 나누어 처리합니다
- 색공간 변환: RGB에서 YCbCr로 변환된 데이터를 다시 RGB로 변환합니다
- 허프만 디코딩: 압축된 데이터를 허프만 코딩을 통해 디코딩합니다
- 역 이산 코사인 변환: DCT(Discrete Cosine Transform)의 역변환을 수행합니다
PIL Image 객체의 내부 구조
PIL Image 객체가 생성되면, 내부적으로 픽셀 데이터를 메모리에 저장합니다[5][6]. 이 객체는 다음과 같은 특성을 가집니다:
- 픽셀 데이터: 실제 이미지의 RGB 값들이 연속된 메모리 공간에 저장됩니다
- 메타데이터: 이미지 크기, 색상 모드, 포맷 정보 등이 포함됩니다
- Array Interface: NumPy와의 호환성을 위한
__array_interface__
속성을 제공합니다[7][8]
NumPy 배열 변환 메커니즘
Array Interface Protocol
PIL Image 객체에서 NumPy 배열로의 변환은 Array Interface Protocol을 통해 이루어집니다[7][8]. PIL Image 객체는 __array_interface__
속성을 가지고 있으며, 이는 다음과 같은 정보를 포함합니다[7][8]:
# PIL Image 객체의 __array_interface__ 예시
{
'version': 3,
'data': (메모리_주소, 읽기전용_여부),
'shape': (높이, 너비, 채널수),
'typestr': '|u1', # unsigned 8-bit integer
'strides': None
}
np.array() 함수의 동작
np.array(pic)
를 호출하면 다음 과정이 순차적으로 실행됩니다[2][9]:
- 객체 타입 확인: NumPy는 입력 객체가 array interface를 지원하는지 확인합니다
- 메모리 접근: PIL Image의
__array_interface__
를 통해 픽셀 데이터의 메모리 위치를 파악합니다[7][8] - 데이터 복사: 기본적으로 새로운 NumPy 배열을 생성하고 데이터를 복사합니다[9]
- 배열 구조 설정: shape, dtype 등의 배열 속성을 설정합니다
np.asarray()와의 차이점
np.array()
와 np.asarray()
는 미묘한 차이가 있습니다[2][9]:
- np.array(): 항상 새로운 배열을 생성하여 데이터를 복사합니다[9]
- np.asarray(): 가능한 경우 기존 데이터를 재사용하려 시도합니다[2][9]
메모리 구조와 데이터 레이아웃
픽셀 데이터 구조
변환된 NumPy 배열은 일반적으로 3차원 구조를 가집니다[1][10]:
- 첫 번째 차원: 이미지의 높이 (세로 픽셀 수)
- 두 번째 차원: 이미지의 너비 (가로 픽셀 수)
- 세 번째 차원: 색상 채널 (RGB의 경우 3개)
데이터 타입
JPEG 이미지에서 변환된 NumPy 배열의 데이터 타입은 일반적으로 uint8
입니다[10][11]. 이는 각 픽셀 값이 0-255 범위의 부호 없는 8비트 정수로 표현됨을 의미합니다.
전체 변환 과정 요약
- JPEG 파일 로딩: PIL이 JPEG 파일을 읽고 디코딩하여 픽셀 데이터를 메모리에 저장합니다[3][4]
- PIL Image 객체 생성: 디코딩된 데이터로 PIL Image 객체가 생성됩니다[5][6]
- Array Interface 활용: PIL Image의
__array_interface__
속성이 NumPy와의 연결고리 역할을 합니다[7][8] - NumPy 배열 생성:
np.array()
가 이 인터페이스를 통해 픽셀 데이터에 접근하여 새로운 배열을 생성합니다[2][9] - 메모리 복사: 일반적으로 PIL Image의 데이터가 NumPy 배열로 복사됩니다[9]
이러한 과정을 통해 np.array(pic)
호출 한 번으로 JPEG 파일의 모든 픽셀 데이터가 NumPy 배열로 변환되어 수치 연산이 가능한 형태로 제공됩니다[1][2][9].
출처
[1] [ Python / PIL ] PIL 이미지, Numpy 배열 변환 및 저장 ( Image … https://supermemi.tistory.com/entry/Python-PIL-PIL-%EC%9D%B4%EB%AF%B8%EC%A7%80-Numpy-%EB%B0%B0%EC%97%B4-%EB%B3%80%ED%99%98-%EB%B0%8F-%EC%A0%80%EC%9E%A5-Imagefromarray-nparray-npasarray
[2] Importing Image Data into NumPy Arrays – Pluralsight https://www.pluralsight.com/resources/blog/guides/importing-image-data-into-numpy-arrays
[3] Understanding and Decoding a JPEG Image using Python https://yasoob.me/posts/understanding-and-writing-jpeg-decoder-in-python/
[4] 10 Understanding and Decoding a JPEG Image using Python¶ https://practicalpython.yasoob.me/chapter10
[5] Image Module – Pillow (PIL Fork) 11.2.1 documentation https://pillow.readthedocs.io/en/stable/reference/Image.html
[6] The Image Module — Python 3.6.1 documentation – omz:software https://omz-software.com/pythonista/docs/ios/Image.html
[7] Related Content you might be interested in https://subscription.packtpub.com/book/data/9781849518925/4/ch04lvl1sec40/using-the-array-interface
[8] 2.2. Advanced NumPy – Scientific Python Lectures https://lectures.scientific-python.org/advanced/advanced_numpy/index.html
[9] How to Convert PIL Image to NumPy Array https://www.delftstack.com/howto/numpy/pil-image-to-numpy-array/
[10] Convert Numpy array to Image https://iq.opengenus.org/convert-numpy-array-to-image/
[11] Convert a PIL Image into a NumPy array – w3resource https://www.w3resource.com/python-exercises/numpy/python-numpy-exercise-108.php
[12] How to convert a Numpy array image to a JPEG without saving the … https://stackoverflow.com/questions/66033622/how-to-convert-a-numpy-array-image-to-a-jpeg-without-saving-the-image
[13] How to Convert Images to Numpy Arrays in Python – AskPython https://www.askpython.com/python/examples/convert-images-to-numpy-arrays
[14] 5 Best Ways to Convert a Python NumPy Array to JPEG – Finxter https://blog.finxter.com/5-best-ways-to-convert-a-python-numpy-array-to-jpeg/
[15] How to Convert a NumPy Array to PIL Image in Python https://www.delftstack.com/howto/matplotlib/convert-a-numpy-array-to-pil-image-python/
[16] Read PNG image data into NumPy array using Python https://www.w3resource.com/python-exercises/numpy/read-png-image-data-into-numpy-array-using-python.php
[17] 5 Best Ways to Convert JPG to Numpy Array in Python – Finxter https://blog.finxter.com/5-best-ways-to-convert-jpg-to-numpy-array-in-python/
[18] Python에서 NumPy 배열을 PIL 이미지로 변환 – Delft Stack https://www.delftstack.com/ko/howto/matplotlib/convert-a-numpy-array-to-pil-image-python/
[19] How to build an image object in PIL/Python – Stack Overflow https://stackoverflow.com/questions/2343115/how-to-build-an-image-object-in-pil-python
[20] Image file formats – Pillow (PIL Fork) 11.2.1 documentation https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
[21] 思维导图备注 https://www.bookstack.cn/read/Pillow-7.1.1/619f891b52eabef4.md?wd=pillow
[22] PIL image to array (numpy array to array) – Python https://stackoverflow.com/questions/13550376/pil-image-to-array-numpy-array-to-array-python
[23] Image.fromarray cannot be used with array.array https://stackoverflow.com/questions/43229482/image-fromarray-cannot-be-used-with-array-array
[24] 3. Image fromarray https://pc-pillow.readthedocs.io/en/latest/Image_class/Image_fromarray.html
[25] How to convert a NumPy array to PIL image applying matplotlib … https://stackoverflow.com/questions/10965417/how-to-convert-a-numpy-array-to-pil-image-applying-matplotlib-colormap
[26] [코드] PIL image를 show 하기 / numpy array plt.show – Flash Summit https://flashsummit.tistory.com/77
[27] Convert PIL Image to NumPy array (OpenCV) – Roboflow https://roboflow.com/use-opencv/convert-pil-image-to-numpy-array
[28] Structured arrays¶ https://jiffyclub.github.io/numpy/user/basics.rec.html
[29] Buffer Protocol and NumPy Arrays – CSnakes https://tonybaloney.github.io/CSnakes/buffers/
[30] tbpaolini/PyJpegDecoder: A JPEG decoder made in Python … – GitHub https://github.com/tbpaolini/PyJpegDecoder
[31] python-jpeg-decoder/jpeg.py at master – GitHub https://github.com/Exaphis/python-jpeg-decoder/blob/master/jpeg.py
[32] GitHub – eilam-ashbell/jpeg-dump: A deep dive into JPEG file structure https://github.com/eilam-ashbell/jpeg-dump
[33] JPEG2000-PIL JPEG 2000 (ISO 15444)¶ https://imageio.readthedocs.io/en/v2.5.0/format_jpeg2000-pil.html
[34] Need for Speed: A Comprehensive Benchmark of JPEG Decoders https://arxiv.org/pdf/2501.13131.pdf
[35] EXTRACTING PIXEL VALUES OF AN IMAGE IN PYTHON https://www.hackerearth.com/practice/notes/extracting-pixel-values-of-an-image-in-python/
[36] Pillow/src/PIL/Image.py at main – GitHub https://github.com/python-pillow/Pillow/blob/main/src/PIL/Image.py
[37] Understanding and Decoding a JPEG Image using Python – Reddit https://www.reddit.com/r/Python/comments/hr9tbi/understanding_and_decoding_a_jpeg_image_using/
답글 남기기