본문 바로가기

Deep Learning/Python

Python에서의 이미지 불러오기 속도 비교(PIL, cv2, imageio, tf)

Python에서 이미지를 읽는 방법은 여러가지가 있습니다.

컴퓨터비전을 위한 머신러닝, 딥러닝에선 이미지를 불러와 직접 다루는 일이 많습니다.

특히 이미지로 이루어진 커다란 데이터셋의 경우, 이미지를 불러오는 속도조차 신경 쓰일 수 있습니다.

이번 글에서는 4가지의 파이썬 외부 패키지의 이미지 로드 속도를 비교해보겠습니다.

 

아래 코드는 Windows 10 PC에서 실행하였습니다.

import os
import time
import numpy as np

import cv2
import PIL
import imageio
import tensorflow as tf

print('PIL:', PIL.__version__)
print('cv2:', cv2.__version__)
print('imageio:', imageio.__version__)
print('tf:', tf.__version__)

# PIL: 7.2.0
# cv2: 4.4.0
# imageio: 2.9.0
# tf: 2.3.1

image_folder = '../Human-Pose-Estimation/data/mpii_human_pose_v1/images'
img_list = os.listdir(image_folder)
len_img = len(img_list)
print(len_img)
num = 2000
end = []

MPII 데이터셋은 Human pose estimation을 위한 데이터셋입니다.

약 24000개의 이미지가 포함되어 있습니다. 데이터셋 내의 이미지 해상도는 각각 다릅니다.

 

그 중 2000개의 이미지를 불러오도록 테스트해보겠습니다.

start = time.time()
for img_dir in img_list[:num]:
    img = cv2.imread(os.path.join(image_folder, img_dir), cv2.IMREAD_COLOR)
end.append(time.time() - start)

start = time.time()
for img_dir in img_list[:num]:
    img = PIL.Image.open(os.path.join(image_folder, img_dir))
    img = np.array(img)
end.append(time.time() - start)

start = time.time()
for img_dir in img_list[:num]:
    img = tf.io.read_file(os.path.join(image_folder, img_dir))
    img = tf.image.decode_jpeg(img, channels=3)
    img = img.numpy()
end.append(time.time() - start)

start = time.time()
for img_dir in img_list[:num]:
    img = tf.io.read_file(os.path.join(image_folder, img_dir))
    img = tf.image.decode_jpeg(img, channels=3)
    img = img.numpy()
end.append(time.time() - start)

컴퓨터비전에서 이미지를 불러오는 경우엔 이미지를 numpy 배열로 다루는 경우가 많습니다.

그래서 이미지를 불러와 numpy 배열로 변환하는 시간도 소요 시간에 포함하였습니다.

cv2와 imageio의 경우, 이미지를 바로 numpy 배열의 타입으로 불러옵니다.

 

y축은 소요 시간(초)을 나타냅니다.

tf의 소요 시간이 가장 짧았습니다. 그 다음은 cv2, imageio, PIL입니다.

 

이번엔 이미지 단 하나를 불러올 때의 비교입니다.

 

유난히 tf의 소요 시간이 오래 걸립니다.

그래서 우선 tf 코드 실행 전 아래의 코드로 무작위 이미지를 하나 불러온 후 다시 단일 이미지를 불러오는데 걸린 소요 시간을 측정하였습니다.

img = tf.io.read_file(os.path.join(image_folder, img_dir))

이번에 tf가 가장 빠른 결과를 보여줬습니다.

전체적으로 여러 이미지를 불러올 때의 양상을 보여줍니다.

 

위의 결과만 보았을 땐 tf < cv2 < imageio < PIL 순의 소요 시간을 보여줍니다.

 

하지만 위의 결과는 단지 참고만 하시면 좋을 것 같습니다.

연구실 Ubuntu 20.04 LTS PC로 위 코드를 실행한 결과, tf 다음으로 PIL이 가장 빠른 속도를 보이기도 하였으며

PIL의 버전을 (7.0.0 -> 8.1.1)로 업그레이드 하여 비교한 결과는 PIL이 가장 느렸습니다.

아무래도 패키지의 버전에도 차이가 큰 것으로 보이며, 운영체제에 따라서도 차이가 있는 것으로 보입니다. 

 

어떤 환경에서도 tf가 인상적인 속도를 보여준 것을 토대로 저는 Tensorflow 코드에선 tf.io.read_file() 를 사용할 예정입니다.