본문 바로가기
Python

[python] [OpenCV] image thresholding, 이미지 임계값 처리

by Chandler.j 2022. 5. 23.
반응형

fig1. title

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()

fig2. parameters of 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()

fig3. output of sample code

2. adaptive

- simple thersholding의 경우 이미지 전체에 적용하기 --> 일부 영역이 흑 or 백이 될 문제가 있음.

- 작은 영역별로 thrsholding을 진행하는 방법

cv2.adaptiveTreshold()

fig4. parameters of 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()

fig5. output of sample code


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

  1. 임계값을 임의로 정해 픽셀을 두 부류로 나누고 두 부류의 명암 분포를 구하는 작업 반복
  2. 모든 경우의 수 중에서 두 부류의 명암 분포가 가장 균일할 때의 값을 임계값으로 선택
  3. 최적의 임계값을 자동으로 찾아주지만 모든 경우의 수 계산 시간이 오래걸림.
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()

fig6. output of sampel code1

 

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()

fug7. output of sampel code2

 

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 


TOP

Designed by 티스토리