Merge pull request #263 from kwagyeman/lsd

Lsd
This commit is contained in:
Ibrahim Abd Elkader 2017-09-13 18:09:50 +02:00 committed by GitHub
commit 0cf13e8777
10 changed files with 2741 additions and 44 deletions

View File

@ -179,6 +179,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/img/,\
lbp.o \
eye.o \
hough.o \
lsd.o \
sincos_tab.o \
edge.o \
hog.o \

View File

@ -61,6 +61,7 @@ SRCS += $(addprefix img/, \
lbp.c \
eye.c \
hough.c \
lsd.c \
sincos_tab.c \
edge.c \
hog.c \

View File

@ -32,6 +32,9 @@
// Enable Find_Rects
#define OMV_ENABLE_FIND_RECTS
// Enable QRCodes (14 KB)
#define OMV_ENABLE_QRCODES
// Enable AprilTags (64 KB).
#define OMV_ENABLE_APRILTAGS

View File

@ -573,7 +573,7 @@ size_t trace_line(image_t *ptr, line_t *l, int *theta_buffer, uint32_t *mag_buff
// http://www.brackeen.com/vga/source/djgpp20/lines.c.html
// http://www.brackeen.com/vga/source/bc31/lines.c.html
static bool merge_line(line_t *big, line_t *small, unsigned int threshold)
bool merge_line(line_t *big, line_t *small, unsigned int threshold)
{
int dx = big->x2 - big->x1; // the horizontal distance of the line
int dy = big->y2 - big->y1; // the vertical distance of the line
@ -634,7 +634,7 @@ static bool merge_line(line_t *big, line_t *small, unsigned int threshold)
return false;
}
static void merge_alot(list_t *out, int threshold, int theta_threshold)
void merge_alot(list_t *out, int threshold, int theta_threshold)
{
for (;;) {
bool merge_occured = false;

View File

@ -1219,8 +1219,11 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
// Shape Detection
void pixel_magnitude(image_t *ptr, int x, int y, int *theta, uint32_t *mag); // helper/internal
size_t trace_line(image_t *ptr, line_t *l, int *theta_buffer, uint32_t *mag_buffer, point_t *point_buffer); // helper/internal
bool merge_line(line_t *big, line_t *small, unsigned int threshold); // helper/internal
void merge_alot(list_t *out, int threshold, int theta_threshold); // helper/internal
void imlib_find_lines(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
uint32_t threshold, unsigned int theta_margin, unsigned int rho_margin);
void imlib_lsd_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int merge_distance, unsigned int max_theta_diff);
void imlib_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
uint32_t threshold, unsigned int theta_margin, unsigned int rho_margin,
uint32_t segment_threshold);

2709
src/omv/img/lsd.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2447,17 +2447,11 @@ static mp_obj_t py_image_find_line_segments(uint n_args, const mp_obj_t *args, m
rectangle_t roi;
py_helper_lookup_rectangle(kw_args, arg_img, &roi);
unsigned int x_stride = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_stride), 2);
PY_ASSERT_TRUE_MSG(x_stride > 0, "x_stride must not be zero.");
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.");
list_t out;
fb_alloc_mark();
imlib_find_line_segments(&out, arg_img, &roi, x_stride, y_stride, py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), 1000),
py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_theta_margin), 25),
py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rho_margin), 25),
py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_segment_threshold), 100));
imlib_lsd_find_line_segments(&out, arg_img, &roi,
py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_merge_distance), 0),
py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_max_theta_diff), 15));
fb_alloc_free_till_mark();
mp_obj_list_t *objects_list = mp_obj_new_list(list_size(&out), NULL);
@ -2728,6 +2722,7 @@ static mp_obj_t py_image_find_rects(uint n_args, const mp_obj_t *args, mp_map_t
}
#endif
#ifdef OMV_ENABLE_QRCODES
// QRCode Object //
#define py_qrcode_obj_size 10
typedef struct py_qrcode_obj {
@ -2894,6 +2889,7 @@ static mp_obj_t py_image_find_qrcodes(uint n_args, const mp_obj_t *args, mp_map_
return objects_list;
}
#endif
#ifdef OMV_ENABLE_APRILTAGS
// AprilTag Object //
@ -3838,7 +3834,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_circles_obj, 1, py_image_find_ci
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_rects_obj, 1, py_image_find_rects);
#endif
/* Code Detection */
#ifdef OMV_ENABLE_QRCODES
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_qrcodes_obj, 1, py_image_find_qrcodes);
#endif
#ifdef OMV_ENABLE_APRILTAGS
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_apriltags_obj, 1, py_image_find_apriltags);
#endif
@ -3942,7 +3940,9 @@ static const mp_map_elem_t locals_dict_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR_find_rects), (mp_obj_t)&py_image_find_rects_obj},
#endif
/* Code Detection */
#ifdef OMV_ENABLE_QRCODES
{MP_OBJ_NEW_QSTR(MP_QSTR_find_qrcodes), (mp_obj_t)&py_image_find_qrcodes_obj},
#endif
#ifdef OMV_ENABLE_APRILTAGS
{MP_OBJ_NEW_QSTR(MP_QSTR_find_apriltags), (mp_obj_t)&py_image_find_apriltags_obj},
#endif

