앞서 thresholding 포스팅에 이어 Otsu's Binarization(오츠의 이진화)에 대해 알아보고
OpenCV에서 어떻게 사용하는지 알아보겠습니다.
포스팅 관련 내용은 아래에서 출처를 얻어 사용하였습니다.
https://docs.opencv.org/4.5.2/d7/d4d/tutorial_py_thresholding.html
Otsu's Binarization (오츠의 이진화)
- 이전 thresholding 방법들은 임계값을 직접 설정해줘야 하며, 설정해주지 않더라도 계산하는 방법을 설정하였습니다.
하지만 영상은 조명에 따라 픽셀 값이 미세하게 변화합니다. 영상마다 사용할 수 있는 임계값을 자동으로 설정해주는 방법이 있는데 그중에 가장 유명한 Otsu's Binarization (오츠의 이진화)에 대해 알아보겠습니다.
- 오츠의 이진화는 이미지의 히스토그램이 두 개의 피크로 구성되는 Bimodal image에 적용이 가능합니다.
좋은 임계값은 이 두 개의 피크 값의 중간에 있고, 오츠의 방법은 이미지 히스토그램에서 최적의 임계값을 결정합니다.
Otsu's Binarization Algorithm (오츠 이진화 알고리즘)
- 오츠 이진화 알고리즘은 Bimodal 히스토그램으로 작업하기 때문에 그룹 내의 분산을 최소로 하는 임계값으로 설정합니다. 모든 t값에 대해 계산을 하기 때문에 연산속도가 오래 걸려 Recursion을 이용해 효율적으로 계산하여 연산 속도를 올렸습니다.
Otsu's Binarization in OpenCV
- OpenCV에서 cv2.threshold 함수로 Otsu 이진화를 지원합니다.
cv2.threshold의 type을 cv2.THRESH_OTSU를 입력하여 적용합니다.
코드)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('./images/noise_img.png', 0)
# 전역 스레시홀딩
_, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 오츠 스레시홀딩
_, th2 = cv2.threshold(img, 127, 255, cv2.THRESH_OTSU)
# 가우시안 필터 후 오츠 스레시홀딩
blur = cv2.GaussianBlur(img, (5,5), 0 )
_, th3 = cv2.threshold(blur, 127, 255, cv2.THRESH_OTSU)
# 이미지 및 이미지의 히스토그램 출력
images = [img, 0, th1,
img, 0, th2,
blur, 0, th3]
titles = ['Original Nosie Image', 'Histogram', 'Global Thresholding ( v = 127 )',
'Original Nosie Image', 'Histogram', "Otsu's Thresholding",
'Gaussian Image', 'Histogram', "Otsu's Thresholding"]
for i in range(3):
plt.subplot(3, 3, i*3+1)
plt.imshow(images[i*3], cmap = 'gray')
plt.title(titles[i*3])
plt.xticks([]), plt.yticks([])
plt.subplot(3, 3, i*3+2)
plt.hist(images[i*3].ravel(), 256)
plt.title(titles[i*3+1])
plt.xticks([]), plt.yticks([])
plt.subplot(3, 3, i*3+3)
plt.imshow(images[i*3+2], cmap = 'gray')
plt.title(titles[i*3+2])
plt.xticks([]), plt.yticks([])
plt.show()
결과)
- 결과에서 가우시안 필터링을 하지 않은 히스토그램들은 Bimodal Histogram처럼 보이진 않습니다.
그래서 결과에 큰 차이가 없으며 이진화 처리도 잘 되지 않은 모습을 볼 수 있고 가우시안 필터링을 거친 마지막 이미지는 히스토그램을 통해 최적의 임계값을 찾아 블러링 처리하지 않은 이미지보다 이진화가 잘 된 것을 볼 수 있습니다.
이번 포스팅은 오츠의 이진화에 대해 알아보았고 틀린 점이나 질문이 있으시면 댓글을 남겨주세요!
다음 포스팅으로 찾아오겠습니다 :)
'영상처리' 카테고리의 다른 글
Python - OpenCV (12) : Segmentation with Watershed (0) | 2021.07.19 |
---|---|
Python - OpenCV (11) : Grayscale 함수 비교 (2) | 2021.07.16 |
Python - OpenCV (9) : Image Thresholding (0) | 2021.07.14 |
Python - OpenCV (8) : k-means Clustering (0) | 2021.07.13 |
Python - OpenCV (7) : Background Subtraction (0) | 2021.07.11 |