Skip to content

Instantly share code, notes, and snippets.

@rhee-elten
Created October 30, 2024 01:00
Show Gist options
  • Select an option

  • Save rhee-elten/e473086b74fdbcf9d81ceea6e8ea3bb1 to your computer and use it in GitHub Desktop.

Select an option

Save rhee-elten/e473086b74fdbcf9d81ceea6e8ea3bb1 to your computer and use it in GitHub Desktop.
"""
HOUGH_GRADIENT_ALT (Scharr algorithm) 의 경우
파라메터 권장값이 소개되어 있어서 이를 적용해 본다.
"""
from functools import partial
from time import perf_counter
import cv2
import numpy as np
def find_circles_240828(
image,
*,
sf, #=2.0, # 이미지를 1/2 으로 축소한 후 탐색
channel=1, # G 채널을 gray로 사용
gb_ksize=7, # gaussian blur kernel size
gb_sigma=1.5, # gaussian blur sigma
hc_dp=1.5, # 3.65, # image / accumulator ratio for hough circle
hc_min_dist_r=1.5, # 한 화면에 한개 서클
hc_param1=300, # HOUGH_GRADIENT_ALT (Scharr algo) >300
hc_param2=0.8, # HOUGH_GRADIENT_ALT 에서 "perfectness" 0.8~0.9
hc_min_dia_r=0.2, # 최소 0.2 크기
hc_max_dia_r=0.4, # 최대 0.4 크기
hc_method=cv2.HOUGH_GRADIENT_ALT,
circ_pad=0.0, # 내부 패딩 비율
_debug=None,
verbose=False,
):
log = partial(print, "find_circles_240828:") if verbose else (lambda *a, **k: None)
inp = resized = cv2.resize(
image, None, fx=1 / sf, fy=1 / sf, interpolation=cv2.INTER_AREA
)
inp = gray = np.ascontiguousarray(inp[:, :, channel]) if inp.ndim > 2 else inp
inp = blur = cv2.GaussianBlur(inp, ksize=(gb_ksize, gb_ksize), sigmaX=gb_sigma)
# 상대크기를 픽셀크기로 변환
image_size = min(*blur.shape[:2])
hough_circles_fn = partial(
cv2.HoughCircles,
method=hc_method,
dp=hc_dp,
param1=hc_param1,
param2=hc_param2,
minDist=max(1, hc_min_dist_r * image_size), # 1 보다 작을 수는 없다
minRadius=int(0.5 * hc_min_dia_r * image_size),
maxRadius=int(0.5 * hc_max_dia_r * image_size),
)
# hough circle 탐색
circles = hough_circles_fn(inp)
# prevent 'None'
if circles is None:
circles = (np.zeros((0, 3), dtype=np.uint32),)
log("hough_circles.shapes:", tuple(c.shape for c in circles))
if len(circles) > 0:
circles0 = circles[0]
circles0 = circles0 * [sf, sf, sf / (1.0 - circ_pad)]
circles0 = sorted(circles0, key=lambda it: -it[2]) # 반지름 역순 정렬
circles0 = np.uint32(np.around(circles0))
log("(circles0):", (circles0,))
circles = (circles0,)
if _debug is not None:
_debug.update(locals())
del _debug["_debug"]
log("circles:", circles)
return circles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment