• 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

[017] OpenCV 영상처리 허프변환

12 Jan 2020

Reading time ~2 minutes

Table of Contents
  • 허프변환
  • 허프변환
  • Hough Circle Transform
    • 함수 원본
    • 코드

허프변환

  • Hough Circle Transform
    • 함수 원본
    • 코드

허프변환

Hough Circle Transform

원을 다음 식으로 나타낼 수 있다.
\((x - cx)^2 + (y - cy)^2 = r^2\)

  • (cx, cy): 원의 중심 좌표
  • r: 원의 반지름
  • 원을 나타내는 식에 3개의 파라미터가 있기 때문에 hough transform를 사용하려면 3차원 배열이 필요 -> 비효율적
    [solve] 에지의 그레디언트 정보를 사용하는 Hough Gradient Method를 사용
    OpenCV에서는 원 검출을 위해 HoughCircles () 함수를 제공
  • 내부에 에지 검출 알고리즘이 포함
  • 캐니 에지 등을 사용하여 에지를 검출한 결과를 입력으로 사용할 필요 없음

image

image

함수 원본

HoughCircles ( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 ) Python:
circles =cv.HoughCircles( image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]] )

  • Image: 입력 이미지는 그레이 스케일 이미지여야 함
  • Method: 원을 검출하는 방법, HOUGH_GRADIENT만 사용 가능
  • dp
    • 이미지 해상도에 대한 accumulator 해상도의 비율의 역수
    • ex) dp=1 이면 배열 accumulator는 입력 이미지와 같은 해상도를 가짐.
    • dp=2이면 배열 accumulator는 절반의 너비와 높이를 가짐
  • minDist: 검출된 원 사이의 최소 거리입니다. 이 값이 너무 크면 검출되지 못한 원들이 생기며, 너무 작으면 인접한 원들이 잘못 검출될 수 있음
  • Circles: 발견한 원에 대한 벡터입니다. 각 벡터는 3개 (x,y,radius) 또는 4개 (x,y,radius,votes)의 원소를 가짐
  • param1: 지정한 원 검출 방법을 위한 파라미터. HOUGH_GRADIENT의 경우 캐니 에지 디텍터의 높은 스레솔드 값입니다. 낮은 스레솔드 값은 0.5배해서 사용하게 됨
  • param2: 지정한 원 검출 방법을 위한 파라미터. HOUGH_GRADIENT의 경우 accumulator 스레솔드 값. 이 값이 너무 작으면 거짓 원이 검출됩니다. 가장 큰 accumulator 값을 가지는 원이 먼저 리턴
  • minRadius: 검출하려는 원의 최소 반지름. 크기를 알 수 없는 경우 0으로 지정.
  • maxRadius: 검출하려는 원의 최대 반지름. 크기를 알 수 없는 경우 0으로 지정. 음수를 지정하면 원의 중심만 리턴.

코드

[C++]

# include < opencv2/opencv.hpp> 
# include < iostream>

using namespace cv;
using namespace std;

int main()
{ 
  // 그레이 스케일로 입력 이미지를 불러옵니다.
  Mat img_gray;
  img_gray = imread("test.jpg", IMREAD_GRAYSCALE);
  medianBlur(img_gray, img_gray, 5);
  
  // 결과 이미지에 컬러 도형을 사용하기 위해 컬러로 변환합니다.
  Mat img_color;
  cvtColor(img_gray, img_color, COLOR_GRAY2BGR);

  // 원을 검출합니다.
  vector<Vec3f> circles;
  HoughCircles(img_gray, circles, HOUGH_GRADIENT, 1,20,50,35,0,0);

  // 검출된 원에 빨간색/초록색 원을 그려줍니다.
  for( size_t i = 0; i < circles.size(); i++ )
  {
    Vec3i c = circles[i];
    Point center(c[0], c[1]);
    int radius = c[2];

    // 바깥 원
    circle( img_color, center, radius, Scalar(0,255,0), 2);
    // 중심 원
    circle( img_color, center, 2, Scalar(0,0,255), 3);
}
  // 검출 결과를 화면에 보여줍니다.
  imshow("detected circles", img_color);
  waitKey(0);
  destroyAllWindows();
  return 0;
}

[Python]

import numpy as np 
import cv2 as cv

# 그레이 스케일로 입력 이미지를 불러옵니다.
img_gray = cv.imread('test.jpg', cv.IMREAD_GRAYSCALE) 
img_gray = cv.medianBlur(img_gray,5)

# 결과 이미지에 컬러 도형을 사용하기 위해 컬러로 변환합니다.
img_color = cv.cvtColor(img_gray,cv.COLOR_GRAY2BGR)

# 원을 검출합니다.
circles = cv.HoughCircles(img_gray,cv.HOUGH_GRADIENT,1,20, param1=50,param2=35,minRadius=0,maxRadius=0) 
circles = np.uint16(np.around(circles))

# 검출된 원에 빨간색/초록색 원을 그려줍니다.
for c in circles[0,:]:
  center = (c[0],c[1]) 
  radius = c[2]
 
  # 바깥 원
  cv.circle(img_color,center,radius,(0,255,0),2)

  # 중심 원
  cv.circle(img_color,center,2,(0,0,255),3)

# 검출 결과를 화면에 보여줍니다.
cv.imshow('detected circles',img_color) 
cv.waitKey(0)  
cv.destroyAllWindows()


OpenCV Share Tweet +1