Update find circles with min and max radius to run faster.

This was a user request.
This commit is contained in:
Kwabena W. Agyeman 2018-05-13 19:31:32 -04:00
parent 3a9b4bd2f7
commit ac2d2fc1cd
5 changed files with 20 additions and 5 deletions

View File

@ -453,7 +453,8 @@ void imlib_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsig
#ifdef IMLIB_ENABLE_FIND_CIRCLES
void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
uint32_t threshold, unsigned int x_margin, unsigned int y_margin, unsigned int r_margin)
uint32_t threshold, unsigned int x_margin, unsigned int y_margin, unsigned int r_margin,
unsigned int r_min, unsigned int r_max, unsigned int r_step)
{
uint16_t *theta_acc = fb_alloc0(sizeof(uint16_t) * roi->w * roi->h);
uint16_t *magnitude_acc = fb_alloc0(sizeof(uint16_t) * roi->w * roi->h);
@ -675,7 +676,7 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
list_init(out, sizeof(find_circles_list_lnk_data_t));
for (int r = 2, rr = IM_MIN((roi->w / 2), (roi->h / 2)); r < rr; r += 2) { // ignore r = 0/1
for (int r = r_min, rr = r_max; r < rr; r += r_step) { // ignore r = 0/1
int a_size, b_size, hough_divide = 1; // divides a and b accumulators
int w_size = roi->w - (2 * r);
int h_size = roi->h - (2 * r);

View File

@ -1348,7 +1348,8 @@ void imlib_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsig
uint32_t threshold, unsigned int theta_margin, unsigned int rho_margin,
uint32_t segment_threshold);
void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
uint32_t threshold, unsigned int x_margin, unsigned int y_margin, unsigned int r_margin);
uint32_t threshold, unsigned int x_margin, unsigned int y_margin, unsigned int r_margin,
unsigned int r_min, unsigned int r_max, unsigned int r_step);
void imlib_find_rects(list_t *out, image_t *ptr, rectangle_t *roi,
uint32_t threshold);
// 1/2D Bar Codes

View File

@ -4017,10 +4017,16 @@ static mp_obj_t py_image_find_circles(uint n_args, const mp_obj_t *args, mp_map_
unsigned int x_margin = py_helper_keyword_int(n_args, args, 5, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_margin), 10);
unsigned int y_margin = py_helper_keyword_int(n_args, args, 6, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_margin), 10);
unsigned int r_margin = py_helper_keyword_int(n_args, args, 7, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_r_margin), 10);
unsigned int r_min = IM_MAX(py_helper_keyword_int(n_args, args, 8, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_r_min),
2), 2);
unsigned int r_max = IM_MIN(py_helper_keyword_int(n_args, args, 9, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_r_max),
IM_MIN((roi.w / 2), (roi.h / 2))), IM_MIN((roi.w / 2), (roi.h / 2)));
unsigned int r_step = py_helper_keyword_int(n_args, args, 10, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_r_step), 2);
list_t out;
fb_alloc_mark();
imlib_find_circles(&out, arg_img, &roi, x_stride, y_stride, threshold, x_margin, y_margin, r_margin);
imlib_find_circles(&out, arg_img, &roi, x_stride, y_stride, threshold, x_margin, y_margin, r_margin,
r_min, r_max, r_step);
fb_alloc_free_till_mark();
mp_obj_list_t *objects_list = mp_obj_new_list(list_size(&out), NULL);

View File

@ -802,6 +802,9 @@ Q(find_circles)
Q(x_margin)
Q(y_margin)
Q(r_margin)
Q(r_min)
Q(r_max)
Q(r_step)
// Circle Object
Q(circle)
// duplicate Q(circle)

View File

@ -28,7 +28,11 @@ while(True):
# `x_margin`, `y_margin`, and `r_margin` control the merging of similar
# circles in the x, y, and r (radius) directions.
for c in img.find_circles(threshold = 2000, x_margin = 10, y_margin = 10, r_margin = 10):
# r_min, r_max, and r_step control what radiuses of circles are tested.
# Shrinking the number of tested circle radiuses yields a big performance boost.
for c in img.find_circles(threshold = 2000, x_margin = 10, y_margin = 10, r_margin = 10,
r_min = 2, r_max = 100, r_step = 2):
img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))
print(c)