프로그래밍/Python

[python] RGBA 형식의 이미지 찾기

채윤아빠 2024. 5. 21. 09:31
728x90
반응형

개요

인터넷에서 수집한 자료 중에 RGBA 형식의 이미지가 확장자만 "*.jpg"로 저장되어 있는 경우가 종종 있습니다.

내부적으로 이미지 처리를 한 후에 cv2.imwrite() 함수를 이용하여 JPG로 저장할 경우 다음과 같이 "RGBA" 형식의 이미지는 JPG로 저장할 수 없다는 오류가 발생합니다.

.
.
.
  File "/usr/local/lib/python3.8/dist-packages/PIL/Image.py", line 2240, in save
    save_handler(self, fp, filename)
  File "/usr/local/lib/python3.8/dist-packages/PIL/JpegImagePlugin.py", line 631, in _save
    raise OSError(f"cannot write mode {im.mode} as JPEG") from e
OSError: cannot write mode RGBA as JPEG

 

이런 문제가 발생하지 않도록 확장자가 "*.jpg"인 파일중에 RGBA 형식의 이미지를 cv2를 이용하여 찾는 방법을 정리해 둡니다.


cv2를 이용한 방법

다음과 같이 cv2.imread() 함수를 이용하여 이미지를 읽어 들인 후, 이미지의 channel 개수를 확인하는 간단한 방법으로 RGBA 형식으로된 이미지들을 찾을 수 있습니다.

from os import getcwd, listdir, makedirs, path, remove, rename, fstat
from typing import Final

import cv2


DATASET_BASE: Final                = r'/data/dataset/ru'
ORG_IMAGES_PATH: Final            = f'{DATASET_BASE}/org_images'


def main() -> int:

    file_list = listdir(ORG_IMAGES_PATH)

    file_count, max_height, max_width = 0, 0, 0
    for filename in file_list:
        file_count += 1
        if (file_count % 1000 == 0):
            print(f'{file_count=} processed...')

        org_image_file = f'{ORG_IMAGES_PATH}/{filename}'

        # 이미지 열기
        org_image = cv2.imread(org_image_file, cv2.IMREAD_UNCHANGED)

        # 이미지 채널 수 확인
        height, width, channels = org_image.shape
        if (max_width < (width)):
            max_width = (width)
        if (max_height < (height)):
            max_height = (height)

        # RGBA 형식 확인
        if (channels == 4):
            print(org_image_file)


if __name__ == '__main__':

    main()

Pillow를 이용한 방법

Pillow.Image 클래스로 이미지를 읽어 들인 후, 이미지의 mode 값을 확인합니다.

from os import getcwd, listdir, makedirs, path, remove, rename, fstat
from PIL import Image
from typing import Final


DATASET_BASE: Final                = r'/data/dataset/ru'
ORG_IMAGES_PATH: Final            = f'{DATASET_BASE}/org_images'


def main() -> int:

    file_list = listdir(ORG_IMAGES_PATH)

    file_count = 0
    for filename in file_list:
        file_count += 1
        if (file_count % 1000 == 0):
            print(f'{file_count=} processed...')

        org_image_file = f'{ORG_IMAGES_PATH}/{filename}'

        # 이미지 열기
        org_image = Image.open(org_image_file)

        # RGBA 형식 확인
        if (org_image.mode == "RGBA"):
            print(org_image_file)


if __name__ == '__main__':

    main()