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

8장. Threshold, Adaptive Threshold, Otsu

임계값을 고르는 어려움

커트라인을 너무 낮게 잡으면 거의 모두 합격하고, 너무 높게 잡으면 거의 모두 떨어집니다. 시험 점수 분포를 그려 보니 "잘한 무리"와 "못한 무리"가 두 언덕으로 뚜렷이 나뉘어 있다면, 두 언덕 사이의 낮은 곳에 커트라인을 두는 것이 가장 자연스럽습니다.

부품 그림의 히스토그램에 임계값 70, 136, 195 를 세로선으로 긋고 아래에 세 결과를 놓은 그림

위의 막대는 4장에서 배운 히스토그램으로, 밝기를 8 씩 묶은 32개 구간으로 그렸습니다. 왼쪽 봉우리(60~110)가 부품, 오른쪽 봉우리(180~210)가 작업대입니다. 갈색 선 70 은 부품 봉우리 한가운데라 와셔와 짙은 동전 하나만 검게 남고, 다홍 선 195 는 작업대 봉우리 한가운데라 작업대의 왼쪽 위 절반까지 검게 칠해집니다. 초록 선 136 처럼 두 봉우리 사이의 골짜기에 두면 부품만 깨끗하게 나뉩니다. 여기서 두 언덕이 두 봉우리이고, 언덕 사이 낮은 곳이 골짜기입니다.

임계값이 어긋날 때

임계값결과부품 그림에서
너무 낮다물체의 밝은 부분까지 바탕(흰색)으로 간다70: 동전 대부분이 사라진다
골짜기물체와 바탕이 깨끗이 나뉜다136: 부품만 검게 남는다
너무 높다바탕의 어두운 부분까지 물체(검정)로 간다195: 작업대가 비스듬히 반쯤 검어진다

195 에서 작업대가 비스듬히 갈리는 것은 작업대 밝기가 왼쪽 위 184 에서 오른쪽 아래 206 쯤까지 조금씩 바뀌도록 만들었기 때문입니다. 커트라인이 봉우리 안에 있으면 이런 작은 밝기 차이가 그대로 드러납니다.

짧은 예시

Python
import cv2

gray = cv2.imread("ch08_parts.png", cv2.IMREAD_GRAYSCALE)
for t in [70, 136, 195]:
    _, out = cv2.threshold(gray, t, 255, cv2.THRESH_BINARY)
    # 검정(0) 칸의 비율: 부품으로 본 칸이 그림의 몇 할인가
    black = round(float((out == 0).mean()), 3)
    print(f"임계값 {t}: 검정 칸 비율 {black}")

교안 PC 에서는 70 에서 0.063, 136 에서 0.176, 195 에서 0.662 가 나옵니다. 골짜기의 어디에 두든 거의 같습니다. 110 이면 0.173, 180 이면 0.182 입니다. 골짜기에는 칸이 거의 없기 때문입니다.

주의할 점

  • 골짜기는 히스토그램을 그려 눈으로 찾을 수 있지만, 사진이 수백 장이면 일일이 볼 수 없습니다. 뒤에서 볼 Otsu 가 이 일을 자동으로 합니다.
  • 실제 사진의 히스토그램은 이 그림처럼 봉우리가 또렷하지 않을 때가 많습니다. 봉우리가 하나뿐이거나 셋 이상이면 골짜기가 애매합니다.
← 이전 절8장 · 임계값 방식 다섯 가지다음 절 →8장 · 조명이 고르지 않을 때