Computer Vision/opencv(python)

[49] 2) 모멘트 기반 객체 검출

jwjwvison 2021. 3. 24. 09:49
  • 모멘트(moments) 란?
    • 영상의 형태를 표현하는 일련의 실수값
    • 특정 함수 집합과의 상관관계(correlation) 형태로 계산

 

  • 모양 비교 함수
cv2.matchShape(contour1,contour2,method,parameter) -> retval

 • contour1: 첫 번째 외곽선 또는 그레이스케일 영상
 • contour2: 두 번째 외곽선 또는 그레이스케일 영상
 • method: 비교 방법 지정 . cv2.CONTOURS_MATCH_I1, cv2.CONTOURS_MATCH_I2,
   cv2.CONTOURS_MATCH_I3 중 하나 사용 .
 • parameter: 사용되지 않음 . 0 지정
 • retval 두 외곽선 또는 그레이스케일 영상 사이의 거리 (distance)

 <참고사함>

    hug의 불변모멘트를 이용하여 두 외곽선 또는 영상의 모양을 비교 

      -> 크기, 회전, 이동, 대칭, 변환에 강인

 

  • 모양 비교 함수

 

  • 모멘트 기반 객체 검출 예제

   회전, 대칭, 크기변환 정도만 잘 작동하고 영상에 약간 변형이 있다면 잘 동작하지 않을 것이다.

import sys
import numpy as np
import cv2


# 영상 불러오기
obj = cv2.imread('spades.png', cv2.IMREAD_GRAYSCALE)
src = cv2.imread('symbols.png', cv2.IMREAD_GRAYSCALE)

if src is None or obj is None:
    print('Image load failed!')
    sys.exit()

# 객체 영상 외곽선 검출
_,obj_bin=cv2.threshold(obj,128,255,cv2.THRESH_BINARY_INV)    #반전 이진화
obj_contours,_=cv2.findContours(obj_bin,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)  #외곽선 검출
obj_pts=obj_contours[0]            #어처피 스페이드 하나라 제일처음 외곽선이든 말든 상관없는듯

# 입력 영상 분석
_, src_bin = cv2.threshold(src, 128, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# 결과 영상
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)

# 입력 영상의 모든 객체 영역에 대해서
for pts in contours:
    if cv2.contourArea(pts)<1000:    # 작은 개체 혹은 노이즈 무시
        continue

    rc=cv2.boundingRect(pts)          # 바운딩 박스: 외곽선을 외접하여 둘러싸는 가장 작은 사각형 구하기 --> (x,y,w,h)
    
    cv2.rectangle(dst,rc,(255,0,0),1)
   
    # 모양비교
    dist=cv2.matchShapes(obj_pts,pts,cv2.CONTOURS_MATCH_I3,0)

    cv2.putText(dst, str(round(dist, 4)), (rc[0], rc[1] - 3),
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 1, cv2.LINE_AA)
    if dist < 0.1:
        cv2.rectangle(dst,rc,(0,0,255),2)
cv2.imshow('obj',obj)
cv2.imshow('dst',dst)
cv2.waitKey(0)