diff --git a/lib/imlib/imlib.c b/lib/imlib/imlib.c index b0591b38d..d7a78b83a 100644 --- a/lib/imlib/imlib.c +++ b/lib/imlib/imlib.c @@ -66,20 +66,6 @@ void point_init(point_t *ptr, int x, int y) { ptr->y = y; } -void point_copy(point_t *dst, point_t *src) { - memcpy(dst, src, sizeof(point_t)); -} - -bool point_equal_fast(point_t *ptr0, point_t *ptr1) { - return !memcmp(ptr0, ptr1, sizeof(point_t)); -} - -int point_quadrance(point_t *ptr0, point_t *ptr1) { - int delta_x = ptr0->x - ptr1->x; - int delta_y = ptr0->y - ptr1->y; - return (delta_x * delta_x) + (delta_y * delta_y); -} - void point_rotate(int x, int y, float r, int center_x, int center_y, int16_t *new_x, int16_t *new_y) { x -= center_x; y -= center_y; @@ -216,14 +202,6 @@ void rectangle_init(rectangle_t *ptr, int x, int y, int w, int h) { ptr->h = h; } -void rectangle_copy(rectangle_t *dst, rectangle_t *src) { - memcpy(dst, src, sizeof(rectangle_t)); -} - -bool rectangle_equal_fast(rectangle_t *ptr0, rectangle_t *ptr1) { - return !memcmp(ptr0, ptr1, sizeof(rectangle_t)); -} - bool rectangle_overlap(rectangle_t *ptr0, rectangle_t *ptr1) { int x0 = ptr0->x; int y0 = ptr0->y; @@ -276,18 +254,6 @@ void image_alloc0(image_t *img, size_t size) { memset(img->data, 0, size); } -void image_init(image_t *ptr, int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels) { - ptr->w = w; - ptr->h = h; - ptr->pixfmt = pixfmt; - ptr->size = size; - ptr->pixels = pixels; -} - -void image_copy(image_t *dst, image_t *src, bool deep) { - memcpy(dst, src, sizeof(image_t)); -} - size_t image_line_size(image_t *ptr) { switch (ptr->pixfmt) { case PIXFORMAT_BINARY: { diff --git a/lib/imlib/imlib.h b/lib/imlib/imlib.h index ad0b75cbb..9c4f972bf 100644 --- a/lib/imlib/imlib.h +++ b/lib/imlib/imlib.h @@ -131,9 +131,6 @@ typedef struct point { } point_t; void point_init(point_t *ptr, int x, int y); -void point_copy(point_t *dst, point_t *src); -bool point_equal_fast(point_t *ptr0, point_t *ptr1); -int point_quadrance(point_t *ptr0, point_t *ptr1); void point_rotate(int x, int y, float r, int center_x, int center_y, int16_t *new_x, int16_t *new_y); void point_min_area_rectangle(point_t *corners, point_t *new_corners, int corners_len); @@ -161,22 +158,10 @@ typedef struct rectangle { int16_t h; } rectangle_t; -typedef struct bounding_box_lnk_data { - rectangle_t rect; - float score; - int label_index; -} bounding_box_lnk_data_t; - void rectangle_init(rectangle_t *ptr, int x, int y, int w, int h); -void rectangle_copy(rectangle_t *dst, rectangle_t *src); -bool rectangle_equal_fast(rectangle_t *ptr0, rectangle_t *ptr1); bool rectangle_overlap(rectangle_t *ptr0, rectangle_t *ptr1); void rectangle_intersected(rectangle_t *dst, rectangle_t *src); void rectangle_united(rectangle_t *dst, rectangle_t *src); -float rectangle_iou(rectangle_t *r1, rectangle_t *r2); -void rectangle_nms_add_bounding_box(list_t *bounding_boxes, bounding_box_lnk_data_t *box); -int rectangle_nms_get_bounding_boxes(list_t *bounding_boxes, float threshold, float sigma); -void rectangle_map_bounding_boxes(list_t *bounding_boxes, int window_w, int window_h, rectangle_t *roi); ///////////////// // Color Stuff // @@ -569,8 +554,6 @@ typedef struct image { void image_alloc(image_t *img, size_t size); void image_alloc0(image_t *img, size_t size); -void image_init(image_t *ptr, int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels); -void image_copy(image_t *dst, image_t *src, bool deep); size_t image_line_size(image_t *ptr); size_t image_size(image_t *ptr); bool image_get_mask_pixel(image_t *ptr, int x, int y); diff --git a/lib/imlib/rectangle.c b/lib/imlib/rectangle.c index 452cdae68..bc87d40bc 100644 --- a/lib/imlib/rectangle.c +++ b/lib/imlib/rectangle.c @@ -130,98 +130,3 @@ void rectangle_expand(rectangle_t *r, int x, int y) { r->h = y; } } - -float rectangle_iou(rectangle_t *r1, rectangle_t *r2) { - int x1 = IM_MAX(r1->x, r2->x); - int y1 = IM_MAX(r1->y, r2->y); - int x2 = IM_MIN(r1->x + r1->w, r2->x + r2->w); - int y2 = IM_MIN(r1->y + r1->h, r2->y + r2->h); - int w = IM_MAX(0, x2 - x1); - int h = IM_MAX(0, y2 - y1); - int rect_intersection = w * h; - int rect_union = (r1->w * r1->h) + (r2->w * r2->h) - rect_intersection; - return ((float) rect_intersection) / ((float) rect_union); -} - -// Adds a bounding box to the list of bounding boxes in descending order of score. -void rectangle_nms_add_bounding_box(list_t *bounding_boxes, bounding_box_lnk_data_t *box) { - // Insertion sort bounding boxes by score. - list_lnk_t *it = bounding_boxes->head; - for (; it; it = it->next) { - if (box->score > ((bounding_box_lnk_data_t *) it->data)->score) { - list_insert(bounding_boxes, it, box); - break; - } - } - - if (!it) { - list_push_back(bounding_boxes, box); - } -} - -// Soft non-max supress the list of bounding boxes. Returns the maximum label index of the new list. -int rectangle_nms_get_bounding_boxes(list_t *bounding_boxes, float threshold, float sigma) { - // Soft non-max suppression with a Gaussian is used below, as this provides the best results. - // A Gaussian is used to apply a soft score penalty to overlapping boxes. On loop entry, - // "bounding_boxes" is sorted, but after each iteration, the next highest score must be picked - // again, given that the score penalty changes the order. - float sigma_scale = (sigma > 0.0f) ? (-1.0f / sigma) : 0.0f; - - list_t nms_bounding_boxes; - list_init(&nms_bounding_boxes, sizeof(bounding_box_lnk_data_t)); - - int max_label_index = 0; - - // The first detection has the higest score since the list is sorted. - list_lnk_t *max_it = bounding_boxes->head; - while (list_size(bounding_boxes)) { - bounding_box_lnk_data_t lnk_data; - memcpy(&lnk_data, max_it->data, bounding_boxes->data_len); - list_move_back(&nms_bounding_boxes, bounding_boxes, max_it); - - float max_score = 0.0f; - for (list_lnk_t *it = bounding_boxes->head; it; ) { - bounding_box_lnk_data_t *lnk_data2 = list_get_data(it); - - // Advance to next now as "it" will be invalid if we remove the current item. - list_lnk_t *old_it = it; - it = it->next; - - float iou = rectangle_iou(&lnk_data.rect, &lnk_data2->rect); - // Do not use fast_expf() as it does not output 1 when it's input is 0. - // This will cause the scores of non-overlapping bounding boxes to decay. - lnk_data2->score *= expf(sigma_scale * iou * iou); - - if (lnk_data2->score < threshold) { - list_remove(bounding_boxes, old_it, NULL); - } else if (lnk_data2->score > max_score) { - max_score = lnk_data2->score; - max_it = old_it; - } - } - - // Find the maximum label index for the output list. - max_label_index = IM_MAX(lnk_data.label_index, max_label_index); - } - - // Set the original list pointers to equal the new list. - memcpy(bounding_boxes, &nms_bounding_boxes, sizeof(list_t)); - return max_label_index; -} - -void rectangle_map_bounding_boxes(list_t *bounding_boxes, int window_w, int window_h, rectangle_t *roi) { - float x_scale = roi->w / ((float) window_w); - float y_scale = roi->h / ((float) window_h); - // MAX == KeepAspectRatioByExpanding - MIN == KeepAspectRatio - float scale = IM_MIN(x_scale, y_scale); - int x_offset = fast_floorf((roi->w - (window_w * scale)) / 2.0f) + roi->x; - int y_offset = fast_floorf((roi->h - (window_h * scale)) / 2.0f) + roi->y; - - list_for_each(it, bounding_boxes) { - rectangle_t *rect = &((bounding_box_lnk_data_t *) it->data)->rect; - rect->x = fast_floorf((rect->x * scale) + x_offset); - rect->y = fast_floorf((rect->y * scale) + y_offset); - rect->w = fast_floorf(rect->w * scale); - rect->h = fast_floorf(rect->h * scale); - } -}