※ 본 게시글은 필자의 개인 경험을 토대로 작성된 것으로, 잘못된 정보를 포함하고 있을 수 있습니다. ※
Python에서는 PIL (Python Image Library)를 제공한다. 이를 이용하면, 간단히 특정한 이미지를 불러와 수정하는 것이 가능하며, 원한다면 불러 온 이미지를 NumPy와 같은 객체로 만드는 것도 가능하다.
이때, 작은 크기의 이미지가 여러 개 있을 때, 이것을 한 눈에 보기 편하게 만들기 위하여 이미지 격자(image grid)를 만드는 방법에 대해서 소개하고자 한다.
바로 다음과 같은 함수를 이용하는 것이다. Image.new()를 사용하면, 특정한 크기의 빈 이미지를 생성할 수 있으며, 해당 빈 이미지에 작은 크기의 이미지 패치를 채워 넣을 수 있다. PIL 이미지 객체가 담겨 있는 하나의 배열 imgs가 있을 때, 이를 rows X cols 형태의 격자 이미지로 만드는 것이다.
from PIL import Image
def image_grid(imgs, rows, cols):
assert len(imgs) == rows * cols
w, h = imgs[0].size # 각 이미지에 대한 해상도 계산: 너비 X 높이
# 최종 이미지 해상도: (열 개수 * 각 이미지 너비) X (행 개수 * 각 이미지 높이)
grid = Image.new('RGB', size=(cols * w, rows * h)) # 하나의 빈 이미지(최종 이미지) 만들기
grid_w, grid_h = grid.size # 전체 너비 X 전체 높이
# 이미지를 하나씩 확인하며, 각 (행, 열) 위치마다 차곡차곡 이미지를 삽입
for i, img in enumerate(imgs):
row_index = i % cols # 행 인덱스
column_index = i // cols # 열 인덱스
# 최종 이미지(grid)의 특정 위치에 이미지 패치 삽입
grid.paste(img, box=(row_index * w, column_index * h))
return grid
아래 코드 예시는 특정한 이미지 폴더에 있는 모든 이미지에 대하여, 모든 이미지를 PIL 객체로 불러 온 뒤에, 이를 섞어서(shuffling) 실제로 이미지 격자로 출력하는 예시이다.
참고로 특정한 경로에 있는 모든 파일 목록의 경로를 불러오는 코드는 glob()을 사용하면 되는데, "./images/*.png"와 같은 형태로 넣으면, 모든 PNG 파일의 경로를 얻어 올 수 있다. 총 12 X 12 = 144개의 이미지를 그리드(grid) 형태로 출력하는 예시임을 확인할 수 있다.
import glob
import random
# 특정한 폴더 내에 포함된 모든 이미지 파일 경로 찾기
image_list = glob.glob({이미지 폴더 경로})
random.shuffle(image_list) # 이미지 경로를 랜덤으로 섞기(옵션)
rows = 12 # 행(row)
cols = 12 # 열(column)
total = rows * cols # 선택할 이미지 개수
imgs = [] # 전체 이미지 리스트
for idx, image_path in enumerate(image_list):
if idx == total: break
# PIL을 이용하여 이미지 파일 열기
image = Image.open(image_path)
# print(image_path) # 불러올 이미지 경로 출력
# 해당 이미지 객체 저장하기
imgs.append(image)
grid = image_grid(imgs, rows=rows, cols=cols)
grid
다음과 같이 Jupyter Notebook에서 이미지 시각화를 수행한 예시는 다음과 같다.