파이썬/zarr

python에서 image data를 zarr array로 저장하는 방법

remarkable-book 2023. 8. 16. 18:00
반응형

zarr 란?

zarr란 데이터를 chunk 단위의 배열로 저장할 수 있는 파이썬 라이브러리다. 데이터를 chunk로 나누어 저장하는 이유는 많은 데이터를 병령처리하여 불러오기 위함이다.

 

Zarr is a format for the storage of chunked, compressed, N-dimensional arrays inspired by 
HDF5, h5py and bcolz.

 

영어로 format 이라 부르는데, 한국어로 형식 정도로 번역할 수 있다.

 

 

DataSet

https://www.kaggle.com/datasets/pranavraikokte/covid19-image-dataset

 

Covid-19 Image Dataset

3 Way Classification - COVID-19, Viral Pneumonia, Normal

www.kaggle.com

 

zarr docs에는 단일 파일만 다루는 내용이 있어서, Kaggle 데이터를 활용해서 여러 데이터를 zarr 파일로 저장하는 코드를 구현한다.

 

import 

import zarr
import glob
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

 

jpg_paths = []
png_paths = []
etc_paths = []
for img_data in img_paths:
    if img_data.endswith(".jpg"):
        jpg_paths.append(img_data)
    if img_data.endswith(".png"):
        png_paths.append(img_data)
    else:
        etc_paths.append(img_data)

이미지 타입에 따라 경로를 따로 리스트 안에 저장한다.

 

이미지 데이터를 zarr array로 저장

zip_path = './zarr_data/examples'
store = zarr.DirectoryStore(zip_path)
root = zarr.group(store=store, overwrite=True)
foo = root.create_group('png_zarr')

for idx, png_img in enumerate(png_paths):
    img = Image.open(png_img)
    img_np = np.array(img)
    shape = img_np.shape
    chunks = (shape[0] // 4, shape[0] // 4)
    dtype = 'i4'
    z = foo.zeros(f'image_zarr_{idx}', shape=shape, chunks=chunks, dtype=dtype)
    z[:] = img_np
store.close()

shape은 이미지 데이터 shape를 그대로 사용한다.

 

chunk는  이미지 데이터 shape를 4로 나눈 값을 사용한다. 프로젝트마다 설정해야하는 chunk가 다르기 때문에, 임의로 설정한다.

 

마지막에 store.close()를 사용해서 열려있는 store를 닫아준다.

 

chunk를 너무 많이 나누면 오버헤드가 발생하고, 너무 작게 나누면, 병렬성의 장점을 살리기 어려울 수 있다.

 

zarr

저장한 데이터는 위의 이미지와 같이 저장된다.

 

zarr array

저장한 zarr array를 확인하면 위와 같이 나오는 것을 확인할 수 있다. 

 

이미지 데이터를 4로 나누어 chunk로 저장했기 때문에, 4.4.0까지 저장되어 있는 것을 확인할 수 있다.

 

zarr array로 저장한 이미지 데이터 open

zarr_range = len(glob.glob('./zarr_data/examples/png_zarr/*'))
img_lists = []
store = zarr.DirectoryStore('./zarr_data/examples')
data_array = zarr.open(store)

for n in range(zarr_range): 
    z = data_array[f'png_zarr/image_zarr_{n}'] 
    img_lists.append(z[:])

Directorystore로 폴더를 열면 데이터의 수를 확인하기 어렵기 때문에, glob를 사용해서 저장한 데이터의 수를 변수로 할당한다.

 

zarr.open으로 store를 열고, for문을 순회하며 list안에 open한 데이터를 할당한다.

 

이미지 데이터 시각화

plt.imshow(img_lists[0])

저장한 데이터를 시각화하면 위와 같이 나오는 것을 확인할 수 있다.

 

반응형