OpenCV 비전 실무8장 · Threshold, Adaptive Threshold, Otsu4 / 21← 이전목차다음 →MetaContents

8장. Threshold, Adaptive Threshold, Otsu

전역 임계값과 cv2.threshold

학교가 전교생에게 커트라인 하나를 똑같이 적용하는 장면을 떠올려 봅시다. 어느 반 학생이든 60점이면 같은 결과를 받습니다. 그림 전체에 숫자 하나를 똑같이 대는 이진화를 전역 임계값이라고 하고, OpenCV 에서는 cv2.threshold 가 이 일을 합니다.

cv2.threshold 에 주는 src, thresh, maxval, type 의 네 인자를 나란히 놓은 비교 그림

그림의 네 상자가 cv2.threshold 에 주는 네 인자입니다. 흑백 그림(src), 커트라인 숫자(thresh), 넘은 칸에 넣을 값(maxval), 나누는 방식(type)을 차례로 줍니다. 여기서 전교생의 점수가 src, 커트라인이 thresh, "합격" 도장이 maxval, 합격·불합격을 어떻게 적을지가 type 입니다.

네 인자와 돌려주는 두 값

순서이름보통 값뜻
1src(source)gray이진화할 흑백 그림(uint8)
2thresh127임계값. 이 값보다 커야 넘은 것으로 친다
3maxval255넘은 칸에 넣을 값
4typecv2.THRESH_BINARY나누는 방식. 다음 절에서 다섯 가지를 본다
돌려줌 1retval(return value)127.0실제로 쓴 임계값(소수). Otsu 를 쓰면 자동으로 고른 값이 여기 온다
돌려줌 2dst(destination)결과 그림src 와 같은 크기의 그림

손으로 계산해 보기

칸 다섯 개 30, 100, 127, 128, 200 에 임계값 127, maxval 255, THRESH_BINARY 를 줍니다.

칸의 밝기127 보다 큰가결과
30아니다0
100아니다0
127아니다(같다)0
128크다255
200크다255

짧은 예시

Python
import cv2
import numpy as np

# 세로 1, 가로 5 짜리 아주 작은 흑백 그림
row = np.array([[30, 100, 127, 128, 200]], dtype=np.uint8)

# 돌려주는 값은 두 개: (쓴 임계값, 결과 그림)
ret, out = cv2.threshold(row,                 # src: 흑백 그림
                         127,                 # thresh: 임계값
                         255,                 # maxval: 넘은 칸에 넣을 값
                         cv2.THRESH_BINARY)   # type: 크면 maxval, 아니면 0
print(ret)                 # 결과: 127.0
print(out.tolist())        # 결과: [[0, 0, 0, 255, 255]]

ret 은 return(돌려주다)을 줄여 흔히 쓰는 이름입니다. 직접 127 을 주었으니 127.0 이 그대로 돌아옵니다. 이 값이 쓸모 있는 것은 Otsu 를 쓸 때입니다.

주의할 점

  • 돌려주는 값이 두 개라서 out = cv2.threshold(...) 로 받으면 out 이 튜플이 됩니다. ret, out = ... 이나 out = cv2.threshold(...)[1] 로 받습니다.
  • 인터넷 예제에는 _, out = cv2.threshold(...) 처럼 첫 값을 _ 로 버리는 꼴이 많습니다. "이 값은 쓰지 않는다"는 표시입니다.
← 이전 절8장 · 이진화란다음 절 →8장 · 임계값 방식 다섯 가지