- 외곽선 검출이란?
- 객체의 외곽선 좌표를 모두 추출하는 작업. Boundary tracking. Contour tracing.
- 바깥쪽 & 안쪽(홀) 외곽선 -> 외곽선의 계층 구조도 표현 가능
- 외곽선 객체 하나의 표현 방법
- numpy.ndarray
- shape=(K,1,2) (K는 외곽선 좌표 개수)
- dtype=numpy.int32
- 여러 외곽선 표현 방법
- "객체 하나의 외곽선(numpy.ndarray)"을 원소로 갖는 리스트
- len(리스트)=전체 외곽선 개수(N)
- 외곽선 검출 함수
cv2.findContours(image,mode,method,contours=None,hierarchy=None,offset=None) -> contours,hierachy
• image: 입력 영상 . non zero 픽셀을 객체로 간주함
• mode: 외곽선 검출 모드 . cv2.RETR_ 로 시작하는 상수
• method: 외곽선 근사화 방법 . cv2.CHAIN_APPROX_ 로 시작하는 상수
• contours: 검출된 외곽선 좌표 . numpy.ndarray 로 구성된 리스트
len (contours)= 전체 외곽선 개수 (N)
contours[ i ]. shape=(K, 1, 2). contours[i].dtype=numpy.int32
• hierarchy: 외곽선 계층 정보 . numpy.ndarray.shape=(1,N,4). dtype numpy.int32
hierarchy[0,i ,0] ~ hierarchy[0,i,3] 이 순서대로 next, prev , child, parent
외곽선 인덱스를 가리킴 . 해당 외곽선이 없으면 -1.
• offset: 좌표 값 이동 옵셋 . 기본값은 (0,0)
- 외곽선 그리기
cv2.drawContours(image,contours,contourIdx,color,thickness=None,
LineType=None,hirarchy=None,maxLevel=None,offset=None) -> image
• image: 입출력 영상
• contours:contours: (cv2.findContours() 함수로 구한) 외곽선 좌표 정보
• contourIdx: 외곽선 인덱스 . 음수 (-1) 를 지정하면 모든 외곽선을 그린다
• color: 외곽선 색상
• thickness: 외곽선 두께 . thinkness < 0 이면 내부를 채운다
• lineType : LINE_4, LINE_8, LINE_AA 중 하나 지정
• hierarchy: 외곽선 계층 정보 .
• maxLevel : 그리기를 수행할 최대 외곽선 레벨 . maxLevel = 0 이면 contourIdx 로
지정된 외곽선만 그린다 .
- 계층 정보를 사용하는 외곽선 검출 예제
import sys
import random
import numpy as np
import cv2
src = cv2.imread('contours.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
contours,hier=cv2.findContours(src,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
dst=cv2.cvtColor(src,cv2.COLOR_GRAY2BGR)
idx=0
while idx>=0:
c=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
cv2.drawContours(dst,contours,idx,c,2,cv2.LINE_8,hier)
#hier 는 외각선 계층 정보로 이것을 지우면 제일 바깥부분만 색이 칠해진다
#그런데 findContours에서 cv2.RETR_LIST를 사용하면 계층정보가 없으므로 hier인자가 있든 없든 상관이 없다
idx=hier[0,idx,0] #hier[0,i,0]~hier[0,i,3]이 순서대로 next,prev,child,parent
cv2.imshow('src',src)
cv2.imshow('dst',dst)
cv2.waitKey()
cv2.destroyAllWindows()
- 계층 정보를 사용하지 않는 외곽선 검출 예제
'''
1,2 방법 모두 알아놓는게 좋다
2번방법이 더 쉬울수도 있다.
'''
import sys
import random
import numpy as np
import cv2
src = cv2.imread('milkdrop.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
_,src_bin=cv2.threshold(src,0,255,cv2.THRESH_OTSU)
contours,_=cv2.findContours(src_bin,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
#list 로 받았기 때문에 hier받을 필요 없음
#contours의 길이가 외각선 객체의 갯수가 된다
h,w=src.shape[:2]
dst=np.zeros((h,w,3),np.uint8)
for i in range(len(contours)):
c=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
cv2.drawContours(dst,contours,i,c,1,cv2.LINE_AA)
cv2.imshow('src', src)
cv2.imshow('src_bin', src_bin)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
'Computer Vision > opencv(python)' 카테고리의 다른 글
[47] 9) 명함 인식 프로그램 (0) | 2021.03.24 |
---|---|
[46] 8) 다양한 외곽선 함수 (0) | 2021.03.24 |
[44] 6) 레이블링 (0) | 2021.03.23 |
[43] 모폴로지(2): 열기와 닫기 (0) | 2021.03.23 |
[42] 4) 모폴로지 (1): 침식과 팽창 (0) | 2021.03.23 |