이미지 전처리는 영상 내에서 불필요한 영역은 제거하고 의미있는 정보만 남겨두는 과정인데요. 가장 자주 사용되는 방식 중 하나가 그레스케일과 이진화 입니다.
이미지는 기본적으로 픽셀(Pixel)로 이루어져 있습니다. pictures element의 줄임말로 '화소'라고도 하는데요. 이미지 크기를 표현할 때는 가로(행) 픽셀 수
x 세로(열) 픽셀 수
(= 해상도) 로 나타내며 128 x 128 이미지는 16,384개 픽셀을 가지고 있습니다. 이처럼 이미지 크기는 2차원 배열로 표현하며 파이썬에서는 numpy.ndarray
클래스 배열로 표현합니다.
이미지의 컬러 정보는 Red, Green, Blue 의 3개 배열로 표현되며, 배열의 개수를 Channel이라고도 부르기 때문에, 컬러 이미지는 3 채널 영상이라고 표현하기도 합니다. R, G, B 값은 0~255 값으로 이루어져 있으며, 256 × 256 × 256 = 16,777,216개 색상을 표현할 수 있습니다.
이렇듯 컬러 이미지는 매우 많은 정보를 담고 있기 때문에 그레스케일과 이진화 를 통해 정보량을 줄여줄 필요가 있습니다.
이미지에서 물체를 찾을 때는 색상은 필요 없이 흑백 이미지로도 검출이 가능합니다. grayscale
을 통해서 다중 채널(3채널) 이미지를 단일 채널로 변환하여 회색조 이미지로 변경함으로써 데이터 폭을 줄여 줍니다.
그레이스케일에서는 모든 색이 흑백이며, 0은 검은색을 나타내고 숫자가 커질수록(255) 하얀색에 가까워 집니다. 이미지가 갖고 있는 형태나 픽셀의 분포에는 크게 영향을 주지는 않지만, 데이터의 양이 1/3 가량 크게 줄어 연산량/정확도 등에 효과를 볼 수 있습니다.
Image Thresholding 혹은 Image Binarization 으로 불리는 이진화는, 이미지 내 객체와 배경을 분리하기 위해 0과 1의 두가지 값으로 픽셀을 조정하는 것을 말합니다. 디지털 컴퓨팅 영역에서는 0 or 1로 설정하지만 영상의 이진화에서는 픽셀값을 0 또는 255로 설정합니다.
grayscale
적용하여 0~255의 픽셀값을 갖도록 변경한 이미지에 대해 threshold
임계값을 기준으로 픽셀을 흑과 백으로 구분하여 물체의 검출 정확도를 높이고, 연산량을 줄일 수 있습니다. (픽셀값이 특정 값 보다 높으면 255, 낮으면 0)
주요 thresholdTypes
속성 | 설명 |
---|---|
THRESH_BINARY | 임계값 초과 시 최대값(maxval), 그외 0 |
THRESH_BINARY_INV | 임계값 초과 시 0, 그외 최대값(maxval) |
THRESH_TRUNC | 임계값 초과 시 임계값, 그외 유지 |
THRESH_TOZERO | 임계값 초과 시 유지, 그외 0 |
THRESH_TOZERO_INV | 임계값 초과 시 0, 그외 유지 |
THRESH_OTSU | 오츠 알고리즘 이용하여 자동 임계값 설정(단일 채널 이미지만 가능) |
THRESH_TRIANGLE | 삼각형 알고리즘 이용하여 자동 임계값 설정(단일 채널 이미지만 가능) |
배경과 객체 두 영역을 구분하는 픽셀값을 찾는 것이 중요한 데, 가장 많이 사용하는 것은 Otsu
방법 입니다. Otus 알고리즘은 thresh 값을 사용자가 임의로 정하는 것이 아니라, 자동으로 정해지도록 하는 일종의 최적화 알고리즘 입니다. 입력 영상이 배경과 객체 두 개로 이뤄져있다고 전제하에(Bimodal) 왼쪽 클래스의 피크값은 배경값, 오른쪽 클래스의 피크값은 객체값이라 판단하고 이 분포를 가장 잘 나타내는(분산이 최소가 되는) 임계값 T를 찾는 것 입니다.
cv2.threshold(src, thresh, maxval, type, dst=None)
- src: 입력 영상. 다채널, 8비트 또는 32비트 실수형.
- thresh: 사용자 지정 임계값
- maxval: cv2.THRESHBINARY 또는 cv2.THRESH_BINARY_INV 방법 사용 시 최댓값. 보통 255로 지정.
- type: cv2.THRESH 로 시작하는 플래그. 자동 임계값 결정 방법 지정
- retval: 사용된 임계값
- dst: 출력 영상. src와 동일 크기, 동일 타입, 같은 채널 수.
import cv2
import matplotlib.pyplot as plt
image = cv2.imread('./images/stoner.jpg', cv2.IMREAD_COLOR)
#BGR 이미지에 grayscale 적용
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#grayscale 이미지에 이진화 적용, threshold값과 결과 이미지 리턴
th, dst = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
print('otsh threshold', th)
plt_imshow(["image", "gray", "thresh_image2"], [image, gray, dst])