Modify LBP to use a cascade

This commit is contained in:
iabdalkader 2014-10-21 16:51:07 +02:00
parent a2780e5a5a
commit cf92de7c8a
3 changed files with 89 additions and 30 deletions

View File

@ -211,7 +211,8 @@ int freak_save_descriptor(kp_t *kpts, int kpts_size, const char *path);
int freak_load_descriptor(kp_t **kpts_out, int *kpts_size_out, const char *path); int freak_load_descriptor(kp_t **kpts_out, int *kpts_size_out, const char *path);
/* LBP Operator */ /* LBP Operator */
uint8_t *imlib_lbp_desc(image_t *image); void imlib_lbp_desc(image_t *image, int div, uint8_t *desc, rectangle_t *roi);
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_distance(uint8_t *d0, uint8_t *d1);
int imlib_lbp_desc_load(const char *path, uint8_t **desc); int imlib_lbp_desc_load(const char *path, uint8_t **desc);

View File

@ -9,6 +9,7 @@
#include "imlib.h" #include "imlib.h"
#include "xalloc.h" #include "xalloc.h"
#include "ff.h" #include "ff.h"
#include "std.h"
#define min(a,b) \ #define min(a,b) \
({ __typeof__ (a) _a = (a); \ ({ __typeof__ (a) _a = (a); \
@ -21,8 +22,7 @@
_a > _b ? _a : _b; }) _a > _b ? _a : _b; })
#define LBP_HIST_SIZE (59) //58 uniform hist + 1 #define LBP_HIST_SIZE (59) //58 uniform hist + 1
#define LBP_NUM_REGIONS (7) //7x7 regions #define LBP_DESC_SIZE (4956)
#define LBP_DESC_SIZE (LBP_NUM_REGIONS*LBP_NUM_REGIONS*LBP_HIST_SIZE)
//const static float lbp_weights [49]= { //const static float lbp_weights [49]= {
// 2.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, // 2.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f,
@ -53,45 +53,95 @@ const static uint8_t uniform_tbl[256] = {
47, 48, 58, 49, 58, 58, 58, 50, 51, 52, 58, 53, 54, 55, 56, 57 47, 48, 58, 49, 58, 58, 58, 50, 51, 52, 58, 53, 54, 55, 56, 57
}; };
uint8_t *imlib_lbp_desc(image_t *image) //(56, 94, 24, 24)
void imlib_lbp_desc(image_t *image, int div, uint8_t *desc, rectangle_t *roi)
{ {
int w = image->w; int RY = roi->h/div;
int h = image->h; int RX = roi->w/div;
int RY = h/LBP_NUM_REGIONS; int s = image->w; //stride
int RX = w/LBP_NUM_REGIONS; int h = (roi->y+RY*div)-3;
int w = (roi->x+RX*div)-3;
uint8_t *data = image->data; uint8_t *data = image->data;
uint8_t *desc = xalloc0(LBP_DESC_SIZE);
for (int y=0; y<h-3; y++) { for (int y=roi->y; y<h; y++) {
int y_idx = (y/RY*(w/RX)); int y_idx = (y-roi->y)/RY*div;
for (int x=0; x<w-3; x++) { for (int x=roi->x; x<w; x++) {
uint8_t lbp=0; uint8_t lbp=0;
int hist_idx = y_idx+x/RX; int hist_idx = y_idx+(x-roi->x)/RX;
uint8_t p = data[(y+1)*w+x+1]; uint8_t p = data[(y+1)*s+x+1];
lbp |= (data[(y+0)*w+x+0] >= p) << 0; lbp |= (data[(y+0)*s+x+0] >= p) << 0;
lbp |= (data[(y+0)*w+x+1] >= p) << 1; lbp |= (data[(y+0)*s+x+1] >= p) << 1;
lbp |= (data[(y+0)*w+x+2] >= p) << 2; lbp |= (data[(y+0)*s+x+2] >= p) << 2;
lbp |= (data[(y+1)*w+x+2] >= p) << 3; lbp |= (data[(y+1)*s+x+2] >= p) << 3;
lbp |= (data[(y+2)*w+x+2] >= p) << 4; lbp |= (data[(y+2)*s+x+2] >= p) << 4;
lbp |= (data[(y+2)*w+x+1] >= p) << 5; lbp |= (data[(y+2)*s+x+1] >= p) << 5;
lbp |= (data[(y+2)*w+x+0] >= p) << 6; lbp |= (data[(y+2)*s+x+0] >= p) << 6;
lbp |= (data[(y+1)*w+x+0] >= p) << 7; lbp |= (data[(y+1)*s+x+0] >= p) << 7;
desc[hist_idx*LBP_HIST_SIZE+uniform_tbl[lbp]]++; desc[hist_idx*LBP_HIST_SIZE+uniform_tbl[lbp]]++;
} }
} }
}
uint8_t *imlib_lbp_cascade(image_t *image, rectangle_t *roi)
{
uint8_t *desc = xalloc0(LBP_DESC_SIZE);
int offset =0;
for (int i=1, c=0; i<=7; i+=2, c++) {
imlib_lbp_desc(image, i, desc+offset, roi);
offset += i*i*LBP_HIST_SIZE;
}
return desc; return desc;
} }
#if 0
int imlib_lbp_desc_distance(uint8_t *d0, uint8_t *d1) int imlib_lbp_desc_distance(uint8_t *d0, uint8_t *d1)
{ {
uint32_t sum = 0; uint32_t sum = 0;
for (int i=0; i<LBP_DESC_SIZE; i++) { float thresh = 0.15f;
sum += (((d0[i] - d1[i]) * (d0[i] - d1[i]))/max((d0[i] + d1[i]),1)); int stages[] = {1*1*59, 3*3*59, 5*5*59, 7*7*59};
for (int i=0, s=0; i<LBP_DESC_SIZE; i++) {
if (i== stages[s]) {
s++;
thresh += 0.25f;
}
sum += (((d0[i] - d1[i]) * (d0[i] - d1[i]))/max((d0[i] + d1[i]), 1)) * thresh;
} }
return sum; return sum;
} }
#else
int imlib_lbp_desc_distance(uint8_t *d0, uint8_t *d1)
{
int size=LBP_DESC_SIZE;
int32_t num = 0;
int32_t den_a=0;
int32_t den_b=0;
int32_t m_a = 0;
int32_t m_b = 0;
for (int i=0; i<size; i++) {
m_a += d0[i];
m_b += d1[i];
}
m_a /= size;
m_b /= size;
for (int i=0; i<size; i++) {
int32_t x =((int)d0[i]) - m_a;
int32_t y =((int)d1[i]) - m_b;
num += x*y;
den_a += x*x;
den_b += y*y;
}
return (num/(fast_sqrtf(den_a) * fast_sqrtf(den_b)))*100;
}
#endif
int imlib_lbp_desc_load(const char *path, uint8_t **desc) int imlib_lbp_desc_load(const char *path, uint8_t **desc)
{ {

View File

@ -359,6 +359,7 @@ static mp_obj_t py_image_binary(mp_obj_t image_obj, mp_obj_t threshold)
return mp_const_none; return mp_const_none;
} }
static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj, mp_obj_t threshold) static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj, mp_obj_t threshold)
{ {
color_t *color; color_t *color;
@ -587,9 +588,6 @@ static mp_obj_t py_image_find_blobs(mp_obj_t image_obj)
/* MP List */ /* MP List */
mp_obj_t objects_list = mp_const_none; mp_obj_t objects_list = mp_const_none;
/* sanity checks */
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565);
/* get image pointer */ /* get image pointer */
image = py_image_cobj(image_obj); image = py_image_cobj(image_obj);
@ -755,7 +753,7 @@ static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_ma
return mp_const_none; return mp_const_none;
} }
static mp_obj_t py_image_find_lbp(mp_obj_t image_obj) static mp_obj_t py_image_find_lbp(mp_obj_t image_obj, mp_obj_t roi_obj)
{ {
image_t *image; image_t *image;
py_lbp_obj_t *lbp_obj; py_lbp_obj_t *lbp_obj;
@ -763,9 +761,19 @@ static mp_obj_t py_image_find_lbp(mp_obj_t image_obj)
image = py_image_cobj(image_obj); image = py_image_cobj(image_obj);
PY_ASSERT_TRUE(image->bpp == 1); PY_ASSERT_TRUE(image->bpp == 1);
mp_obj_t *array;
mp_obj_get_array_fixed_n(roi_obj, 4, &array);
rectangle_t roi = {
mp_obj_get_int(array[0]),
mp_obj_get_int(array[1]),
mp_obj_get_int(array[2]),
mp_obj_get_int(array[3]),
};
lbp_obj = m_new_obj(py_lbp_obj_t); lbp_obj = m_new_obj(py_lbp_obj_t);
lbp_obj->base.type = &py_lbp_type; lbp_obj->base.type = &py_lbp_type;
lbp_obj->hist = imlib_lbp_desc(image); lbp_obj->hist = imlib_lbp_cascade(image, &roi);
return lbp_obj; return lbp_obj;
} }
@ -930,7 +938,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_find_blobs_obj, py_image_find_blobs);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_find_template_obj, py_image_find_template); STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_find_template_obj, py_image_find_template);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_features_obj, 2, py_image_find_features); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_features_obj, 2, py_image_find_features);
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_keypoints_obj, 1, py_image_find_keypoints);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_find_lbp_obj, py_image_find_lbp); STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_find_lbp_obj, py_image_find_lbp);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_image_match_keypoints_obj, 4, 4, py_image_match_keypoints); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_image_match_keypoints_obj, 4, 4, py_image_match_keypoints);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_match_lbp_obj, py_image_match_lbp); STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_match_lbp_obj, py_image_match_lbp);