AI 그게 뭔데
끄적끄적 개발일지
AI 그게 뭔데
전체 방문자
오늘
어제
  • 분류 전체보기 (342)
    • 논문 (5)
    • DL(Deep-Learning) (34)
      • 개념 (14)
      • Python 기초 (14)
      • Tensorflow (6)
      • Pytorch (0)
    • NLP (10)
    • OpenCV (53)
    • DevOps (10)
      • AWS (2)
      • Docker & Kubernetes (4)
      • Spark (3)
      • SQL (1)
    • MacOS (1)
    • React-Native (2)
    • BI (3)
      • GA(Google Analytics) (3)
      • Tableau (0)
    • 알고리즘 (221)
      • 백준 (76)
      • 프로그래머스 (108)
      • 기타 알고리즘 (37)

인기 글

태그

  • 이코테
  • 백준
  • Python
  • level1
  • 프로그래머스
  • LEVEL2
  • 연습문제
  • OpenCV
  • 파이썬
  • 알고리즘

최근 글

hELLO · Designed By 정상우.
AI 그게 뭔데

끄적끄적 개발일지

[OpenCV with Python] 이진 영상 처리 : 다양한 외곽선 함수
OpenCV

[OpenCV with Python] 이진 영상 처리 : 다양한 외곽선 함수

2022. 2. 4. 20:27

다양한 외곽선 함수

 

OpenCV: Contour Features

Prev Tutorial: Contours : Getting Started Next Tutorial: Contour Properties Goal In this article, we will learn To find the different features of contours, like area, perimeter, centroid, bounding box etc You will see plenty of functions related to contour

docs.opencv.org

 

 

 

외곽선 길이 구하기 - cv2.arclength

retval = cv2.arcLength(curve, closed)
  • curve : 외곽선 좌표. numpy.ndarray.
                 shape=(K, 1, 2)
  • closed : True이면 폐곡선으로 간주
  • retval : 외곽선 길이

 

 

면적 구하기 - cv2.contourArea

retval = cv2.contourArea(contour, oriented=None)
  • contour : 외곽선 좌표. numpy.ndarray.
                     shape=(K, 1, 2)
  • oriented : True이면 외곽선 진행 방향에 따라 부호 있는 면적을 반환.
                     기본값은 False
  • retval : 외곽선으로 구성된 영역의 면적

 

 

바운딩 박스(외곽선을 외접하여 둘러싸는 가장 작은 사각형) 구하기 - cv2.boundingRect

retval = cv2.boundingRect(array)
  • array : 외곽선 좌표. numpy.ndarray.
                shape=(K, 1, 2)
  • retval : 사각형 정보. (x, y, w, h) 튜플

 

 

바운딩 서클(외곽선을 외접하여 둘러싸는 가장 작은 원) 구하기 -  cv2.minEnclosingCircle

center, radius = cv2.minEnclosingCircle(points)
  • points : 외곽선 좌표. numpy.ndarray.shape=(K, 1, 2)
  • center : 바운딩 서클 중심 좌표. (x, y) 튜플
  • radius : 바운딩 서클 반지름. 실수.

 

최소 면적 사각형 함수(윤곽선의 경계면을 둘러싸는 최소 크기의 사각형) - cv2.minAreaRect

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)

 

 

윤곽선에 가장 근사한 원 구하기 - cv.minEnclosingCircle

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(0,255,0),2)

 

 

외곽선 근사화 - cv2.approxPolyDP

retval = cv2.approxPolyDP(curve, epsilon, closed, approxCurve=None)
  • curve : 입력 곡선 좌표. numpy.ndarray.shape=(K, 1, 2)
  • epsilon : 근사화 정밀도 조절. 입력 곡선과 근사화 곡선 간의 최대 거리.
    • ex) cv2.arcLength(curve) * 0.02
  • closed : True를 전달하면 폐곡선으로 인식
  • approxCurve : 근사화된 곡선 좌표. numpy.ndarray.shape=(K', 1, 2)
  • 참고사항
    • 더글라스-포이커 알고리즘 (Douglas-peucker algorithm)

 

 

윤곽선에 근접한 타원 구하기 - cv2.fitEllipse

ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(0,255,0),2)

 

 

주어진 점에 적합한 직선 그리기 - cv2.fitLine

rows, cols = img.shape[:2]
[vx, vy, x, y] = cv2.fitLine(cnt, cv.DIST_L2, 0, 0.01, 0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(img, (cols-1, righty), (0, lefty), (0, 255, 0), 2)

 

 

Convex 검사

retval = cv2.isContourConvex(contour)
  • contour : 입력 곡선 좌표. numpy.ndarray.
                     shape=(K, 1, 2)
  • retval : 컨벡스이면 True, 아니면 False.

 

 

윤곽선의 경계면을 둘러싸는 다각형 구하기 - cv2.convexHull

for i in contours:
    hull = cv2.convexHull(i, clockwise=True)
    cv2.drawContours(dst, [hull], 0, (0, 0, 255), 2)
  • 윤곽선은 윤곽선 검출 함수에서 반환되는 구조를 사용
  • 방향은 검출된 볼록 껍질의 볼록점들의 인덱스 순서를 의미

블록 껍질 함수는 단일 형태에서만 검출이 가능하다.

  • 윤곽선 구조는 윤곽선 검출 함수의 반환값과 형태가 동일하다면, 임의의 배열에서도 검출이 가능하다.
  • 방향이 True라면 시계 방향, False라면 반시계 방향으로 정렬된다.

 

 

Contour에 볼록 결함(Convexity Defect)가 있는지 확인 -cv2.convexityDefects

convexityDefects = cv2.convexityDefects(contour, convexhull[, convexityDefects])
  • contour : convexHull을 진행했던 Contours를 그대로 인자로 받는다.
  • convexhull : 볼록체를 만든 Contour Points의 인덱스를 포함한 convexHull를 인자로 받는다.

 

convexityDefects는 Contour의 각 인덱스마다 다음 4가지를 계산하여 반환한다.

  1.  start point : Convex Hull를 이루는 시작 인덱스
  2.  end point : Convex Hull를 이루기 위해 그 다음으로 연결되는 점의 인덱스
  3.  farthest point : start와 end를 연결한 직선과 가장 멀리 떨어져 있는 Contour 상의 인덱스
  4.  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()

 

'OpenCV' 카테고리의 다른 글

[OpenCV with Python] 영상 분할과 객체 검출 : 모멘트 기반 객체 검출  (0) 2022.02.04
[OpenCV with Python] 영상 분할과 객체 검출 : 그랩컷 - cv2.grabCut  (0) 2022.02.04
[OpenCV with Python] 이진 영상 처리 : 외곽선 검출  (0) 2022.02.04
[OpenCV with Python] 이진 영상 처리 : 레이블링  (0) 2022.02.04
[OpenCV with Python] 이진 영상 처리 : 모폴로지(Morphology) - 열기와 닫기  (0) 2022.02.04
    AI 그게 뭔데
    AI 그게 뭔데
    공부와 개발 그리고 AI가 약간 첨가된 흔적 남기기

    티스토리툴바