- 이진화 : 특정 값을 기준으로 흑과 백만 가지게 하는 binary 작업
기본적인 threshold함수 사용
import cv2
img = cv2.imread('book.jpg',cv2.IMREAD_GRAYSCALE)
ret, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 2개의 값을 얻을 수 있음 = cv2.threshold(대상 사진, 임계값(기준점), 임계값보다 클 때 변할 목표, ???)
# 위에선 임계값 127보다 크면 255 하얗게 변하고 그 외엔 검은색으로 변함
cv2.imshow('img',img)
cv2.imshow('binary',binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
- Threshoid (임계값) : 기준점과 같은 의미, 주어진 시간과 상황에 따라 기준이 달라질 수 있음을 의미
Trackbar를 활용해 실시간 변화 확인
import cv2
def empty(pos):
#print(pos)
pass
img = cv2.imread('book.jpg',cv2.IMREAD_GRAYSCALE)
name = 'Trackbar'
cv2.namedWindow(name) #트랙바를 사용하고자 할 땐 미리 윈도우의 이름을 정의해주어야 한다
cv2.createTrackbar('threshold', name, 127,255, empty)
#cv2.createTrackbar(이름, 창의 이름, 초기값, 최댓값, 이벤트 처리)
while True:
thresh = cv2.getTrackbarPos('threshold', name) #트랙바이름, 창 이름 둘 다 입력하면 트랙바의 position을 가져얼 수 있음
ret, binary = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY)
if not ret:
break
cv2.imshow(name, binary)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()
threshold 작동원리를 확인할 수 있는 코드

import cv2
def empty(pos):
#print(pos)
pass
img = cv2.imread('위 예시 사진',cv2.IMREAD_GRAYSCALE)
name = 'Trackbar'
cv2.namedWindow(name) #트랙바를 사용하고자 할 땐 미리 윈도우의 이름을 정의해주어야 한다
cv2.createTrackbar('threshold', name, 127,255, empty)
#cv2.createTrackbar(이름, 창의 이름, 초기값, 최댓값, 이벤트 처리)
while True:
thresh = cv2.getTrackbarPos('threshold', name) #트랙바이름, 창 이름 둘 다 입력하면 트랙바의 position을 가져얼 수 있음
ret, binary = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY)
if not ret:
break
cv2.imshow('img', img)
cv2.imshow(name, binary)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()
- 첫번째 검은색은 임계값이 0 이므로 계속 검은색유지
- 두번째 진한회색은 임계값이 127이므로 127이상부터 검은색
- 세번째 밝은 회색은 임계값이 195이므로 그전까지 흰색 그 후 검
- 네번째 흰색은 255까지 흰색 유지
Adaptive Threshold
- 동일 이미지 내에서 조명이 다른 영역에 대해서도 좋은 결과를 얻을 수 있다
import cv2
def empty(pos):
# 트랙바가 변경될 때마다 호출되는 콜백 함수
pass
img = cv2.imread('book.jpg',cv2.IMREAD_GRAYSCALE)
name = 'Trackbar'
cv2.namedWindow(name)
cv2.createTrackbar('block_size', name, 25,100, empty) # 'block_size'라는 이름의 트랙바를 생성하고 초기값을 25, 최대값을 100으로 설정
cv2.createTrackbar('c', name, 3,10, empty) # 'c'라는 이름의 트랙바를 생성하고 초기값을 3, 최대값을 10으로 설정
while True: # 무한 루프를 시작
block_size = cv2.getTrackbarPos('block_size', name) # 'block_size' 트랙바의 현재 위치 값을 가져온다
c = cv2.getTrackbarPos('c',name) # 'c' 트랙바의 현재 위치 값을 가져온다
if block_size <= 1: # block_size 값이 1 이하일 경우 3으로 변경, 이는 이진화를 위한 블록 크기가 최소 3이어야 하기 때문
block_size = 3
if block_size % 2 == 0: # block_size 값이 짝수일 경우 홀수로 변경, 이는 이진화를 위한 블록 크기가 홀수이어야 함
block_size += 1
binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, block_size, c) # 적응형 이진화를 적용하여 이진 이미지를 생성
cv2.imshow(name, binary)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()
오츠 알고리즘(OTSU Algorithm)
- Bimodal Image에 사용하기 적합 (최적의 임계치를 자동으로 발견)
- Bimodal Image(바이모달)이미지란 히스토그램 상에서 두 개의 피크를 치는 형태의 이미지
import cv2
img = cv2.imread('book.jpg',cv2.IMREAD_GRAYSCALE)
ret, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 기본 threshold 함수
ret, otsu = cv2.threshold(img, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
#otsu Algorithm을 사용한 함수
#cv2.threshold(img, 초기값에 무엇을 넣든 오츠에선 무시가 됨, 최댓값, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print('otsu threshold',ret)
cv2.imshow('img',img)
cv2.imshow('binary',binary)
cv2.imshow('otsu',otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
- print 결과 : otsu threshold 110.0