View File

@ -469,12 +469,8 @@ Q(rho_margin)
// Find Line Segments
Q(find_line_segments)
// duplicate Q(roi)
// duplicate Q(x_stride)
// duplicate Q(y_stride)
// duplicate Q(threshold)
// duplicate Q(theta_margin)
// duplicate Q(rho_margin)
Q(segment_threshold)
Q(merge_distance)
Q(max_theta_diff)
// Find Circles
Q(find_circles)

View File

@ -3,11 +3,10 @@
# This example shows off how to find line segments in the image. For each line object
# found in the image a line object is returned which includes the line's rotation.
# Note: Line detection is done by using the Hough Transform:
# http://en.wikipedia.org/wiki/Hough_transform
# Please read about it above for more information on what `theta` and `rho` are.
# find_line_segments() finds finite length lines (but is slow).
# Use find_line_segments() to find non-infinite lines (and is fast).
enable_lens_corr = True # turn on for straighter lines...
enable_lens_corr = False # turn on for straighter lines...
import sensor, image, time
@ -25,30 +24,15 @@ while(True):
img = sensor.snapshot()
if enable_lens_corr: img.lens_corr(1.8) # for 2.8mm lens...
# `threshold` controls how many lines in the image are found. Only lines with
# edge difference magnitude sums greater than `threshold` are detected...
# `merge_distance` controls the merging of nearby lines. At 0 (the default), no
# merging is done. At 1, any line 1 pixel away from another is merged... and so
# on as you increase this value. You may wish to merge lines as line segment
# detection produces a lot of line segment results.
# More about `threshold` - each pixel in the image contributes a magnitude value
# to a line. The sum of all contributions is the magintude for that line. Then
# when lines are merged their magnitudes are added togheter. Note that `threshold`
# filters out lines with low magnitudes before merging. To see the magnitude of
# un-merged lines set `theta_margin` and `rho_margin` to 0...
# `max_theta_diff` controls the maximum amount of rotation difference between
# any two lines about to be merged. The default setting allows for 15 degrees.
# `theta_margin` and `rho_margin` control merging similar lines. If two lines
# theta and rho value differences are less than the margins then they are merged.
# Setting both the above to zero will greatly increase segment detection at the
# cost of a lot of FPS. This is because when less lines are merged more pixels
# are tested... which takes longer but covers more possibilities...
# `segment_threshold` controls line segment extraction. It's a threshold on the
# magnitude response per pixel under an infinite line. Pixels with a magnitude
# above threshold are added to the line segment.
# `find_line_segments` merges detected lines that are no more than 5 pixels apart
# and no more than 15 degrees different to create nice continous line segments.
for l in img.find_line_segments(threshold = 1000, theta_margin = 15, rho_margin = 15, segment_threshold = 100):
for l in img.find_line_segments(merge_distance = 0, max_theta_diff = 5):
img.draw_line(l.line(), color = (255, 0, 0))
# print(l)

View File

@ -7,7 +7,7 @@ import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # can be QVGA on M7...
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must turn this off to prevent image washout...
clock = time.clock()