다음 링크에서 오츠 이진화에 대해 잘 정리하여 참고
medipixel.github.io/post/2019-06-07-image-thresholding/
* 본 내용을 정리하면서 앞의 일부 내용들은 엉망이라 유의하자.
오츠 이진화
- 최적의 임계치를 찾아 영상을 이진화하는 알고리즘
- 흑색 영상과 백색 영상의 분산 가중 합을 가장 적게하는 임계치가 최적 임계치
- 위 내용을 대강 그림으로 그리면 히스토그램에 대해서 다음과 같다
인줄 알았는데
해당 블로그에서 hat h(t)에 대한 설명부분이나, between class variance에 대한 설명이 빠져있어
조금 해매버렸다.
이 블로그도 조금은 잘못됬지만 대강
클래스내 분산 within class variance와 클래스간 분산 between class variance에 대해서 보다 잘 설명해주고 있다.
다만 틀린 부분은
클래스 내 분산이 최소가 되도록 하는 임계치 t의 인덱스가 오츠 임계값이고,
이는 클래스간 분산이 최대가 되는것과 동일한 의미이다.
오츠 임계치를 다시 정리하면,
클래스 내 분산이 최소가 되는 인덱스나
클래스 간 분산이 최대가 되는 인덱스를 찾는 것이고
이 인덱스가 가장 잘 영상을 이진화 시키는 오츠 임계치 값이 된다.
이런 식으로 클래스 간 분산이 최대(클래스 내 분산이 최소)로 분할하는 임계치이다.
아래의 코드는 내가 구현한 오츠 임계치 함수인데
def otsuThreshold(img):
if type(img) is not np.ndarray:
raise AssertionError("img is not ndarray")
hist = Histogram(img)
vars_within = []
vars_between = []
zero = 1.e-17
for t in range(0, 256):
sumb = np.sum(hist[:t]) + zero
sumw = np.sum(hist[t:]) + zero
sum = sumb + sumw
wb = sumb/sum
ww = sumw/sum
mub = zero
muw = zero
for i in range(0, t):
mub += i * hist[i]/sumb
for i in range(t, 256):
muw += i * hist[i]/sumw
vb = zero
vw = zero
for i in range(0, t):
vb += hist[i] * ((i - mub)**2)/sumb
for i in range(t, 256):
vw += hist[i] * ((i - muw)**2)/sumw
var_within = wb * vb + ww * vw
vars_within.append(var_within)
th = vars_within.index(min(vars_within))
print(th)
res = Threshold(img, th)
return res
res = otsuThreshold(img)
위 함수를 사용한 결과 오츠 임계치는 96가 되며 아래의 이미지를 얻었다.
히스토그램으로 보면 가장 흑백 영상 클래스가 잘 분할하도록 분포하고 있다.
* 위 이미지 처리 관련 코드들은 사이킷런에서도 잘 구현되 있었다.
* 내것보다 유효성 검증, cumsum 같은 함수 사용, 인덱싱 처리에서 훨씬 간결하다.
ref : github.com/scikit-image/scikit-image/blob/master/skimage/filters/thresholding.py#L237
아무튼 이론과 구현에 대한 내용들은
learning opencv에서 잘 제공하고 있었다
www.learnopencv.com/otsu-thresholding-with-opencv/
'로봇 > 영상' 카테고리의 다른 글
컴퓨터 비전 알고리즘 구현 - 7. 가우시안 스무딩 (0) | 2020.11.30 |
---|---|
컴퓨터 비전 알고리즘 구현 - 6. 평균 스무딩 (0) | 2020.11.30 |
컴퓨터 비전 알고리즘 구현 - 4. 평균 기반 적응적 임계치 이진화 (0) | 2020.11.26 |
컴퓨터 비전 알고리즘 구현 - 3. 단순 이진화 (0) | 2020.11.26 |
컴퓨터 비전 알고리즘 구현 - 2. 이미지 히스토그램 (0) | 2020.11.26 |