플로라도의 data workout

파이썬에서 이미지 로드하는 다양한 방법 본문

기초 노트/Python

파이썬에서 이미지 로드하는 다양한 방법

플로라도 2024. 6. 8. 23:35

파이썬에서는 이미지 입출력(image I/O)를 처리하는 정말 많은 라이브러리와 함수들을 제공하고 있다.

 

특별히 opencv를 사용하면 이미지를 RGB의 형태가 아닌 BGR의 형태로 읽어 색상값이 뒤직박죽 섞여 이를 적절히 섞어줘야 한다던가 하는 테크닉이 필요한 것은 알았지만,

이미지를 로드하는 라이브러리와 함수에 따라 이미지 픽셀값의 분포가 다르다던지(1), EXIF라고 하는 사진의 메타 데이터의 반영여부가 달라진다던지(2) 하는 차이점을 최근에서야 알게 되었다.

 

 

이미지 입출력 라이브러리에 따라 픽셀 히스토그램의 분포가 다르다.

 

1. PIL/Pillow

- PIL(Python Imaging Library)의 후속으로 유지보수 되고 있는 라이브러리, 원래의 라이브러리는 Python 1.5-2.7을 지원하며, 2011년 PIL 저장소에 대한 마지막 커밋으로 중단되어 Pillow라는 후속 프로젝트를 통해 Python 3.x 지원을 추가하고 있다고 한다.

 

- 다양한 이미지 파일 형식을 지원한다.(JPEG, PNG, BMP, GIF 등)

- 이미지 생성, 변환, 필터 적용, 텍스트 추가 등 다양한 기능을 제공한다.

- PyTorch에서 이미지 전처리를 위해 자주 사용된다, 특히 데이터 증강(data augmentation)분야에 있어 torchvision.transforms에서 Pillow를 활용한다.

from PIL import Image
from torchvision import transforms

# 이미지 열기
image = Image.open("example.jpg")

# 이미지 전처리
transform = transforms.Compose([
    transforms.Resize((128, 128)),
    transforms.ToTensor()
])
tensor_image = transform(image)

 

2. OpenCV(Open Source Computer Vision)

- 컴퓨터 비전 및 이미지 처리 분야를 통틀어서 가장 널리 사용되는 라이브러리이다.

- 파이썬뿐만 아니라, C++, Java등 다양한 프로그래밍 언어를 지원하는 것이 특징이다.

- 대부분의 영상처리 관련은 OpenCV를 거치지 않고 이야기하는 것이 불가능 할 정도로, 영상 관련 라이브러리로서의 사실상 표준의 지위를 가지고 있다고 한다(출처- 나무위키)

- OpenCV는 영상을 'uint8' (0-255) 데이터 타입의 NumPy 배열로 읽는다. 픽셀에 대한 접근은 Numpy 배열에 대한 접근으로 가능하다.

- 데이터 증강에 있어 PIL과 torchvision.transforms의 조합처럼 OpenCV + Albumentation의 조합이 더 많은 기능의 지원과 빠른 속도로 더 애용된다.

import cv2
import numpy as np

# 이미지 읽기
image = cv2.imread("example.jpg")

# 이미지 배열의 형태 출력
print(image.shape)

# 데이터 타입 확인
print(image.dtype)  # 출력: uint8

# float 타입으로 변환
image_float = image.astype(np.float32) / 255.0

 

- 대부분의 기능이 구현되어있고 가장 Advanced Library인 OpenCV지만 cv2.putText와 같은 함수는 이미지 내 텍스트를 입력에는 한글 폰트를 지원하지 않아, PIL의 ImageDraw, ImageFont를 사용해야 하는 경우도 있다.

 

3. matplotlib

matplotlib은 데이터 시각화 라이브러리로 주로 차트를 시각화하는데 사용되지만, 간단한 이미지 입출력 처리도 가능하다.이미지를 간단히 그리드 상에서 표현하고자 할 때 주로 사용한다.

plt.imread 외에도 image모듈에 imread메서드도 지원하며, 기능적으로 이 둘의 차이는 없다고 한다.

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# 이미지 읽기
image = mpimg.imread("example.jpg")

# 이미지 표시
plt.imshow(image)
plt.show()

# 이미지 저장
plt.imsave("new_example.jpg", image)

 

4. scikit-image

아마도 대부분은 PIL과 OpenCV를 통해 이미지를 입력받아 transform을 진행하고, 간단한 시각화는 plt.imread 등을 통해 진행할 것이다. 

오픈소스 소스코드에서 종종 scikit-image의 imread를 사용하여 이미지를 입력받곤 하는데 다른 라이브러리와의 구체적인 차이점이나 사용 목적은 아직 잘 모르겠다.

 

-imread시 여타 다른 라이브러리와 마찬가지로 동일하게 uint8의 형식으로 읽는다.

from skimage import io, color
from skimage.transform import resize

# 이미지 열기
image = io.imread("example.jpg")

# 이미지 크기 조정
resized_image = resize(image, (128, 128))

# 이미지 그레이스케일 변환
gray_image = color.rgb2gray(resized_image)

# 이미지 저장
io.imsave("resized_example.jpg", resized_image)

 

 

5. imageio

마찬가지로  imread메서드 활용시 uint8배열로 영상을 읽는다.

import imageio

# 이미지 읽기
image = imageio.imread("example.jpg")

# 이미지 저장
imageio.imwrite("new_example.jpg", image)

 

 

요약

PIL/Pillow PIL 이미지 객체 uint8 NumPy 배열로 변환 가능
OpenCV NumPy 배열 (BGR) uint8 BGR 형식으로 읽음
scikit-image NumPy 배열 uint8, float64 as_gray=True 옵션 사용 시 float64
imageio NumPy 배열 uint8 다양한 이미지 및 비디오 포맷 지원
matplotlib NumPy 배열 float32, uint8 PNG는 float32, 다른 포맷은 uint8

 


Reference)

https://stackoverflow.com/questions/59855615/skimage-io-imread-versus-cv2-imread

 

skimage.io.imread Versus cv2.imread

I am using and familiar with cv2, today I was giving a try with skimage. I was trying to read an image using skimage and cv2. It seems that they both read the image perfectly. But when I plot

stackoverflow.com

https://ko.wikipedia.org/wiki/Python_Imaging_Library