티스토리 뷰

반응형
[영상처리] 오츠의 알고리즘(Otsu Algorithm, Thresholding)

오츠의 알고리즘이란?

어떤 영상을 thresholding 하고 싶을 때, 적정한 threshold 값을 찾아주는 알고리즘을 말한다.

방법은 경게값을 임의로 정해서 픽셀들을 두 부류로 나누고 두 부류의 명암 분포를 반복해서 구한 다음 두 부류의 명암 분포를 가장 균일하게 하는 경게 값을 선택한다. 다시말해, 특정 threshold를 T라 하면, T를 기준으로 이진 분류된 픽셀의 비율의 차가 가장 작은 optimal T를 구하는 것이다.

오츠 알고리즘은 모든 threshold에 대해 계산해야 하기 때문에 속도가 느리다는 단점이 있다. 또한 노이즈가 많은 영상에는 오츠의 알고리즘을 적용해도 좋은 결과를 얻지 못하는 경우가 있다.

코드

python의 opencv 라이브러리를 사용하면 쉽게 구현할수 있다.

cv2.threshold() 를 이용하는 것인데, threshold함수의 type파라미터로 cv2.THRESHD_OTSU 인자를 넣어주면 otsu threshold인 임계값과 해당 임계값을 기준으로하는 이미지가 반환된다.

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('sample.png', cv2.IMREAD_GRAYSCALE)

# 130을 threshold로 하는 이미지
_, t_130 = cv2.threshold(img, 130, 255, cv2.THRESH_BINARY)
# otsu algorithm을 적용한 이미지
t, t_otsu = cv2.threshold(img, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print('otsu threshold:', t)

imgs = {'Original': img, 't:130':t_130, f'otsu:{t:.0f}': t_otsu}
for i, (key, value) in enumerate(imgs.items()):
    plt.subplot(1, 3 , i+1)
    plt.title(key)
    plt.imshow(value, cmap='gray')
    plt.xticks([])
    plt.yticks([])
plt.show()

위의 코드를 실행하면 가장 왼쪽 이미지가 원본이고, 가운데는 threshold가 130일때이다. 가장 오른쪽 그림은 otsu 알고리즘을 적용했을 때 optimal threshold는 29이고, 29를 기준으로 이진화 했을 때의 이미지이다.

참고자료

[도서] 파이썬으로 만드는 OpenCV 프로젝트

[블로그] 영상이진화 (binarization, thresholding)

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday