Use ROI in Keypoint detector

This commit is contained in:
iabdalkader 2014-09-12 13:54:26 +02:00
parent 017b62d20d
commit 918026a22c
2 changed files with 88 additions and 75 deletions

View File

@ -4,24 +4,48 @@
#define INIT_ALLOC (50)
#define Compare(X, Y) ((X)>=(Y))
static kp_t* fast9_detect(const uint8_t* im, int xsize, int ysize, int stride, int b, int* ret_num_corners, rectangle_t *roi);
static int pixel[16];
static kp_t* fast9_detect(const uint8_t* im, int stride, int b, int* ret_num_corners, rectangle_t *roi);
static uint8_t* fast9_score(const uint8_t* i, int stride, kp_t* corners, int num_corners, int b);
static kp_t* nonmax_suppression(const kp_t* corners, const uint8_t* scores, int num_corners, int* ret_num_nonmax);
static void make_offsets(int pixel[], int row_stride)
{
pixel[0] = 0 + row_stride * 3;
pixel[1] = 1 + row_stride * 3;
pixel[2] = 2 + row_stride * 2;
pixel[3] = 3 + row_stride * 1;
pixel[4] = 3 + row_stride * 0;
pixel[5] = 3 + row_stride * -1;
pixel[6] = 2 + row_stride * -2;
pixel[7] = 1 + row_stride * -3;
pixel[8] = 0 + row_stride * -3;
pixel[9] = -1 + row_stride * -3;
pixel[10] = -2 + row_stride * -2;
pixel[11] = -3 + row_stride * -1;
pixel[12] = -3 + row_stride * 0;
pixel[13] = -3 + row_stride * 1;
pixel[14] = -2 + row_stride * 2;
pixel[15] = -1 + row_stride * 3;
}
kp_t *fast_detect(image_t *image, int threshold, int *ret_num_corners, rectangle_t *roi)
{
uint8_t* scores;
kp_t* nonmax;
kp_t* corners=0;
int num_corners=0;
int num_corners;
kp_t* corners;
uint8_t* scores=0;
kp_t* nonmax=0;
corners = fast9_detect(image->data, image->w, image->h, image->w, threshold, &num_corners, roi);
scores = fast9_score(image->data, image->w, corners, num_corners, threshold);
nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
make_offsets(pixel, image->w);
corners = fast9_detect(image->data, image->w, threshold, &num_corners, roi);
if (num_corners) {
scores = fast9_score(image->data, image->w, corners, num_corners, threshold);
nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
xfree(scores);
}
xfree(corners);
xfree(scores);
return nonmax;
}
@ -33,7 +57,7 @@ static kp_t* nonmax_suppression(const kp_t* corners, const uint8_t* scores, int
int* row_start;
int i, j;
kp_t* ret_nonmax;
const int sz = (int)num_corners;
const int sz = (int)num_corners;
/*Point above points (roughly) to the pixel above the one of interest, if there
is a feature there.*/
@ -3069,58 +3093,30 @@ static uint8_t fast9_corner_score(const uint8_t* p, const int pixel[], int bstar
}
}
static void make_offsets(int pixel[], int row_stride)
{
pixel[0] = 0 + row_stride * 3;
pixel[1] = 1 + row_stride * 3;
pixel[2] = 2 + row_stride * 2;
pixel[3] = 3 + row_stride * 1;
pixel[4] = 3 + row_stride * 0;
pixel[5] = 3 + row_stride * -1;
pixel[6] = 2 + row_stride * -2;
pixel[7] = 1 + row_stride * -3;
pixel[8] = 0 + row_stride * -3;
pixel[9] = -1 + row_stride * -3;
pixel[10] = -2 + row_stride * -2;
pixel[11] = -3 + row_stride * -1;
pixel[12] = -3 + row_stride * 0;
pixel[13] = -3 + row_stride * 1;
pixel[14] = -2 + row_stride * 2;
pixel[15] = -1 + row_stride * 3;
}
static uint8_t* fast9_score(const uint8_t* i, int stride, kp_t* corners, int num_corners, int b)
{
int n;
uint8_t* scores = (uint8_t*)xalloc(sizeof(uint8_t)* num_corners);
int pixel[16];
make_offsets(pixel, stride);
for(n=0; n < num_corners; n++)
scores[n] = fast9_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b);
return scores;
}
static kp_t* fast9_detect(const uint8_t* im, int xsize, int ysize, int stride, int b, int* ret_num_corners, rectangle_t *roi)
static kp_t* fast9_detect(const uint8_t* im, int stride, int b, int* ret_num_corners, rectangle_t *roi)
{
int num_corners=0;
kp_t* ret_corners;
int rsize= INIT_ALLOC;
int pixel[16];
int x, y;
ret_corners = (kp_t*)xalloc(sizeof(kp_t)*rsize);
make_offsets(pixel, stride);
for(y=3; y < ysize - 3; y++)
for(x=3; x < xsize - 3; x++)
{
const uint8_t* p = im + y*stride + x;
int cb = *p + b;
int c_b= *p - b;
for(int y=roi->y+3; y < roi->h+roi->y-3; y++) {
const uint8_t* p = im + y*stride;
for(int x=roi->x+3; x < roi->w+roi->x-3; x++, p++) {
int cb = *p + b;
int c_b= *p - b;
if(p[pixel[0]] > cb)
if(p[pixel[1]] > cb)
if(p[pixel[2]] > cb)
@ -6024,28 +6020,22 @@ static kp_t* fast9_detect(const uint8_t* im, int xsize, int ysize, int stride, i
continue;
if(num_corners == rsize)
{
rsize*=2;
rsize+=INIT_ALLOC;
ret_corners = (kp_t*)xrealloc(ret_corners, sizeof(kp_t)*rsize);
}
//check if the description at this position/scale fits inside the image
if (x <= KP_SIZE || x >= (xsize-KP_SIZE) ||
y <= KP_SIZE || y >= (ysize-KP_SIZE)) {
if (x <= (roi->x+KP_SIZE) || x >= ((roi->x+roi->w)-KP_SIZE) ||
y <= (roi->y+KP_SIZE) || y >= ((roi->y+roi->h)-KP_SIZE)) {
continue;
}
// check if kp inside ROI
if (roi) {
if (x <= (roi->x+KP_SIZE) || x >= ((roi->x+roi->w)-KP_SIZE) ||
y <= (roi->y+KP_SIZE) || y >= ((roi->y+roi->h)-KP_SIZE)) {
continue;
}
}
ret_corners[num_corners].x = x;
ret_corners[num_corners].y = y;
num_corners++;
}
}
*ret_num_corners = num_corners;
return ret_corners;

View File

@ -491,8 +491,11 @@ static mp_obj_t py_image_draw_keypoints(mp_obj_t image_obj, mp_obj_t kpts_obj)
/* get pointer */
image = py_image_cobj(image_obj);
kpts = (py_kp_obj_t*)kpts_obj;
color_t cl = {.r=0xFF, .g=0xFF, .b=0xFF};
PY_ASSERT_TRUE(image->bpp == 1);
PY_ASSERT_TYPE(kpts_obj, &py_kp_type);
color_t cl = {.r=0xFF, .g=0xFF, .b=0xFF};
for (int i=0; i<kpts->size; i++) {
kp_t *kp = &kpts->kpts[i];
float co = arm_cos_f32(kp->angle);
@ -551,7 +554,7 @@ static mp_obj_t py_image_find_features(mp_obj_t image_obj, mp_obj_t cascade_obj)
mp_obj_t objects_list = mp_const_none;
/* sanity checks */
PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA);
PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QCIF);
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE);
/* get C image pointer */
@ -568,11 +571,12 @@ static mp_obj_t py_image_find_features(mp_obj_t image_obj, mp_obj_t cascade_obj)
/* Add detected objects to the list */
for (int i=0; i<array_length(objects_array); i++) {
struct rectangle *r = array_at(objects_array, 0);
mp_obj_t rec_obj[4];
rec_obj[0] = mp_obj_new_int(r->x);
rec_obj[1] = mp_obj_new_int(r->y);
rec_obj[2] = mp_obj_new_int(r->w);
rec_obj[3] = mp_obj_new_int(r->h);
mp_obj_t rec_obj[4] = {
mp_obj_new_int(r->x),
mp_obj_new_int(r->y),
mp_obj_new_int(r->w),
mp_obj_new_int(r->h),
};
mp_obj_list_append(objects_list, mp_obj_new_tuple(4, rec_obj));
}
@ -617,35 +621,54 @@ static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_ma
{
int threshold = 20;
bool normalized = false;
int kpts_size = 0;
kp_t *kpts = NULL;
py_kp_obj_t *kp_obj =NULL;
/* make sure image is grayscale */
image_t *image = py_image_cobj(args[0]);
rectangle_t roi={0, 0, image->w, image->h};
PY_ASSERT_TRUE(image->bpp == 1);
/* read var args */ //TODO
/* read var args */
mp_map_elem_t *kw_thresh = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("threshold")), MP_MAP_LOOKUP);
if (kw_thresh != NULL) {
threshold = mp_obj_get_int(kw_thresh->value);
}
mp_map_elem_t *kw_norm = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("normalized")), MP_MAP_LOOKUP);
if (kw_norm != NULL) {
normalized = mp_obj_get_int(kw_norm->value);
}
/* run keypoint extractor */
int kpts_size = 0;
kp_t *kpts = fast_detect(image, threshold, &kpts_size, NULL);
freak_find_keypoints(image, kpts, kpts_size, normalized, normalized);
mp_map_elem_t *kw_roi = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("roi")), MP_MAP_LOOKUP);
if (kw_roi != NULL) {
mp_obj_t *array;
mp_obj_get_array_fixed_n(kw_roi->value, 4, &array);
roi.x=mp_obj_get_int(array[0]);
roi.y=mp_obj_get_int(array[1]);
roi.w=mp_obj_get_int(array[2]);
roi.h=mp_obj_get_int(array[3]);
}
/* return keypoints MP object */
kp_obj = m_new_obj(py_kp_obj_t);
kp_obj->base.type = &py_kp_type;
kp_obj->kpts = kpts;
kp_obj->size = kpts_size;
kp_obj->threshold = threshold;
kp_obj->normalized = normalized;
return kp_obj;
/* run keypoint extractor on ROI */
kpts = fast_detect(image, threshold, &kpts_size, &roi);
if (kpts_size) {
/* run keypoint descriptor */
freak_find_keypoints(image, kpts, kpts_size, normalized, normalized);
/* return keypoints MP object */
kp_obj = m_new_obj(py_kp_obj_t);
kp_obj->base.type = &py_kp_type;
kp_obj->kpts = kpts;
kp_obj->size = kpts_size;
kp_obj->threshold = threshold;
kp_obj->normalized = normalized;
return kp_obj;
}
return mp_const_none;
}
static mp_obj_t py_image_match_keypoints(uint n_args, const mp_obj_t *args)
@ -712,7 +735,7 @@ mp_obj_t py_image_load_cascade(mp_obj_t path_obj)
/* detection parameters */
struct cascade cascade = {
.step = 2,
.scale_factor = 0.35f,
.scale_factor = 0.5f,
};
const char *path = mp_obj_str_get_str(path_obj);