• Home
  • About
    • Yerim Oh photo

      Yerim Oh

      Happy and worthwhile day by day :)

    • Learn More
    • Email
    • LinkedIn
    • Instagram
    • Github
    • Youtube
  • Posts
    • All Posts
    • All Tags
  • Projects

[019] OpenCV 영상처리 컨투어

10 Jan 2020

Reading time ~3 minutes

Table of Contents
  • 컨투어 목차
  • 컨투어 검출하기
    • findContours 함수 원형
    • drawContours 함수 원형
    • 코드

컨투어 목차

  • 컨투어 검출하기
    • findContours 함수 원형
    • drawContours 함수 원형
    • 코드

컨투어 검출하기

컨투어

  • 특정 영역의 경계를 따라 같은 픽셀값을 갖는 지점을 연결하는 선
  • 즉 외곽선을 그리는 함수
    [주의]
    꼭 오브젝트는 흰색 배경은 검정색인 흑백으로 해야함!

(사용되는 곳)

  • 영역에 대한 모양 분석
  • 오브젝트 검출을 위한 전처리로 사용
    findContours함수제공

findContours 함수 원형

findContours ( InputArray image, OutputArrayOfArrays contours, int mode, int method )
Python:
contours, hierarchy = cv.findContours( image, mode, method)

  • OpenCV 4.0으로 넘어오면서 파이썬의 findContours함수 리턴값이 3개에서 2개로 변경. 그외 사용 방법은 동일합니다.
  • Image: 입력 이미지는 검은색과 흰색으로만 구성되는 바이너리 이미지여야 함
    • find Contours 함수를 사용하기 전에 이진화 또는 케니 에지 디텍터 등을 입력 이미지에 적용하여 바이너리 이미지로 바꾸어야 함
  • Contours: 검출된 컨투어.
    • C++에서는 vector에 cv::Point 타입으로 저장
    • 파이썬에서는 리스트로 저장.
    • 각각의 컨투어에는 오브젝트의 외곽선을 구성하는 점들의 (x,y)좌표를 저장하고 있음.
  • Hierarchy: 검출된 컨투어 정보를 구조적으로 저장하고 있음.
    • C++에서는 vector에 cv::Vec4i 타입으로 저장
    • 파이썬에서는 리스트로 저장
  • Mode: Contour retrieval mode는 검출된 에지 정보를 계층 또는 리스트로 저장하는 방식을 지정
    • 4가지 모드가 있음(2개 자주 사용)
    • RETR_LIST 전체 컨투어를 검출하기 위함
    • RETR_EXTERNAL 영역 외곽의 컨투어만 검출하기 위함
  • Method: Contour approximation method 메소드는 컨투어를 구성하는 포인트 검출 방법을 지정
    • 2가지 방법이 있음
    • CHAIN_APPROX_NONE: 컨투어를 구성하는 모든 점을 좌표로 저장
    • CHAIN_APPROX_SIMPLE: 컨투어의 일부 구간이 직선인 경우 시작 좌표와 끝 좌표만 저장

drawContours 함수 원형

이를 사용하여 컨투어를 이미지에 그릴 수 있음
보통 원본 이미지에 있는 특정 모양의 외곽선을 따라 그림
drawContours( InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar & color, int thickness = 1) Python:
image = cv.drawContours( image, contours, contourIdx, color[, thickness])

  • Image: 컨투어를 그릴 대상 이미지. 컬러 이미지를 선택해야 함.
  • Contours: 이미지 위에 그릴 컨투어가 저장된 리스트
  • contourIdx: 이미지에 그릴 특정 컨투어의 인덱스입니다. 음수로 지정하면 모든 컨투어를 그림.
  • Color : 컨투어를 그릴 때 사용할 색상을 지정합니다. BGR 순으로 적어주면 됨.
  • Thickness: 컨투어를 그릴 때 선의 굵기입니다. 음수이면 내부를 채움.

간단한 도형이 그려진 이미지에서 컨투어를 검출하여 이미지에 컨투어를 그려주면 도형 외곽을 따라 검출된 컨투어가 그려짐

(원본) image

(컨투어링 후) image

코드

[C++]

# include < opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{ 
  // 컬러로 이미지를 가져옵니다.
  Mat img_color;
  img_color = imread("test.jpg", IMREAD_COLOR);

  // 그레이 스케일로 변환한 후, 이진화하여 바이너리 이미지로 변환
  Mat img_gray;
  cvtColor(img_color, img_gray, COLOR_BGR2GRAY);

  Mat img_binary;
  threshold(img_gray, img_binary, 150, 255, THRESH_BINARY_INV);

  // 이진화 결과를 개선하기 위해 모폴로지 연산을 해줍니다.
  Mat kernel = getStructuringElement( MORPH_RECT, Size( 5, 5 ) ); 
  morphologyEx(img_binary, img_binary, MORPH_CLOSE, kernel);

  // 컨투어를 검출합니다.
  vector<vector<Point>> contours;
  findContours(img_binary, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

  // 검출된 2개의 컨투어를 이미지에 그려줍니다.
  // 각각 인덱스 0, 인덱스 1로 지정할 수 있습니다.
  drawContours(img_color, contours, 0, Scalar(0, 0, 255), 3);
  drawContours(img_color, contours, 1, Scalar(0, 255, 0), 3);

  // 다음처럼 한번에 모든 컨투어를 그릴 수도 있습니다.
  // drawContours(img_color, contours, - 1, Scalar(0, 255, 0), 3);
 
  imshow("result", img_color);
  waitKey(0);
  return 0;
}

[Python]

import cv2 as cv

# 컬러로 이미지를 가져옵니다.
img_color = cv.imread('test.jpg', cv.IMREAD_COLOR)

# 그레이 스케일로 변환한 후, 이진화하여 바이너리 이미지로 변환합니다.
img_gray = cv.cvtColor(img_color, cv.COLOR_BGR2GRAY) 
ret, img_binary = cv.threshold(img_gray, 150, 255, cv.THRESH_BINARY_INV)

# 이진화 결과를 개선하기 위해 모폴로지 연산을 해줍니다.
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5)) 
img_binary = cv.morphologyEx(img_binary, cv.MORPH_CLOSE, kernel)

# 컨투어를 검출합니다.
contours, hierarchy = cv.findContours(img_binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)

# 검출된 2개의 컨투어를 이미지에 그려줍니다.
# 각각 인덱스 0, 인덱스 1로 지정할 수 있습니다.
cv.drawContours(img_color, contours, 0, (0, 0, 255), 3) 
cv.drawContours(img_color, contours, 1, (0, 255, 0), 3)

# 다음처럼 한번에 모든 컨투어를 그릴 수도 있습니다.
# cv.drawContours(img_color, contours, - 1, (0, 255, 0), 3)
cv.imshow("result", img_color) 
cv.waitKey(0)


OpenCV Share Tweet +1