AIFFEL FD #11 파이썬으로 이미지 파일 다루기 (Pillow, OpenCV)

이재준·2021년 7월 18일
0

AIFFEL Fundamental

목록 보기
12/25
post-custom-banner

✅ 핵심내용

  • 컴퓨터에서 이미지가 표현되는 방식 이해
  • Pillow와 OpenCV로 Python 에서 이미지 정보 추출
  • 히스토그램을 기반으로 유사한 이미지 골라내기

📷 디지털 이미지

디지털 화면은 수많은 점들로 이루어져 있으며, 색상을 가지는 점 하나를 화소(pixel, picture element) 라고 한다. 각 화소는 RGB(Red, Green, Blue) 세 개의 단일 색의 강도를 각각 조절하여 색상을 표현한다.

디지털 화면에 표시되는 이미지를 저장하는 방법은 여러가지가 있다.

  • 래스터(raster) 또는 비트맵(bitmap) 방식 : 각 점 하나하나의 색상 값을 저장, 보통 한 점마다 각 색상별로 8비트를 사용하여 0~255 사이의 값(2^8 = 256)으로 해당 색의 감도를 표시
  • 벡터(vector) 방식 : 이미지는 상대적인 점과 선의 위치를 방정식으로써 기록해 두었다가, 확대 및 축소에 따라 디지털 화면의 각 화소에 어떻게 표현될지를 재계산 (이미지 깨짐이 없음)


출처 : https://wacomkoreablog.com/

우리가 주로 다루는 파일들 중에는 사진 파일들이 래스터 방식이며, 확대 축소가 자유로이 가능한 글꼴들이 주로 벡터 방식이다.

디지털 화면의 화소로 표시되는 이미지를 저장하는 방법이 여러 가지인 것 처럼, 색을 표현하는 다양한 방식이 있다.

  • YUV 방식 : 인간의 눈이 색상의 차이보다는 음영에 더 민감한 것을 역이용하여, 기존 흑백 채널에다가 그보다 1/4의 해상도를 가진 두 색상 채널을 덧붙여서 송출
  • HSV 방식 : Hue 색상, Saturation 채도, Value 명도
  • CMYK 방식 : Cyan, Magenta, Yellow, Black 네 가지 색상. 검은색을 표현할 때 각 색을 조합하면 잉크의 낭비가 심하다는이유 때문에 사용

이러한 색을 표현하는 방식을 각각 컬러 스페이스(color space, 색 공간) 라고 하며, 각 컬러 스페이스를 구성하는 단일 축(RGB에서의 각각 R, G, B)을 채널(channel) 이라고 한다.


Pillow

Pillow 는 간단한 이미지 작업에 Numpy 와 결합하여 간편하게 사용 할 수 있는 도구이다.

  • PIL.Image.fromarry() : 이미지 객체로 변환
  • PIL.Image.open() : 이미지 파일 불러오기

을 통해 여러 이미지 객체를 만들고, 이미지 파일을 불러올 수 있고 해당 이미지에 resize(), crop() 등의 메소드를 통해 여러 기능을 수행 할 수 있다.

CIFAR-100 데이터셋 에 Pillow 를 활용하여 데이터 전처리 과정을 해보자.

사용할 데이터셋은 이 페이지 에서 CIFAR-100 python version 이다. 해당 데이터 셋은 32x32 화소 해상도의 이미지들이 100개 클래스 당 600장(각 학습용 500장, 테스트용 100장)하여 총 60,000장 있다.

자세한 과정은 아래의 GitHub 에 기록하였다.

GitHub Link 🔗 ➡ FD12_Image_with_Pillow_OpenCV


OpenCV

OpenCV 는 오픈소스로 제공되는 컴퓨터 비전용 라이브러리 이다. C++, Python, Java, MATLAB 등 다양한 언어에서 호출하여 사용할 수 있으며, 영상 처리에 대한 다양한 고급 기능들이 사용하기 쉽도록 구현되어 있다.

OpenC 튜토리얼 에 여러 기능들을 구현할 수 있는 예제들이 준비되어있다.

OpenCV 자체는 C++로 구현되어 있고, 이를 아래의 코드를 이용해 파이썬에서 불러 쓸 수 있도록 하는 패키지인 opencv-python를 설치해야한다.

pip install open-cv python

OpenCV 를 활용한 특정 색 영역 추출

그 중에서 이미지에서 특정 색을 가진 영역만 추출하는 예제(Changing Colorspaces) 를 통해 OpenCV 를 활용해보겠다.

이미지의 내용 중 관심 있는 부분이 특정 색을 가지고 있다면, 이 정보를 통해 원하는 부분을 배경을 구분하고, 원하는 부분만 따로 떼어낼 수 있다. 이 예제에서는 이미지를 읽어 들이고, 파란색을 찾기 쉽도록 컬러스페이스를 BGR(RGB)에서 HSV로 변환한 뒤, 해당 색상과 맞는 영역만 표시하는 작업이 진행된다.

간단한 예시로, 아래의 이미지에서 파란색 부분을 추출해보았다.

자세한 과정은 아래의 GitHub 에 기록하였다.

GitHub Link 🔗 ➡ FD12_Image_with_Pillow_OpenCV

OpenCV 를 활용한 비슷한 이미지 찾아내기

OpenCV에서 제공하는 기능 중에서 이미지에서 색상 히스토그램을 추출하고, 이를 서로 비교하는 기능들을 불러 사용해보자.

여기서 히스토그램 이란, 이미지에서 픽셀 별 색상 값의 분포이다.

OpenCV 를 활용하여 CIFAR-100 데이터 중 입력 이미지에 가장 비슷한 사진 5개를 찾아내는 프로그램을 만들 수 있다.

설계 과정은 다음과 같다.

  • 프로그램 실행

  • build_histogram_db()

    • CIFAR-100 이미지들을 불러옴
    • CIFAR-100 이미지들을 하나하나 히스토그램으로 만듦
    • 이미지 이름을 key, 히스토그램을 value 로 하는 딕셔너리 histogram_db 생성
  • CIFAR-100 히스토그램 중 입력된 이미지 이름에 해당하는 히스토그램을 입력 이미지로 선택하여 target_histogram이라는 변수명으로 지정

  • search()

    • 입력 이미지 히스토그램 target_histogram와 전체 검색 대상 이미지들의 히스토그램을 가진 딕셔너리 histogram_db를 입력으로 받음

    • OpenCV의 compareHist() 함수를 사용하여 입력 이미지와 검색 대상 이미지 하나하나의 히스토그램 간 유사도를 계산. 결과는 result라는 이름의 딕셔너리로, 키는 이미지 이름, 값은 유사도로 저장

    • 계산된 유사도를 기준으로 정렬하여 순서를 매겨서 유사도 순서상으로 상위 5개 이미지만 골라서 result에 남김

  • 고른 이미지(result)들을 표시

  • 프로그램이 종료

자세한 과정은 아래의 GitHub 에 기록하였다.

GitHub Link 🔗 ➡ FD12_Image_with_Pillow_OpenCV

profile
🏫 𝑲𝒚𝒖𝒏𝒈 𝑯𝒆𝒆 𝑼𝒏𝒊𝒗. / 👨‍🎓 𝑪𝒐𝒍𝒍𝒆𝒈𝒆 𝒐𝒇 𝑬𝒏𝒈𝒊𝒏𝒆𝒆𝒓𝒊𝒏𝒈
post-custom-banner

0개의 댓글