728x90
이진화란?
-
이미지의 픽셀 값을 0 또는 255 로 만드는 연산이다.
-
원하는 피사체의 모양을 좀 더 정확히 판단 가능하다.
-
배경과 물체를 구분한다.
-
관심 영역, 비관심 영역을 구분한다.
cv2.threshold(src, threshold, maxval, type_falg, dst=None) -> retval, dst
- src: 입력 이미지
- threshold: 임계값
- maxval: cv2.THRESH_BINARY 또는 cv2.THRESH_BINARY_INV 방법 사용시 최대값 일반적으로는 255로 지정
- type: 임계값 함수 동작 지정 또는 자동 임계값 결정 방법 지정
- retval: 사용된 임계값(type 에서 자동 임계값 결정 방법 사용시 확인 가능)
- dst: 출력 이미지(src 와 동일)
- type_flag 종류
- cv2.THRESH_BINARY: src(x, y) > threshold 이면 maxval, 그렇지 않으면 0
- cv2.THRESH_BINARY_INV: src(x, y) > threshold 이면 0, 그렇지 않으면 maxval
- cv2.THRESH_TRUNC: src(x, y) > threshold 이면 threshold, 그렇지 않으면 src(x, y)
- cv2.THRESH_TOZERO: src(x, y) > threshold 이면 src(x, y), 그렇지 않으면 0
- cv2.THRESH_TOZERO_INV: src(x, y) > threshold 이면 0, 그렇지 않으면 src(x, y)
- cv2.THRESH_OTSU: otsu 알고리즘으로 임계값 결정
- cv2.THRESH_TRIANGLE: 삼각 알고리즘으로 임계값 결정
이진화 구현
넘파이를 이용한 구현
import os
import cv2
import numpy as np
path = os.path.join('image', 'gray_gradient.jpg')
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
thresh_np = np.zeros_like(img)
thresh_np[img > 127] = 255
cv2.imshow('img',img)
cv2.imshow('thresh_np', thresh_np)
cv2.waitKey()
cv2.destroyAllWindows()
threshold 를 이용
import os
import cv2
import numpy as np
path = os.path.join('image', 'gray_gradient.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
bz = np.zeros_like(src)
bz[src > 127] = 255
ret, thresh = cv2.threshold(src, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('src', src)
cv2.imshow('binarization', bz)
cv2.imshow('thresh', thresh)
cv2.waitKey()
cv2.destroyAllWindows()
트랙바를 이용하여 임계값에 따른 차이를 비교합니다.
import os
import cv2
path = os.path.join('image', 'sudoku.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
src = cv2.resize(src, None, fx=2, fy=2)
def onChange(val):
_, dst = cv2.threshold(src, val, 255, cv2.THRESH_BINARY)
cv2.imshow('binarization', dst)
cv2.imshow('binarization', src)
cv2.createTrackbar('level', 'binarization', 0, 255, onChange)
cv2.waitKey()
cv2.destroyAllWindows()
otsu (cv2.THRESH_OTSU)
otsu 이진화는 자동으로 임계값을 구하는 알고리즘입니다.
- 임계값을 임의로 정해서 픽셀들을 두 개의 클래스로 나눔.
- 두 클래스의 intensity 의 분포를 반복해서 구하고, 두 클래스의 intensity 분포를 가장 균일하게 하는 임계값을 찾음.
cv2.threshold(src, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
import os
import cv2
import numpy as np
import matplotlib.pylab as plt
path = os.path.join('image', 'scaned_paper.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
t, t_otsu = cv2.threshold(src, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print(t)
cv2.imshow('src', src)
cv2.imshow('otsu', t_otsu)
cv2.waitKey()
cv2.destroyAllWindows()
otsu 알고리즘이 찾은 임계값은 t 입니다.
t, t_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print(t)
131.0
Adaptive Threshold
적응형 스레시홀드로 이미지를 여러 영역으로 나눈 다음 각각의 임계값을 구하는 과정을 거칩니다.
영상 내 조명이 균일하지 않거나 배경색이 여러가지인 경우 정확한 이진화가 어렵습니다.
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None) -> dst
- src: 입력 이미지
- maxValue: 임계값 함수 최대값(일반적으로 255)
- adaptiveMethod: 블록 평균 계산 방법
- cv2.ADAPTIVE_THRESH_MEAN_C: 산술평균
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 가우시안(Gaussian) 가중치 평균
- thresholdType: cv2.THRESH_BINARY / cv2.THRESH_BINARY_INV
- blockSize: 블록 크기 (3 이상의 홀수)
- C
- dst: 출력 이미지
import os
import numpy as np
import cv2
import matplotlib.pylab as plt
path = os.path.join('image', 'sudoku.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
t, t_otsu = cv2.threshold(src, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
at = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 55, 5)
cv2.imshow('src', src)
cv2.imshow('otsu', t_otsu)
cv2.imshow('at', at)
cv2.waitKey()
cv2.destroyAllWindows()
트랙바를 이용해서 블록크기에 따른 차이를 비교합니다.
import os
import numpy as np
import cv2
path = os.path.join('image', 'sudoku.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
src = cv2.resize(src, None, fx=2, fy=2)
def onChange(val):
if val < 3:
cv2.imshow('adaptiveThreshold', src)
if val % 2 == 0:
val = val - 1
dst = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, blockSize=val, C=5)
cv2.imshow('adaptiveThreshold', dst)
cv2.imshow('adaptiveThreshold', src)
cv2.createTrackbar('block size', 'adaptiveThreshold', 0, 200, onChange)
cv2.waitKey()
cv2.destroyAllWindows()
'OpenCV' 카테고리의 다른 글
파이썬 OpenCV 라벨링(Labeling) (0) | 2020.07.26 |
---|---|
파이썬 OpenCV 외곽선 검출(Contours) (0) | 2020.07.26 |
파이썬 OpenCV 모폴로지(Morphology) -2 : Gradient / Tophat / Blackhat (0) | 2020.07.26 |
파이썬 OpenCV 모폴로지(Morphology) -1: 침식(erode) / 팽창(dilate) /Opening & Closing (0) | 2020.07.26 |
파이썬 OpenCV 미분 필터링 -3 : Canny (0) | 2020.07.26 |