[ch07] 이진 영상 처리 - 외곽선 검출

빨주노·2021년 8월 27일
0

외곽선 검출이란?

  • 객체의 외곽선 좌표를 모두 추출하는 작업. 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, hierarchy
  • 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
    • hierrarchy[0, i, 0] ~ hierarchy[0, i, 3]이 순서대로 next, prev, child, paraent 외곽선 인덱스를 가리킴. 해당 외곽선이 없으면 -1.
  • offset : 좌표 값 이동 옵셋. 기본값은 (0, 0)

외곽선 그리기

cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None) -> image
  • image : 입출력 영상
  • contours : (cv2.findContours() 함수로 구현) 외곽선 좌표 정보
  • contourIdx : 외곽선 인덱스. 음수(-1)를 지정하면 모든 외곽선을 그린다.
  • color : 외곽선 색상
  • thickness : 외곽선 두께. thickness < 0이면 내부를 채운다.
  • lineType : LINE_4, LINE_8, LINE_AA 중 하나 지정
  • hierarchy : 외곽선 계층 정보
  • maxLevel : 그리기를 수행할 최대 외곽선 레벨. maxLevel=0이면 contourIdx로 지정된 외곽선만 그린다.

계층 정보를 사용하는 외곽선 검출 예제

src = cv2.imread('contours.bmp', cv2.IMREAD_GRAYSCALE)

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)
    idx = kier[0, idx, 0]

  • cv2.RETR_TREE로 바꾼 결과

계층 정보를 사용하지 않는 외곽선 검출 예제

src = cv2.imread('milkdrop.bmp', cv2.IMREAD_GRAYSCALE)
_, src_bin = cv2.threshold(src, 0, 255, cv2.THRESH_OTSU)
contours, _ = cv2.findContours(src_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

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)

profile
딥 하게 딥러닝 하는중

0개의 댓글