From 83451de050e339c11c1d112f3cc52b4edd764dcb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 12 Sep 2016 22:16:58 +0200 Subject: [PATCH] Add Hough Transform. --- src/Makefile | 1 + src/omv/Makefile | 1 + src/omv/img/hough.c | 71 ++++++++++++++++++++++++++++++++++++++++ src/omv/img/imlib.h | 9 +++++ src/omv/py/py_image.c | 31 ++++++++++++++++++ src/omv/py/qstrdefsomv.h | 1 + 6 files changed, 114 insertions(+) create mode 100644 src/omv/img/hough.c diff --git a/src/Makefile b/src/Makefile index d9befdae6..2811389d4 100755 --- a/src/Makefile +++ b/src/Makefile @@ -165,6 +165,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/img/,\ jpeg.o \ lbp.o \ eye.o \ + hough.o \ sincos_tab.o \ ) diff --git a/src/omv/Makefile b/src/omv/Makefile index 8ae7cbcaf..e6b6fc6b3 100644 --- a/src/omv/Makefile +++ b/src/omv/Makefile @@ -52,6 +52,7 @@ SRCS += $(addprefix img/, \ jpeg.c \ lbp.c \ eye.c \ + hough.c \ sincos_tab.c \ ) diff --git a/src/omv/img/hough.c b/src/omv/img/hough.c new file mode 100644 index 000000000..8ca12ce3b --- /dev/null +++ b/src/omv/img/hough.c @@ -0,0 +1,71 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013/2014 Ibrahim Abdelkader + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Hough Transform. + * + */ +#include +#include +#include "imlib.h" +#include "xalloc.h" +#include "fb_alloc.h" + +static inline line_t *line_alloc(int x1, int y1, int x2, int y2) +{ + line_t *l = xalloc(sizeof(line_t)); + l->x1=x1; l->y1=y1; l->x2=x2; l->y2=y2; + return l; +} + +array_t *imlib_find_lines(image_t *src, rectangle_t *roi, int threshold) +{ + array_t *lines; + array_alloc(&lines, xfree); + + int s = src->w; // stride + int w = roi->x+roi->w; + int h = roi->y+roi->h; + + int htw = 180; + int hth = sqrtf(w*w + h*h)*2; + uint8_t *ht = fb_alloc0(htw*hth*sizeof*ht); + + // Transform to ht Space + for (int y=roi->y; yx; xdata[y*s+x] > 250) { + for (int t=0; t threshold) { + int x1=0, y1=0, x2=0, y2=0; + if(t >= 45 && t <= 135) { + //y = (r - x cos(t)) / sin(t) + x1 = 0; + y1 = ((float)(r-(hth/2)) - (x1 * cos_table[t])) / sin_table[t]; + x2 = w; + y2 = ((float)(r-(hth/2)) - (x2 * cos_table[t])) / sin_table[t]; + } else { + //x = (r - y sin(t)) / cos(t); + y1 = 0; + x1 = ((float)(r-(hth/2)) - (y1 * sin_table[t])) / cos_table[t]; + y2 = h; + x2 = ((float)(r-(hth/2)) - (y2 * sin_table[t])) / cos_table[t]; + } + array_push_back(lines, line_alloc(x1, y1, x2, y2)); + } + } + } + + fb_free(); + return lines; +} diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index 34cbb0e81..94df8ac04 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -183,6 +183,13 @@ typedef struct point { int16_t y; } point_t; +typedef struct line { + int16_t x1; + int16_t y1; + int16_t x2; + int16_t y2; +} line_t; + typedef struct rectangle { int16_t x; int16_t y; @@ -515,4 +522,6 @@ void imlib_find_iris(image_t *src, point_t *iris, rectangle_t *roi); void im_filter_bw(uint8_t *src, uint8_t *dst, int size, int bpp, void *args); void im_filter_skin(uint8_t *src, uint8_t *dst, int size, int bpp, void *args); +// Lines +array_t *imlib_find_lines(image_t *src, rectangle_t *roi, int threshold); #endif //__IMLIB_H__ diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index 125531c2b..496b00af9 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -1342,6 +1342,35 @@ static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_ma return mp_const_none; } +static mp_obj_t py_image_find_lines(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) +{ + image_t *img = py_image_cobj(args[0]); + PY_ASSERT_TRUE_MSG(IM_IS_GS(img), "This function is only supported on GRAYSCALE images"); + + rectangle_t roi; + py_helper_lookup_rectangle(kw_args, img, &roi); + int threshold = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), 50); + + rectangle_t rect; + if (!rectangle_subimg(img, &roi, &rect)) { + return mp_const_none; + } + + mp_obj_t lines_list = mp_obj_new_list(0, NULL); + array_t *lines = imlib_find_lines(img, &roi, threshold); + for (int i=0; ix1), + mp_obj_new_int(l->y1), + mp_obj_new_int(l->x2), + mp_obj_new_int(l->y2), + }; + mp_obj_list_append(lines_list, mp_obj_new_tuple(4, line_obj)); + } + return lines_list; +} + /* Image file functions */ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_obj, 1, py_image_copy); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_to_fb_obj, 1, py_image_copy_to_fb); @@ -1404,6 +1433,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_features_obj, 2, py_image_find_f STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_find_eye_obj, py_image_find_eye); STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_find_lbp_obj, py_image_find_lbp); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_keypoints_obj, 1, py_image_find_keypoints); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_lines_obj, 1, py_image_find_lines); static const mp_map_elem_t locals_dict_table[] = { /* Image file functions */ {MP_OBJ_NEW_QSTR(MP_QSTR_copy), (mp_obj_t)&py_image_copy_obj}, @@ -1467,6 +1497,7 @@ static const mp_map_elem_t locals_dict_table[] = { {MP_OBJ_NEW_QSTR(MP_QSTR_find_eye), (mp_obj_t)&py_image_find_eye_obj}, {MP_OBJ_NEW_QSTR(MP_QSTR_find_lbp), (mp_obj_t)&py_image_find_lbp_obj}, {MP_OBJ_NEW_QSTR(MP_QSTR_find_keypoints), (mp_obj_t)&py_image_find_keypoints_obj}, + {MP_OBJ_NEW_QSTR(MP_QSTR_find_lines), (mp_obj_t)&py_image_find_lines_obj}, { NULL, NULL }, }; STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table); diff --git a/src/omv/py/qstrdefsomv.h b/src/omv/py/qstrdefsomv.h index 2214db862..d64304121 100644 --- a/src/omv/py/qstrdefsomv.h +++ b/src/omv/py/qstrdefsomv.h @@ -79,6 +79,7 @@ Q(find_features) Q(find_keypoints) Q(find_lbp) Q(find_eye) +Q(find_lines) Q(cmp_lbp) Q(quality) Q(color)