#11-1. 영상의 이진화
이진화 Binarization
- 영상의 각 픽셀을 두 개의 분류로 나누는 작업
- ex. 객체 영역 - 배경 영역
- 중요도가 높은 관심 영역(ROI) - 그렇지 않은 비관심 영역
- 0 또는 255로 설정
- 보통 흰색, 검은색 픽셀로만 구성
- 특정값보다 크면 255, 작으면 0
- 특정값
- 임계값(threshold), 문턱치
- 0~255 사이의 정수 지정
- 사용자 경험에 의해 임의 지정, 영상 특성 분석하여 자동 결정
- 임계값에 따라 이진화 영상의 의미 달라짐
- 활용 : 지문 인식 전처리, 문서 스캔, 마커 구분
OpenCV에서의 이진화
-
threshold(src, dst, thresh, maxval, type)
- maxval : 결과 영상의 최댓값 (보통 255)
-
ThresholdTypes
- THRESH_OTSU, THRESH_TRIANGLE : 임계값 자동 결정 → 논리합으로 위의 상수와 함께 사용
-
THRESH_OTSU
- Otsu(오츠)가 제안한 최적의 임계값을 결정하는 알고리즘
- 얼마나 균일한지 확인(분산)
- sum(영역n번의분산 * 영역n번의가중치)의 최솟값
- 이전 항 바탕으로 다음 항 산출 : 0~255 연산량 대폭 감소
-
THRESH_TRIANGLE
-
과정
- background estimation
- background removal
- recursive Otsu Thresholding
- Selective Bilateral Filtering (노이즈 제거)
- Recursive Otsu Thresholding with Hysteresis (edge 탐색)
def on_threshold(pos):
_, dst = cv2.threshold(src, pos, 255, cv2.THRESH_BINARY)
cv2.imshow('dst', dst)
cv2.namedWindow('dst')
cv2.createTrackbar('Threshold', 'dst', 0, 255, on_threshold)
cv2.setTrackbarPos('Threshold', 'dst', 128)
적응형 이진화
-
전역 이진화 global binarization
- 영상의 모든 픽셀에 같은 임계값을 적용하여 이진화를 수행하는 방식
- 균일하지 않은 조명 환경에서 촬영된 영상에 적용 X
-
적응형 이진화 adaptive binarization
- 각 픽셀마다 서로 다른 임계값 적용
- 모든 픽셀에서 정해진 크기의 사각형 블록 영역 설정
- 블록 영역 내부의 픽셀값 분포로부터 고유의 임계값 결정하여 이진화
- μ(x,y): (x,y) 주변 블록 영역의 픽셀 값 평균 C : 임계값의 크기 조정하는 상수
-
adaptiveThreshold(src, dst, maxValue, adaptiveMethod, thresholdType, blockSize, C)
dst = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.TRESH_BINARY, bsize, 5)
#11-2. 모폴로지 연산
모폴로지
- 형태 또는 모양에 관한 학문 → 영상에서 객체의 형태 및 구조 분석, 처리
- 주로 이진 영상에서 객체의 모양 단순화, 잡음 제거 용도
- 구조 요소 structuring element
침식(erosion) & 팽창(dilation)
- 가장 기본이 되는 연산
- 침식 연산
- 객체 영역의 외곽 골고루 깎아내는 연산
- 전체적으로 객체 영역 축소, 배경 확대
- 구조 요소가 객체 영역 내부에 완전히 포함 → 고정점 위치 픽셀 = 255
- 팽창 연산
- 객체 외곽을 확대하는 연산
- 객체 영역 확대, 배경 영역 축소
- 구조 요소와 객체 영역이 한 픽셀이라도 만날 경우 → 고정점 위치 픽셀 = 255
- getStructuringElement(shape, ksize, anchor = Point(-1, -1))
- 구조 요소 행렬 간단히 생성
- MORPH_RECT : 사각형 모양의 구조 요소 MORPH_CROSS : 십자가 모양의 구조 요소 MORPH_ELLIPSE : 타원 모양의 구조 요소 → 지정한 구조 요소 크기의 사각형에 내접하는 타원 이용
- anchor = Point(-1, -1) → 구조 요소 중앙을 십자가 중심 좌표로 사용
- 침식 erode(src, kernel, anchor=Point(-1, -1), iterations = 1, borderType = BORDER_CONSTANT, borderValue = morphologyDefaultBorderValue())
- 팽창 dilate(src, kernel, anchor=Point(-1, -1), iterations = 1, borderType = BORDER_CONSTANT, borderValue = morphologyDefaultBorderValue())
_, src_bin = cv2.threshold(src, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
dst1 = cv2.erode(src_bin, None)
dst2 = cv2.dilate(src_bin, None)
plt.subplot(221), plt.axis('off'), plt.imshow(src, 'gray'), plt.title('src')
plt.subplot(222), plt.axis('off'), plt.imshow(src_bin, ' gray'), plt.title('src_bin')
plt.subplot(223), plt.axis('off'), plt.imshow(dst1, 'gray'), plt.title('erode')
plt.subplot(224), plt.axis('off'), plt.imshow(dst2, 'gray'), plt.title('dilate')
plt.show()
이진 영상의 열기와 닫기
- 열기 연산
- 침식 연산 → 팽창 연산
- 한두 픽셀짜리 영역 제거 → 작은 크기의 객체 효과적으로 제거
- 닫기 연산
- 팽창 연산 → 침식 연산
- 작은 구멍 메워진 후 침식 연산 수행 → 객체 내부의 작은 구멍 제거
- morphologyEx(src, op, kernel, anchor=Point(-1,-1), iterations=1, borderType=BORDER_CONSTANT, borderValue=morphologyDefaultBorderValue())
-
MORPH_ERODE : 침식연산
-
MORPH_DILATE : 팽창 연산
-
MORPH_OPEN : 열기 연산
-
MORPH_CLOSE : 닫기 연산
-
MORPH_GRADIENT : 모폴로지 그래디언트 연산
→ dst = dilate(src, element) - erode(src, element)
→ 객체 외곽선 추출
_, src_bin = cv2.threshold(src, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
dst1 = cv2.morphologyEx(src_bin, cv2.MORPH_OPEN, None)
dst2 = cv2.morphologyEx(src_bin, cv2.MORPH_CLOSE, None)