Change Iris detector to work on a single region.

* This allows the detector to work on ROIs detected by the eye Haar
  cascade, which improves the accuracy and speed of the detection.
This commit is contained in:
iabdalkader 2016-02-21 20:38:01 +02:00
parent e18058f27c
commit 50e53c91bc
3 changed files with 44 additions and 56 deletions

View File

@ -11,7 +11,7 @@
#include "xalloc.h"
#include "fmath.h"
static void imlib_find_gradients(image_t *src, array_t *gradients, int x_off, int y_off, int box_w, int box_h)
static void find_gradients(image_t *src, array_t *gradients, int x_off, int y_off, int box_w, int box_h)
{
for (int y=y_off; y<y_off+box_h-3; y++) {
for (int x=x_off; x<x_off+box_w-3; x++) {
@ -46,15 +46,32 @@ static void imlib_find_gradients(image_t *src, array_t *gradients, int x_off, in
}
}
static void imlib_find_pupil(image_t *src, array_t *gradients, int x_off, int y_off, int box_w, int box_h, point_t *e)
// TODO use the gradients median not average
static void filter_gradients(array_t *gradients)
{
float total_m=0.0f;
for (int i=0; i<array_length(gradients); i++) {
vec_t *v = (vec_t *) array_at(gradients, i);
total_m += v->m;
}
float avg_m = total_m/array_length(gradients);
for (int i=0; i<array_length(gradients); i++) {
vec_t *v = (vec_t *) array_at(gradients, i);
float diff =(v->m-avg_m) * (v->m-avg_m);
if (fast_sqrtf(diff)>100) {
array_erase(gradients, i);
}
}
}
static void find_iris(image_t *src, array_t *gradients, int x_off, int y_off, int box_w, int box_h, point_t *e)
{
int max_x=0;
int max_y=0;
float max_dot = 0.0f;
// rectangle_t r = {x_off, y_off, box_w, box_h};
// imlib_draw_rectangle(src, &r);
for (int y=y_off; y<y_off+box_h; y++) {
for (int x=x_off; x<x_off+box_w; x++) {
float sum_dot=0.0f;
@ -94,53 +111,26 @@ static void imlib_find_pupil(image_t *src, array_t *gradients, int x_off, int y_
e->y = max_y;
}
// TODO use the gradients median not average
static void imlib_filter_gradients(array_t *gradients)
// This function should be called on an ROI detected with the eye Haar cascade.
void imlib_find_iris(image_t *src, point_t *iris, rectangle_t *roi)
{
float total_m=0.0f;
for (int i=0; i<array_length(gradients); i++) {
vec_t *v = (vec_t *) array_at(gradients, i);
total_m += v->m;
}
array_t *iris_gradients;
array_alloc(&iris_gradients, xfree);
float avg_m = total_m/array_length(gradients);
for (int i=0; i<array_length(gradients); i++) {
vec_t *v = (vec_t *) array_at(gradients, i);
float diff =(v->m-avg_m) * (v->m-avg_m);
if (fast_sqrtf(diff)>100) {
array_erase(gradients, i);
}
}
}
void imlib_find_eyes(image_t *src, point_t *left, point_t *right, rectangle_t *roi)
{
array_t *left_gradients, *right_gradients;
array_alloc(&left_gradients, xfree);
array_alloc(&right_gradients, xfree);
int box_w = roi->w/3;
int box_h = roi->h/4;
int l_x_off = roi->x+((int)(0.15f*roi->w));
int l_y_off = roi->y+((int)(0.30f*roi->h));
int r_x_off = roi->x+((int)(0.55f*roi->w));
int r_y_off = roi->y+((int)(0.30f*roi->h));
// Tune these offsets to avoid eyebrows and reduce window size
int box_w = roi->w;
int box_h = roi->h;
int x_off = roi->x+((int)(0.25f*roi->w));
int y_off = roi->y+((int)(0.25f*roi->h));
// find gradients with strong magnitudes
imlib_find_gradients(src, left_gradients, l_x_off, l_y_off, box_w, box_h);
imlib_find_gradients(src, right_gradients, r_x_off, r_y_off, box_w, box_h);
find_gradients(src, iris_gradients, x_off, y_off, box_w, box_h);
// filter gradients
imlib_filter_gradients(left_gradients);
imlib_filter_gradients(right_gradients);
filter_gradients(iris_gradients);
// search for pupils
imlib_find_pupil(src, left_gradients, l_x_off, l_y_off, box_w, box_h, left);
imlib_find_pupil(src, right_gradients, r_x_off, r_y_off, box_w, box_h, right);
// search for iriss
find_iris(src, iris_gradients, x_off, y_off, box_w, box_h, iris);
array_free(left_gradients);
array_free(right_gradients);
array_free(iris_gradients);
}

View File

@ -382,8 +382,8 @@ uint8_t *imlib_lbp_cascade(image_t *image, rectangle_t *roi);
int imlib_lbp_desc_distance(uint8_t *d0, uint8_t *d1);
int imlib_lbp_desc_load(const char *path, uint8_t **desc);
/* Eye detector */
void imlib_find_eyes(image_t *src, point_t *left, point_t *right, rectangle_t *roi);
/* Iris detector */
void imlib_find_iris(image_t *src, point_t *iris, rectangle_t *roi);
/* Misc */
void imlib_scale(struct image *src, struct image *dst, interp_t interp);

View File

@ -1234,17 +1234,15 @@ static mp_obj_t py_image_find_eyes(mp_obj_t image_obj, mp_obj_t roi_obj)
mp_obj_get_int(array[3]),
};
point_t l={0}, r={0};
imlib_find_eyes(image, &l, &r, &roi);
point_t iris;
imlib_find_iris(image, &iris, &roi);
mp_obj_t eyes_obj[4] = {
mp_obj_new_int(l.x),
mp_obj_new_int(l.y),
mp_obj_new_int(r.x),
mp_obj_new_int(r.y),
mp_obj_t eyes_obj[2] = {
mp_obj_new_int(iris.x),
mp_obj_new_int(iris.y),
};
return mp_obj_new_tuple(4, eyes_obj);
return mp_obj_new_tuple(2, eyes_obj);
}
static mp_obj_t py_image_match_keypoints(uint n_args, const mp_obj_t *args)