Add Hough Transform.

This commit is contained in:
iabdalkader 2016-09-12 22:16:58 +02:00
parent 217b3a8dd4
commit 83451de050
6 changed files with 114 additions and 0 deletions

View File

@ -165,6 +165,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/img/,\
jpeg.o \
lbp.o \
eye.o \
hough.o \
sincos_tab.o \
)

View File

@ -52,6 +52,7 @@ SRCS += $(addprefix img/, \
jpeg.c \
lbp.c \
eye.c \
hough.c \
sincos_tab.c \
)

71
src/omv/img/hough.c Normal file
View File

@ -0,0 +1,71 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Hough Transform.
*
*/
#include <stdio.h>
#include <math.h>
#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; y<h; y++) {
for (int x=roi->x; x<w; x++) {
if (src->data[y*s+x] > 250) {
for (int t=0; t<htw; t++) {
int r = (int)roundf((x*cos_table[t] + y*sin_table[t] + (hth/2)));
ht[r*htw+t]++;
}
}
}
}
for(int r=0; r<hth; r++) {
for(int t=0; t<htw; t++) {
if (ht[r*htw+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;
}

View File

@ -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__

View File

@ -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; i<array_length(lines); i++) {
line_t *l = (line_t *) array_at(lines, i);
mp_obj_t line_obj[4] = {
mp_obj_new_int(l->x1),
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);

View File

@ -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)