diff --git a/src/omv/img/hough.c b/src/omv/img/hough.c index 694d5a2c8..c66b6577a 100644 --- a/src/omv/img/hough.c +++ b/src/omv/img/hough.c @@ -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); diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index e97725ecd..2e9f67e21 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -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 diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index b017582fc..9523db601 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -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); diff --git a/src/omv/py/qstrdefsomv.h b/src/omv/py/qstrdefsomv.h index 7ea663bf7..136a84076 100644 --- a/src/omv/py/qstrdefsomv.h +++ b/src/omv/py/qstrdefsomv.h @@ -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) diff --git a/usr/examples/09-Feature-Detection/find_circles.py b/usr/examples/09-Feature-Detection/find_circles.py index 3334b25aa..a208b4a5b 100644 --- a/usr/examples/09-Feature-Detection/find_circles.py +++ b/usr/examples/09-Feature-Detection/find_circles.py @@ -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)