convexhull : 볼록체를 만든 Contour Points의 인덱스를 포함한 convexHull를 인자로 받는다.
convexityDefects는 Contour의 각 인덱스마다 다음 4가지를 계산하여 반환한다.
start point : Convex Hull를 이루는 시작 인덱스
end point : Convex Hull를 이루기 위해 그 다음으로 연결되는 점의 인덱스
farthest point : start와 end를 연결한 직선과 가장 멀리 떨어져 있는 Contour 상의 인덱스
approximate distance to farthest point : farthest point와 Convex Hull 사이의 거리
다각형 검출 프로그램
다양한 다각형 객체 영상에서 삼각형, 사각형, 원 찾기
구현 순서
이진화
외곽선 찾기
외곽선 근사화
너무 작은 객체와 컨벡스가 아닌 객체 제외
꼭지점 개수 확인 - 삼각형, 사각형 검출 - 원 판별
원 판별하기
정해진 외곽선 길이에 대한 넓이 비율이 가장 큰 형태가 원 → 도형의 넓이(A)와 외곽선 길이(P)의 비율을 검사
따라서$\frac{A}{P^2}$로 만들어 비율을 계산해준다.
$\frac{A}{P}$의 경우 약분하면r이 남게 되어 비율이 상수로 떨어지지 않는다.
$4\pi \frac{A}{P^2}$ 의 값이 1에 가까울수록 원으로 판단한다.
length = cv2.arcLength(pts, True)
area = cv2.contourArea(pts)
ratio = 4. * math.pi * area / (length * lenght)
if ratio > 0.05:
setLabel(img, pts, 'CIR') # 원
💬 다각형 판별 프로그램 예제
import math
import cv2
def setLabel(img, pts, label):
(x, y, w, h) = cv2.boundingRect(pts)
pt1 = (x, y)
pt2 = (x + w, y + h)
cv2.rectangle(img, pt1, pt2, (0, 0, 255), 1)
cv2.putText(img, label, pt1, cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255))
def main():
img = cv2.imread('polygon.bmp', cv2.IMREAD_COLOR)
if img is None:
print('Image load failed!')
return
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, img_bin = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
contours, _ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for pts in contours:
if cv2.contourArea(pts) < 400: # 너무 작으면 무시
continue
approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)
vtc = len(approx)
if vtc == 3:
setLabel(img, pts, 'TRI')
elif vtc == 4:
setLabel(img, pts, 'RECT')
else:
length = cv2.arcLength(pts, True)
area = cv2.contourArea(pts)
ratio = 4. * math.pi * area / (length * length)
if ratio > 0.85:
setLabel(img, pts, 'CIR')
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()