0. image thresholding
1. simple
2. adaptive
3. otsu's
0. image thresholding
이미지 이진화 : threshold(임계값)에 따라 흑백을 정함.
- pixel's value> threshold : 백
- pixel's value < threshold : 흑
1. simple
- 이미지 전체에 고정된 임계값 적용
cv2.threshold()
*thresholding type
- cv2.THRESH_BINARY : pixel's value > threshold --> value, or 0
- cv2.THRESH_BINARY_INV : 위의 반대
- cv2.THRESH_TRUNC : pixel's value > threshold --> value, or pixel's value
- cv2.THRESH_TOZERO : pixel's value > threshold --> pixel's value, or 0
- cv2.THRESH_TOZERO_INV : 위의 반대
sample code
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('gradient.jpeg',0)
ret, thresh1 = cv2.threshold(img,127,255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img,127,255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img,127,255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img,127,255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img,127,255, cv2.THRESH_TOZERO_INV)
titles =['Original','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img,thresh1,thresh2,thresh3,thresh4,thresh5]
for i in range(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
2. adaptive
- simple thersholding의 경우 이미지 전체에 적용하기 --> 일부 영역이 흑 or 백이 될 문제가 있음.
- 작은 영역별로 thrsholding을 진행하는 방법
cv2.adaptiveTreshold()
*Adaptive Method
- cv2.ADAPTIVE_THRESH_MEAN_C : 주변영역의 평균값으로 결정
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 가우시안 분포에 따른 가중치의 합으로 결정
sample code
# import 부분 생략
img = cv2.imread('sudoku.jpeg',0)
# img = cv2.medianBlur(img,5)
ret, th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,15,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,15,2)
titles = ['Original','Global','Mean','Gaussian']
images = [img,th1,th2,th3]
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
3. otsu's
- simple thresholding 이나 adaptive thresholding 방법에서 threshold 값 설정 : manual
- threshold 값 설정
- 일반적인 방법 : trial and error
- biomodal image (histogram에서 two peak 이미지)의 경우 : Otsu's binarization method
- Otsu's binarization method
- 임계값을 임의로 정해 픽셀을 두 부류로 나누고 두 부류의 명암 분포를 구하는 작업 반복
- 모든 경우의 수 중에서 두 부류의 명암 분포가 가장 균일할 때의 값을 임계값으로 선택
- 최적의 임계값을 자동으로 찾아주지만 모든 경우의 수 계산 시간이 오래걸림.
cv2.threshold() # cv2.THRESH_OTSU, threshold=0 or 아무 숫자 (THRESH_OTSU 적용시 무시됨)
sample code1
# sample code1
# import 부분 생략
# 이미지를 그레이 스케일로 읽기
img = cv2.imread('paper.jpeg', cv2.IMREAD_GRAYSCALE)
# 경계 값을 130으로 지정 ---①
_, t_130 = cv2.threshold(img, 130, 255, cv2.THRESH_BINARY)
# 경계 값을 지정하지 않고 OTSU 알고리즘 선택 ---②
t, t_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print('otsu threshold:', t) # Otsu 알고리즘으로 선택된 경계 값 출력
imgs = {'Original': img, 't:130':t_130, 'otsu:%d'%t: 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()
sample code2
# sample code2
#import 부분 생략
img = cv2.imread('noise.png',0)
# global thresholding
ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# Otsu thresholding
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# gaussian blur - noise 제거
blur = cv2.GaussianBlur(img,(5,5),0)
# nosie 제거된 img에 Otsu thresholding
ret3, th3 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# plot all the images and their histograms
images = [img, 0, th1, img, 0, th2, blur, 0, th3]
titles = [
'Original Noisy Image','Histogram','Global Thresholding (v=127)',
'Original Noisy Image','Histogram',"Otsu's Thresholding",
'Gaussian filtered Image','Histogram',"Otsu's Thresholding"
]
for i in range(3):
plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'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],'gray')
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()
ref :
https://opencv-python.readthedocs.io/en/latest/doc/09.imageThresholding/imageThresholding.html
https://bkshin.tistory.com/entry/OpenCV-8-%EC%8A%A4%EB%A0%88%EC%8B%9C%ED%99%80%EB%94%A9Thresholding