1. 이진화
- 명암 영상을 흑과 백만 가진 이진 영상으로 변환하는 것. 이때 백은 0, 검은색은 255를 의미한다.
- 영상을 이진화하는데 이유는 여러가지의 이유가 있지만, 가장 중요한 이뉴는 어떠한 경계값을 기준으로 이진화를 시키면 물체가 뚜렷해지기 때문이다.
- 그럼 어떻게 화소의 명암값을 흑과 백 중 하나로 결정할 수 있을까?
- 간단히 생각해보자면 어떠한 임계값(T)을 지정해 두고, 그 화소의 값이 임계값보다 크다면 백, 작으면 흑으로 바꾸는 것이다.
cv2.threshold(이진화할 이미지경로, 임계값(T), x>T일때 적용할 값, thresholding type)
import cv2
img = cv2.imread('book.jpg', cv2.IMREAD_GRAYSCALE)
#threshold(불러올 이미지,임계값,값이 임계값보다 클때 적용할 value,tresholding type)
#ret : 이미지가 제대로 불러와졌는지에 대한 여부 리턴받음 (type: bool)
ret, binary = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow('img',img)
cv2.imshow('binary',binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
- thresholding type은 아래와 같다.
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
Trackbar를 이용하여 값 변화에 따른 변형 확인
import cv2
def empty(pos):
pass
img = cv2.imread('book.jpg', cv2.IMREAD_GRAYSCALE)
name = 'Trackbar'
cv2.namedWindow(name)
#createTrackbar(bar 이름, 창의 이름, 임계값, 최대값, 이벤트 처리함수)
cv2.createTrackbar('Threshold',name,127,255,empty)
while True:
#현재 Trackbar의 위치를 가져오는 함수.
#getTrackbarPos(bar 이름, 창의 이름)
thresh = cv2.getTrackbarPos('Threshold',name) # 트랙바의 포지션을 thresh 변수에 넣음(임계값을 우리가 임의로 지정할 수 있는 기능)
ret, binary = cv2.threshold(img,thresh,255,cv2.THRESH_BINARY_INV) # 우리가 임의로 지정한 임계값을 기준으로 이진화
if not ret: #더이상 보여줄 영상이 없다면
break
cv2.imshow(name,binary) #우리가 임의로 지정한 임계값으로 이진화한 이미지를 출력
if cv2.waitKey(1) == ord('q'):
break
cv2.distroyAllWindows()
cv2.waitKey(1)
Adaptive Threshold
- 이미지를 작은 영역으로 나누어서 임계치를 적용
src – grayscale image
maxValue – 임계값
adaptiveMethod – thresholding value를 결정하는 계산 방법
thresholdType – threshold
typeblockSize – thresholding을 적용할 영역 사이즈
C – 평균이나 가중평균에서 차감할 값
Adaptive Method는 아래와 같습니다.
cv2.ADAPTIVE_THRESH_MEAN_C : 주변영역의 평균값으로 결정
cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 주변영역의 가우시안 분포로 결정
import cv2
img = cv2.imread('book.jpg', cv2.IMREAD_GRAYSCALE)
block_size = 3
binary = cv2.adaptiveThreshold(img,125,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, block_size, c)
cv2.imshow(name,binary) #우리가 임의로 지정한 임계값으로 이진화한 이미지를 출력
if cv2.waitKey(1) == ord('q'):
break
cv2.distroyAllWindows()
cv2.waitKey(1)
- 하지만 임계값 방법은 단순한 반면 문제점을 안고 있다.
- 앞에서 우리는 이진화를 위한 임계값을 지정하기 위해 히스토그램에서 두 봉우리의 위치를 직접 확인하거나, Trackbar을 이용하여 최적의 임계값을 알아냈는데, 컴퓨터 비전에서는 그 일을 자동으로 처리해야 한다.
2. 오츠 알고리즘
- 오츠 알고리즘은 임계값을 우리가 임의로 정의해주지 않고도 자동으로 임계값을 지정하여 최적의 이진 영상을 만들어 준다.
- 하지만 오츠 알고리즘은 모든 이미지에 대해 최적의 임계값을 지정해 주는것은 아니다.
- 이미지 형태가 Bimoadl Image에 사용하기 적합(최적의 임계치를 자동으로 발견함) Bimoadl Image는 히스토그램상에서 두개의 피크를 치는 형태의 이미지를 의미한다.
import cv2
img = cv2.imread('book.jpg', cv2.IMREAD_GRAYSCALE)
#threshold(불러올 이미지,임계값,값이 임계값보다 클때 적용할 value,tresholding type)
ret, binary = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#오츠의 경우 자동으로 임계값을 찾으므로 그냥 초기 임계값을 -1로 지정함.
ret, otsu = cv2.threshold(img,-1,255,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()
cv2.waitKey(1)
'CV' 카테고리의 다른 글
OpenCV 기본 연산 (0) | 2022.10.22 |
---|---|
도형 그리기(직선, 사각형, 원, 타원, 다각형, 텍스트) (0) | 2022.10.22 |
연결 요소 (0) | 2022.10.22 |
히스토그램 평활화, 역투영(Equalized, Back-Projection) (0) | 2022.10.22 |
에지 검출 (Edge Detection) / Image Gradients (0) | 2022.10.18 |