Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 이진 영상 처리 - 자동 이진화 - Otsu 방법

AI 꿈나무 2020. 10. 10. 17:36
반응형

황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다.

 

예제 코드 출처 :  황선규 박사님 github홈페이지

 

『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』

예제 소스 코드는 아래 링크를 참고하세요

sunkyoo.github.io


자동 이진화

 영상 이진화 처리시 임계값은 경험에 의존해 임계값을 설정하는 것이 일반적입니다.

 하지만 영상이 조명이나 환경에 따라서 픽셀 값이 미세하게 변화합니다.

 영상마다 사용할 수 있는 임계값이 있는데 임계값을 자동으로 설정해주는 방법이 있습니다.

 가장 유명한 방법인 Otsu 이진화 방법에 대해 알아보겠습니다.

Otsu 이진화 방법

 이진화의 임계값을 구분하는 가장 좋은 방법으로 많이 이용하고 있습니다.

 입력 영상이 배경(background)과 객체(object) 두 개로 구성되어 있다고 가정하겠습니다.

 이를 Bimodal histogram 이라고 합니다.

 

Bimodal histogram

 

 Otsu 이진화는 Bimodal histogram인 경우에 적용이 가능합니다.

 임의의 임계값 T에 의해 나눠지는 두 픽셀 부포의 분산이 최소가 되는 T를 선택하는 방법입니다.

 

Ostu 이진화 알고리즘

 

 Otus 이진화는 그룹 내 분산과 그룹 간 분산을 이용합니다.

 

 

 그룹 내 분산을 최소로 하는 곳을 임계값으로 설정합니다.

 T가 1~255까지 다 계산하는데 이 계산이 너무 오래 걸리므로 그룹 간 분산을 이용합니다.

 

 

 모든 t값에 대해 그룹 간 분산을 구하여 최적의 T를 선택합니다

 하지만 연산속도가 너무 오래 걸립니다.

 

 Otsu는 Recursion을 이용해 효율적으로 계산하여 연산속도를 높였습니다.

 

 

 이전의 값들을 이용하는 recursion 방식으로 연산 속도를 높였습니다.

 

Otsu 방법을 이용한 자동 이진화 - cv2.threshold

 OpenCV에서 cv2.threshold 함수는 Otsu 이진화 계산을 지원합니다.

 type flag에 cv2.THRESH_OTSU를 입력해주면 됩니다.

 

 예제 코드를 살펴보겠습니다.

 

src = cv2.imread('rice.png', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

# or 연산자로 OTSU 인자 입력
# 반환값 2개, 1개는 OTSU 임계값(실수형), 1개는 dst영상
# cv2.THRESH_OTSU 만 입력해도 됌
th, dst = cv2.threshold(src, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print("otsu's threshold:", th)  # 131

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

 

 주의할 점은 반환값이 두 개가 리턴된다는 것입니다.

 첫 번째 반환값은 Otsu 이진화로 계산한 임계값을 반환합니다.

 두 번째 반환값은 최종 영상 정보를 반환합니다.

 

 위 코드를 실행시켜 보겠습니다.

 

원본 영상

 

Otsu 이진화 영상

 

 이처럼 이진화 처리가 된 것을 확이할 수 있습니다.

 

반응형