From ca390130971bf7bbca2aae592d9a9e86394bac94 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 13 Feb 2014 03:12:11 +0200 Subject: [PATCH] Update imlib * Use image for imlib functions * Rename some types --- src/imlib.c | 273 +++++++++++++++++++++++++++------------------------- src/imlib.h | 46 ++++----- 2 files changed, 163 insertions(+), 156 deletions(-) diff --git a/src/imlib.c b/src/imlib.c index 148ec9289..f00d784fa 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -17,6 +17,8 @@ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) +#define MAX_GRAY_LEVEL (255) + float imlib_distance(struct color *c0, struct color *c1) { float sum=0.0f; @@ -28,7 +30,7 @@ float imlib_distance(struct color *c0, struct color *c1) void imlib_rgb_to_hsv(struct color *rgb, struct color *hsv) { - int min; + int min; int max; int r,g,b; int delta; @@ -38,8 +40,8 @@ void imlib_rgb_to_hsv(struct color *rgb, struct color *hsv) g = rgb->g*100/255; b = rgb->b*100/255; - min = MIN(r, MIN(g, b)); - max = MAX(r, MAX(g, b)); + min = MIN(r, MIN(g, b)); + max = MAX(r, MAX(g, b)); if (min == max) { /* Black/gray/white */ @@ -66,12 +68,12 @@ void imlib_rgb_to_hsv(struct color *rgb, struct color *hsv) } /* converts a grayscale buffer to RGB565 to display on LCDs */ -void imlib_grayscale_to_rgb565(struct frame_buffer *fb) +void imlib_grayscale_to_rgb565(struct image *image) { #if 0 int i; - for (i=0; i<(fb->width * fb->height * fb->bpp); i++) { - uint8_t y = fb->pixels[i]; + for (i=0; i<(image->w * image->h * image->bpp); i++) { + uint8_t y = image->pixels[i]; uint8_t r = y*31/255; uint8_t g = y*63/255; uint8_t b = y*31/255; @@ -80,7 +82,7 @@ void imlib_grayscale_to_rgb565(struct frame_buffer *fb) #endif } -void imlib_color_track(struct frame_buffer *fb, struct color *color, struct point *point, int threshold) +void imlib_detect_color(struct image *image, struct color *color, struct rectangle *rectangle, int threshold) { int x,y; uint8_t p0,p1; @@ -88,17 +90,19 @@ void imlib_color_track(struct frame_buffer *fb, struct color *color, struct poin struct color hsv; int pixels = 1; - point->x = 0; - point->y = 0; + rectangle->w = 0; + rectangle->h = 0; + rectangle->x = image->w; + rectangle->y = image->h; //to avoid sqrt we use squared values threshold *= threshold; - for (y=0; yheight; y++) { - for (x=0; xwidth; x++) { - int i=y*fb->width*fb->bpp+x*fb->bpp; - p0 = fb->pixels[i]; - p1 = fb->pixels[i+1]; + for (y=0; yh; y++) { + for (x=0; xw; x++) { + int i=y*image->w*image->bpp+x*image->bpp; + p0 = image->pixels[i]; + p1 = image->pixels[i+1]; /* map RGB565 to RGB888 */ rgb.r = (uint8_t) (p0>>3) * 255/31; @@ -114,75 +118,83 @@ void imlib_color_track(struct frame_buffer *fb, struct color *color, struct poin /* add pixel if within threshold */ if (hsv.h < threshold && hsv.s > color->s && hsv.v > color->v) { //s==pale pixels++; - point->x += x; - point->y += y; + if (x < rectangle->x) { + rectangle->x = x; + } + if (y < rectangle->y) { + rectangle->y = y; + } + + if (x > rectangle->w) { + rectangle->w = x; + } + if (y > rectangle->h) { + rectangle->h = y; + } } } } - if (pixels < 10) { - point->x = 0; - point->y = 0; - } else { - point->x /= pixels; - point->y /= pixels; - } + rectangle->w = rectangle->w-rectangle->x; + rectangle->h = rectangle->h-rectangle->y; } -void imlib_erosion_filter(struct frame_buffer *fb, uint8_t *kernel, int k_size) +void imlib_erosion_filter(struct image *src, uint8_t *kernel, int k_size) { int x, y, j, k; - int w = fb->width; - int h = fb->height; + int w = src->w; + int h = src->h; + /* TODO */ uint8_t *dst = calloc(w*h, 1); - + for (y=0; ypixels[w*(y+j)+x+k] != (kernel[j*k_size+k]*255)) { + if (src->pixels[w*(y+j)+x+k] != (kernel[j*k_size+k]*255)) { dst[w*(y+1)+x+1] = 0; j=k_size; break; } } } - } + } } - memcpy(fb->pixels, dst, w*h); + memcpy(src->pixels, dst, w*h); free(dst); } -void imlib_integral_image(struct frame_buffer *src, struct integral_image *sum) +void imlib_integral_image(struct image *src, struct integral_image *sum) { - int x, y, s,t; - unsigned char *data = src->data; - typeof(*sum->data) *sumData = sum->data; - for (y=0; yheight; y++) { - s = 0; - /* loop over the number of columns */ - for (x=0; xwidth; x++) { - /* sum of the current row (integer)*/ - s += data[y*src->width+x]; - t = s; - if (y != 0) { - t += sumData[(y-1)*src->width+x]; - } - sumData[y*src->width+x]=t; - } - } + int x, y, s,t; + unsigned char *data = src->pixels; + typeof(*sum->data) *sumData = sum->data; + + for (y=0; yh; y++) { + s = 0; + /* loop over the number of columns */ + for (x=0; xw; x++) { + /* sum of the current row (integer)*/ + s += data[y*src->w+x]; + t = s; + if (y != 0) { + t += sumData[(y-1)*src->w+x]; + } + sumData[y*src->w+x]=t; + } + } } -void imlib_scale_image(struct frame_buffer *src, struct frame_buffer *dst) +void imlib_scale_image(struct image *src, struct image *dst) { int x, y, i, j; uint8_t *t, *p; - int w1 = src->width; - int h1 = src->height; - int w2 = dst->width; - int h2 = dst->height; + int w1 = src->w; + int h1 = src->h; + int w2 = dst->w; + int h2 = dst->h; int rat = 0; @@ -205,53 +217,57 @@ void imlib_scale_image(struct frame_buffer *src, struct frame_buffer *dst) } } -void imlib_draw_rectangle(struct frame_buffer* image, struct rectangle *r) +void imlib_draw_rectangle(struct image *image, struct rectangle *r) { - int i; - int bpp = image->bpp; - int col = image->width*image->bpp; - uint8_t c=0xff; - for (i = 0; i < r->width*bpp; i++) { - image->data[r->y*col + r->x*bpp + i] = c; - } + int i; + uint8_t c=0xFF; + int x = MIN(MAX(r->x, 0), image->w); + int y = MIN(MAX(r->y, 0), image->h); + int w = (x+r->w) > image->w ? (image->w-x):r->w; + int h = (y+r->h) > image->h ? (image->h-y):r->h; - for (i = 0; i < r->height; i++) { - image->data[col*(r->y+i) + r->x*bpp + r->width*bpp] = c; - } + x *= image->bpp; + w *= image->bpp; + int col = image->w*image->bpp; - for (i = 0; i < r->width*bpp; i++) { - image->data[col*(r->y + r->height) + r->x*bpp + r->width*bpp - i] = c; - } + for (i=0; ipixels[y*col + x + i] = c; + image->pixels[(y+h)*col + x + i] = c; + } - for (i = 0; i < r->height; i++) { - image->data[col*(r->y + r->height - i) + r->x*bpp] =c; - } + for (i=0; ipixels[(y+i)*col + x] = c; + image->pixels[(y+i)*col + x + w-2] = c; + if (image->bpp>1) { + image->pixels[(y+i)*col + x+1] = c; + image->pixels[(y+i)*col + x + w-1] = c; + } + } } -#define MAX_GRAY_LEVEL (255) -void imlib_histeq(struct frame_buffer *fb) +void imlib_histeq(struct image *src) { int i, sum; - int a = fb->width*fb->height; - uint32_t hist[MAX_GRAY_LEVEL+1]={0}; + int a = src->w*src->h; + uint32_t hist[MAX_GRAY_LEVEL+1]={0}; /* compute image histogram */ for (i=0; ipixels[i]]+=1; + hist[src->pixels[i]]+=1; } - /* compute the CDF */ + /* compute the CDF */ for (i=0, sum=0; ipixels[i] = (uint8_t) ((MAX_GRAY_LEVEL/(float)a) * hist[fb->pixels[i]]); + src->pixels[i] = (uint8_t) ((MAX_GRAY_LEVEL/(float)a) * hist[src->pixels[i]]); } } -/* Viola-Jones face detector implementation +/* Viola-Jones face detector implementation * Original Author: Francesco Comaschi (f.comaschi@tue.nl) */ static int evalWeakClassifier(struct integral_image *sum, int std, int p_offset, int tree_index, int w_index, int r_index ) @@ -270,7 +286,7 @@ static int evalWeakClassifier(struct integral_image *sum, int std, int p_offset, int i,k, sumw=0; - if ((tr.x)&& (tr.y) &&(tr.width) &&(tr.height)) { + if ((tr.x)&& (tr.y) &&(tr.w) &&(tr.h)) { k = 3; } else { k = 2; @@ -283,13 +299,13 @@ static int evalWeakClassifier(struct integral_image *sum, int std, int p_offset, tr.h = rectangles_array[r_index + i*4 + 3]; sumw += ( - *((sum->data + sum->width*(tr.y ) + (tr.x )) + p_offset) - - *((sum->data + sum->width*(tr.y ) + (tr.x + tr.width)) + p_offset) - - *((sum->data + sum->width*(tr.y + tr.height) + (tr.x )) + p_offset) - + *((sum->data + sum->width*(tr.y + tr.height) + (tr.x + tr.width)) + p_offset)) + *((sum->data + sum->w*(tr.y ) + (tr.x )) + p_offset) + - *((sum->data + sum->w*(tr.y ) + (tr.x + tr.w)) + p_offset) + - *((sum->data + sum->w*(tr.y + tr.h) + (tr.x )) + p_offset) + + *((sum->data + sum->w*(tr.y + tr.h) + (tr.x + tr.w)) + p_offset)) * weights_array[w_index + i]; } - + if (sumw >= t) { return alpha2_array[tree_index]; } @@ -308,42 +324,42 @@ static int runCascadeClassifier(struct cascade* cascade, struct point pt, int st int r_index = 0; int stage_sum; int tree_index = 0; - + int x,y,offset; uint32_t sumsq=0; vec_t v0, v1; for (y=pt.y; y<24; y++) { for (x=pt.x; x<24; x+=2) { - offset = y*cascade->img->width+x; - v0.s0 = cascade->img->data[offset+0]; - v0.s1 = cascade->img->data[offset+1]; + offset = y*cascade->img->w+x; + v0.s0 = cascade->img->pixels[offset+0]; + v0.s1 = cascade->img->pixels[offset+1]; - v1.s0 = cascade->img->data[offset+0]; - v1.s1 = cascade->img->data[offset+1]; + v1.s0 = cascade->img->pixels[offset+0]; + v1.s1 = cascade->img->pixels[offset+1]; sumsq = __SMLAD(v0.i, v1.i, sumsq); } } /* Image normalization */ - int win_w = cascade->window.width - 1; - int win_h = cascade->window.height - 1; + int win_w = cascade->window.w - 1; + int win_h = cascade->window.h - 1; - p_offset = pt.y * (cascade->sum.width) + pt.x; + p_offset = pt.y * (cascade->sum.w) + pt.x; mean = cascade->sum.data[p_offset] - cascade->sum.data[win_w + p_offset] - - cascade->sum.data[cascade->sum.width * win_h + p_offset] - + cascade->sum.data[cascade->sum.width * win_h + win_w + p_offset]; + - cascade->sum.data[cascade->sum.w * win_h + p_offset] + + cascade->sum.data[cascade->sum.w * win_h + win_w + p_offset]; - std = sqrtf(sumsq * cascade->window.width * cascade->window.height - mean * mean); + std = sqrtf(sumsq * cascade->window.w * cascade->window.h - mean * mean); for (i=start_stage; in_stages; i++) { stage_sum = 0; for (j=0; jsum, std, p_offset, tree_index, w_index, r_index); - } + } /* If the sum is below the stage threshold, no faces are detected */ if (stage_sum < 0.4*stages_thresh_array[i]) { @@ -362,12 +378,12 @@ static void ScaleImageInvoker(struct cascade *cascade, float factor, int sum_row struct point p; struct size win_size; - win_size.width = roundf(cascade->window.width*factor); - win_size.height = roundf(cascade->window.height*factor); + win_size.w = roundf(cascade->window.w*factor); + win_size.h = roundf(cascade->window.h*factor); /* When filter window shifts to image boarder, some margin need to be kept */ - y2 = sum_row - win_size.height; - x2 = sum_col - win_size.width; + y2 = sum_row - win_size.h; + x2 = sum_col - win_size.w; /* Shift the filter window over the image. */ for (x=0; x<=x2; x+=cascade->step) { @@ -382,8 +398,8 @@ static void ScaleImageInvoker(struct cascade *cascade, float factor, int sum_row struct rectangle *r = malloc(sizeof(struct rectangle)); r->x = roundf(x*factor); r->y = roundf(y*factor); - r->w = win_size.width; - r->h = win_size.height; + r->w = win_size.w; + r->h = win_size.h; array_push_back(vec, r); } } @@ -447,7 +463,7 @@ struct array *imlib_merge_detections(struct array *rectangles) rect1 = (struct rectangle *) array_at(rectangles, 0); for (j=1; jwidth; - img.height = fb->height; - /* use the second half of the frame_buffer */ - img.pixels = fb->pixels+(fb->width * fb->height); + img.w = image->w; + img.h = image->h; + img.bpp = image->bpp; + /* use the second half of the framebuffer */ + img.pixels = image->pixels+(image->w * image->h); /* allocate buffer for integral image */ - sum.width = fb->width; - sum.height = fb->height; - //sum.data = malloc(fb->width *fb->height*sizeof(*sum.data)); - sum.data = (uint32_t*) fb->pixels+(fb->width * fb->height * 2); + sum.w = image->w; + sum.h = image->h; + //sum.data = malloc(image->w *image->h*sizeof(*sum.data)); + sum.data = (uint32_t*) (image->pixels+(image->w * image->h * 2)); /* allocate the detections array */ array_alloc(&objects, free); @@ -503,26 +520,26 @@ struct array *imlib_detect_objects(struct cascade *cascade, struct frame_buffer /* iterate over the image pyramid */ for(factor=1.0f; ; factor*=cascade->scale_factor) { /* size of the scaled image */ - struct size sz = { - (fb->width/factor), - (fb->height/factor) + struct size sz = { + (image->w/factor), + (image->h/factor) }; /* if scaled image is smaller than the original detection window, break */ - if ((sz.width - cascade->window.width) <= 0 || - (sz.height - cascade->window.height) <= 0) { + if ((sz.w - cascade->window.w) <= 0 || + (sz.h - cascade->window.h) <= 0) { break; } - /* Set the width and height of the images */ - img.width = sz.width; - img.height = sz.height; + /* Set the width and height of the images */ + img.w = sz.w; + img.h = sz.h; - sum.width = sz.width; - sum.height = sz.height; + sum.w = sz.w; + sum.h = sz.h; /* downsample using nearest neighbor */ - imlib_scale_image(fb, &img); + imlib_scale_image(image, &img); /* compute a new integral image */ imlib_integral_image(&img, &sum); @@ -531,7 +548,7 @@ struct array *imlib_detect_objects(struct cascade *cascade, struct frame_buffer cascade->sum = sum; /* process the current scale with the cascaded fitler. */ - ScaleImageInvoker(cascade, factor, sum.height, sum.width, objects); + ScaleImageInvoker(cascade, factor, sum.h, sum.w, objects); } //free(sum.data); @@ -539,5 +556,3 @@ struct array *imlib_detect_objects(struct cascade *cascade, struct frame_buffer objects = imlib_merge_detections(objects); return objects; } - - diff --git a/src/imlib.h b/src/imlib.h index c28fa7c7b..de0ae7e2a 100644 --- a/src/imlib.h +++ b/src/imlib.h @@ -7,21 +7,15 @@ struct point { }; struct size { - int width; - int height; + int w; + int h; }; struct rectangle { int x; int y; - union { - int width; - int w; - }; - union { - int h; - int height; - }; + int w; + int h; }; struct color { @@ -39,19 +33,16 @@ struct color { }; }; -struct frame_buffer { - int width; - int height; +struct image { + int w; + int h; int bpp; - union { - uint8_t *data; - uint8_t *pixels; - }; + uint8_t *pixels; }; struct integral_image { - int width; - int height; + int w; + int h; uint32_t *data; }; @@ -86,16 +77,17 @@ struct cascade { /* pointer to current integral image */ struct integral_image sum; /* pointer to current scaled image in the pyramid */ - struct frame_buffer *img; + struct image *img; }; float imlib_distance(struct color *c0, struct color *c1); void imlib_rgb_to_hsv(struct color *rgb, struct color *hsv); -void imlib_grayscale_to_rgb565(struct frame_buffer *fb); -void imlib_color_track(struct frame_buffer *fb, struct color *color, struct point *point, int threshold); -void imlib_erosion_filter(struct frame_buffer *fb, uint8_t *kernel, int k_size); -void imlib_scale_image(struct frame_buffer *src, struct frame_buffer *dst); -void imlib_integral_image(struct frame_buffer *src, struct integral_image *sum); -void imlib_draw_rectangle(struct frame_buffer* image, struct rectangle *r); -struct array *imlib_detect_objects(struct cascade* cascade, struct frame_buffer* fb); +void imlib_grayscale_to_rgb565(struct image *image); +void imlib_detect_color(struct image *image, struct color *color, struct rectangle *rectangle, int threshold); +void imlib_erosion_filter(struct image *src, uint8_t *kernel, int k_size); +void imlib_scale_image(struct image *src, struct image *dst); +void imlib_integral_image(struct image *src, struct integral_image *sum); +void imlib_draw_rectangle(struct image *image, struct rectangle *r); +void imlib_histeq(struct image *src); +struct array *imlib_detect_objects(struct image *image, struct cascade* cascade); #endif //__IMLIB_H__