From 38f2c418775d1c629ca482ecbea7e0bdf161520e Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sat, 20 Jan 2018 01:56:51 -0500 Subject: [PATCH] Add pixel and area threshold settings to get_regression() You can now make it not return anything for images with a low pixel count. --- src/omv/img/imlib.h | 2 +- src/omv/img/stats.c | 42 +++++++++++++++++++++++++++++++++++++--- src/omv/py/py_image.c | 4 +++- src/omv/py/qstrdefsomv.h | 7 +++++-- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index 3f357e9c2..684546e39 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -1222,7 +1222,7 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi); void imlib_get_percentile(percentile_t *out, image_bpp_t bpp, histogram_t *ptr, float percentile); void imlib_get_statistics(statistics_t *out, image_bpp_t bpp, histogram_t *ptr); bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride, - list_t *thresholds, bool invert, bool robust); + list_t *thresholds, bool invert, unsigned int area_threshold, unsigned int pixels_threshold, bool robust); // Color Tracking void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride, list_t *thresholds, bool invert, unsigned int area_threshold, unsigned int pixels_threshold, diff --git a/src/omv/img/stats.c b/src/omv/img/stats.c index 77be49895..187ef3663 100644 --- a/src/omv/img/stats.c +++ b/src/omv/img/stats.c @@ -587,12 +587,16 @@ static int get_median_l(long long *array, long long array_sum, int array_len) } bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride, - list_t *thresholds, bool invert, bool robust) + list_t *thresholds, bool invert, unsigned int area_threshold, unsigned int pixels_threshold, bool robust) { bool result = false; memset(out, 0, sizeof(find_lines_list_lnk_data_t)); if (!robust) { // Least Squares + int blob_x1 = roi->x + roi->w - 1; + int blob_y1 = roi->y + roi->h - 1; + int blob_x2 = roi->x; + int blob_y2 = roi->y; int blob_pixels = 0; int blob_cx = 0; int blob_cy = 0; @@ -610,6 +614,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; blob_cx += x; blob_cy += y; @@ -626,6 +634,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; blob_cx += x; blob_cy += y; @@ -642,6 +654,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; blob_cx += x; blob_cy += y; @@ -659,7 +675,9 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang } } - if (blob_pixels) { + int w = blob_x2 - blob_x1; + int h = blob_y2 - blob_y1; + if (blob_pixels && ((w * h) >= area_threshold) && (blob_pixels >= pixels_threshold)) { // http://www.cse.usf.edu/~r1k/MachineVisionBook/MachineVision.files/MachineVision_Chapter2.pdf // https://www.strchr.com/standard_deviation_in_one_pass // @@ -735,6 +753,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang size_t points_count = 0; if(points_max) { + int blob_x1 = roi->x + roi->w - 1; + int blob_y1 = roi->y + roi->h - 1; + int blob_x2 = roi->x; + int blob_y2 = roi->y; int blob_pixels = 0; for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { @@ -747,6 +769,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; x_histogram[x]++; y_histogram[y]++; @@ -765,6 +791,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; x_histogram[x]++; y_histogram[y]++; @@ -783,6 +813,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { + blob_x1 = IM_MIN(blob_x1, x); + blob_y1 = IM_MIN(blob_y1, y); + blob_x2 = IM_MAX(blob_x2, x); + blob_y2 = IM_MAX(blob_y2, y); blob_pixels += 1; x_histogram[x]++; y_histogram[y]++; @@ -802,7 +836,9 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang } } - if (blob_pixels) { + int w = blob_x2 - blob_x1; + int h = blob_y2 - blob_y1; + if (blob_pixels && ((w * h) >= area_threshold) && (blob_pixels >= pixels_threshold)) { long long delta_sum = (points_count * (points_count - 1)) / 2; if (delta_sum) { diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index f18d8ac77..80df44347 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -2381,11 +2381,13 @@ static mp_obj_t py_image_get_regression(uint n_args, const mp_obj_t *args, mp_ma unsigned int y_stride = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_stride), 1); PY_ASSERT_TRUE_MSG(y_stride > 0, "y_stride must not be zero."); bool invert = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_invert), false); + unsigned int area_threshold = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_area_threshold), 10); + unsigned int pixels_threshold = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_pixels_threshold), 10); bool robust = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_robust), false); find_lines_list_lnk_data_t out; fb_alloc_mark(); - bool result = imlib_get_regression(&out, arg_img, &roi, x_stride, y_stride, &thresholds, invert, robust); + bool result = imlib_get_regression(&out, arg_img, &roi, x_stride, y_stride, &thresholds, invert, area_threshold, pixels_threshold, robust); fb_alloc_free_till_mark(); list_free(&thresholds); if (!result) { diff --git a/src/omv/py/qstrdefsomv.h b/src/omv/py/qstrdefsomv.h index 6c27783f5..c75fd7ab9 100644 --- a/src/omv/py/qstrdefsomv.h +++ b/src/omv/py/qstrdefsomv.h @@ -469,6 +469,8 @@ Q(get_regression) Q(x_stride) Q(y_stride) // duplicate Q(invert) +Q(area_threshold) +Q(pixels_threshold) Q(robust) // Line Object Q(line) @@ -487,8 +489,9 @@ Q(find_blobs) // duplicate Q(roi) // duplicate Q(x_stride) // duplicate Q(y_stride) -Q(area_threshold) -Q(pixels_threshold) +// duplicate Q(invert) +// duplicate Q(area_threshold) +// duplicate Q(pixels_threshold) Q(merge) Q(margin) Q(threshold_cb)