box.c
Go to the documentation of this file.
00001 #include "box.h"
00002 #include <stdio.h>
00003 #include <math.h>
00004 #include <stdlib.h>
00005 
00006 box float_to_box(float *f)
00007 {
00008     box b;
00009     b.x = f[0];
00010     b.y = f[1];
00011     b.w = f[2];
00012     b.h = f[3];
00013     return b;
00014 }
00015 
00016 dbox derivative(box a, box b)
00017 {
00018     dbox d;
00019     d.dx = 0;
00020     d.dw = 0;
00021     float l1 = a.x - a.w/2;
00022     float l2 = b.x - b.w/2;
00023     if (l1 > l2){
00024         d.dx -= 1;
00025         d.dw += .5;
00026     }
00027     float r1 = a.x + a.w/2;
00028     float r2 = b.x + b.w/2;
00029     if(r1 < r2){
00030         d.dx += 1;
00031         d.dw += .5;
00032     }
00033     if (l1 > r2) {
00034         d.dx = -1;
00035         d.dw = 0;
00036     }
00037     if (r1 < l2){
00038         d.dx = 1;
00039         d.dw = 0;
00040     }
00041 
00042     d.dy = 0;
00043     d.dh = 0;
00044     float t1 = a.y - a.h/2;
00045     float t2 = b.y - b.h/2;
00046     if (t1 > t2){
00047         d.dy -= 1;
00048         d.dh += .5;
00049     }
00050     float b1 = a.y + a.h/2;
00051     float b2 = b.y + b.h/2;
00052     if(b1 < b2){
00053         d.dy += 1;
00054         d.dh += .5;
00055     }
00056     if (t1 > b2) {
00057         d.dy = -1;
00058         d.dh = 0;
00059     }
00060     if (b1 < t2){
00061         d.dy = 1;
00062         d.dh = 0;
00063     }
00064     return d;
00065 }
00066 
00067 float overlap(float x1, float w1, float x2, float w2)
00068 {
00069     float l1 = x1 - w1/2;
00070     float l2 = x2 - w2/2;
00071     float left = l1 > l2 ? l1 : l2;
00072     float r1 = x1 + w1/2;
00073     float r2 = x2 + w2/2;
00074     float right = r1 < r2 ? r1 : r2;
00075     return right - left;
00076 }
00077 
00078 float box_intersection(box a, box b)
00079 {
00080     float w = overlap(a.x, a.w, b.x, b.w);
00081     float h = overlap(a.y, a.h, b.y, b.h);
00082     if(w < 0 || h < 0) return 0;
00083     float area = w*h;
00084     return area;
00085 }
00086 
00087 float box_union(box a, box b)
00088 {
00089     float i = box_intersection(a, b);
00090     float u = a.w*a.h + b.w*b.h - i;
00091     return u;
00092 }
00093 
00094 float box_iou(box a, box b)
00095 {
00096     return box_intersection(a, b)/box_union(a, b);
00097 }
00098 
00099 float box_rmse(box a, box b)
00100 {
00101     return sqrt(pow(a.x-b.x, 2) + 
00102                 pow(a.y-b.y, 2) + 
00103                 pow(a.w-b.w, 2) + 
00104                 pow(a.h-b.h, 2));
00105 }
00106 
00107 dbox dintersect(box a, box b)
00108 {
00109     float w = overlap(a.x, a.w, b.x, b.w);
00110     float h = overlap(a.y, a.h, b.y, b.h);
00111     dbox dover = derivative(a, b);
00112     dbox di;
00113 
00114     di.dw = dover.dw*h;
00115     di.dx = dover.dx*h;
00116     di.dh = dover.dh*w;
00117     di.dy = dover.dy*w;
00118 
00119     return di;
00120 }
00121 
00122 dbox dunion(box a, box b)
00123 {
00124     dbox du;
00125 
00126     dbox di = dintersect(a, b);
00127     du.dw = a.h - di.dw;
00128     du.dh = a.w - di.dh;
00129     du.dx = -di.dx;
00130     du.dy = -di.dy;
00131 
00132     return du;
00133 }
00134 
00135 
00136 void test_dunion()
00137 {
00138     box a = {0, 0, 1, 1};
00139     box dxa= {0+.0001, 0, 1, 1};
00140     box dya= {0, 0+.0001, 1, 1};
00141     box dwa= {0, 0, 1+.0001, 1};
00142     box dha= {0, 0, 1, 1+.0001};
00143 
00144     box b = {.5, .5, .2, .2};
00145     dbox di = dunion(a,b);
00146     printf("Union: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
00147     float inter =  box_union(a, b);
00148     float xinter = box_union(dxa, b);
00149     float yinter = box_union(dya, b);
00150     float winter = box_union(dwa, b);
00151     float hinter = box_union(dha, b);
00152     xinter = (xinter - inter)/(.0001);
00153     yinter = (yinter - inter)/(.0001);
00154     winter = (winter - inter)/(.0001);
00155     hinter = (hinter - inter)/(.0001);
00156     printf("Union Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
00157 }
00158 void test_dintersect()
00159 {
00160     box a = {0, 0, 1, 1};
00161     box dxa= {0+.0001, 0, 1, 1};
00162     box dya= {0, 0+.0001, 1, 1};
00163     box dwa= {0, 0, 1+.0001, 1};
00164     box dha= {0, 0, 1, 1+.0001};
00165 
00166     box b = {.5, .5, .2, .2};
00167     dbox di = dintersect(a,b);
00168     printf("Inter: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
00169     float inter =  box_intersection(a, b);
00170     float xinter = box_intersection(dxa, b);
00171     float yinter = box_intersection(dya, b);
00172     float winter = box_intersection(dwa, b);
00173     float hinter = box_intersection(dha, b);
00174     xinter = (xinter - inter)/(.0001);
00175     yinter = (yinter - inter)/(.0001);
00176     winter = (winter - inter)/(.0001);
00177     hinter = (hinter - inter)/(.0001);
00178     printf("Inter Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
00179 }
00180 
00181 void test_box()
00182 {
00183     test_dintersect();
00184     test_dunion();
00185     box a = {0, 0, 1, 1};
00186     box dxa= {0+.00001, 0, 1, 1};
00187     box dya= {0, 0+.00001, 1, 1};
00188     box dwa= {0, 0, 1+.00001, 1};
00189     box dha= {0, 0, 1, 1+.00001};
00190 
00191     box b = {.5, 0, .2, .2};
00192 
00193     float iou = box_iou(a,b);
00194     iou = (1-iou)*(1-iou);
00195     printf("%f\n", iou);
00196     dbox d = diou(a, b);
00197     printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh);
00198 
00199     float xiou = box_iou(dxa, b);
00200     float yiou = box_iou(dya, b);
00201     float wiou = box_iou(dwa, b);
00202     float hiou = box_iou(dha, b);
00203     xiou = ((1-xiou)*(1-xiou) - iou)/(.00001);
00204     yiou = ((1-yiou)*(1-yiou) - iou)/(.00001);
00205     wiou = ((1-wiou)*(1-wiou) - iou)/(.00001);
00206     hiou = ((1-hiou)*(1-hiou) - iou)/(.00001);
00207     printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou);
00208 }
00209 
00210 dbox diou(box a, box b)
00211 {
00212     float u = box_union(a,b);
00213     float i = box_intersection(a,b);
00214     dbox di = dintersect(a,b);
00215     dbox du = dunion(a,b);
00216     dbox dd = {0,0,0,0};
00217 
00218     if(i <= 0 || 1) {
00219         dd.dx = b.x - a.x;
00220         dd.dy = b.y - a.y;
00221         dd.dw = b.w - a.w;
00222         dd.dh = b.h - a.h;
00223         return dd;
00224     }
00225 
00226     dd.dx = 2*pow((1-(i/u)),1)*(di.dx*u - du.dx*i)/(u*u);
00227     dd.dy = 2*pow((1-(i/u)),1)*(di.dy*u - du.dy*i)/(u*u);
00228     dd.dw = 2*pow((1-(i/u)),1)*(di.dw*u - du.dw*i)/(u*u);
00229     dd.dh = 2*pow((1-(i/u)),1)*(di.dh*u - du.dh*i)/(u*u);
00230     return dd;
00231 }
00232 
00233 typedef struct{
00234     int index;
00235     int class;
00236     float **probs;
00237 } sortable_bbox;
00238 
00239 int nms_comparator(const void *pa, const void *pb)
00240 {
00241     sortable_bbox a = *(sortable_bbox *)pa;
00242     sortable_bbox b = *(sortable_bbox *)pb;
00243     float diff = a.probs[a.index][b.class] - b.probs[b.index][b.class];
00244     if(diff < 0) return 1;
00245     else if(diff > 0) return -1;
00246     return 0;
00247 }
00248 
00249 void do_nms_sort(box *boxes, float **probs, int total, int classes, float thresh)
00250 {
00251     int i, j, k;
00252     sortable_bbox *s = calloc(total, sizeof(sortable_bbox));
00253 
00254     for(i = 0; i < total; ++i){
00255         s[i].index = i;       
00256         s[i].class = 0;
00257         s[i].probs = probs;
00258     }
00259 
00260     for(k = 0; k < classes; ++k){
00261         for(i = 0; i < total; ++i){
00262             s[i].class = k;
00263         }
00264         qsort(s, total, sizeof(sortable_bbox), nms_comparator);
00265         for(i = 0; i < total; ++i){
00266             if(probs[s[i].index][k] == 0) continue;
00267             box a = boxes[s[i].index];
00268             for(j = i+1; j < total; ++j){
00269                 box b = boxes[s[j].index];
00270                 if (box_iou(a, b) > thresh){
00271                     probs[s[j].index][k] = 0;
00272                 }
00273             }
00274         }
00275     }
00276     free(s);
00277 }
00278 
00279 void do_nms(box *boxes, float **probs, int total, int classes, float thresh)
00280 {
00281     int i, j, k;
00282     for(i = 0; i < total; ++i){
00283         int any = 0;
00284         for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0);
00285         if(!any) {
00286             continue;
00287         }
00288         for(j = i+1; j < total; ++j){
00289             if (box_iou(boxes[i], boxes[j]) > thresh){
00290                 for(k = 0; k < classes; ++k){
00291                     if (probs[i][k] < probs[j][k]) probs[i][k] = 0;
00292                     else probs[j][k] = 0;
00293                 }
00294             }
00295         }
00296     }
00297 }
00298 
00299 box encode_box(box b, box anchor)
00300 {
00301     box encode;
00302     encode.x = (b.x - anchor.x) / anchor.w;
00303     encode.y = (b.y - anchor.y) / anchor.h;
00304     encode.w = log2(b.w / anchor.w);
00305     encode.h = log2(b.h / anchor.h);
00306     return encode;
00307 }
00308 
00309 box decode_box(box b, box anchor)
00310 {
00311     box decode;
00312     decode.x = b.x * anchor.w + anchor.x;
00313     decode.y = b.y * anchor.h + anchor.y;
00314     decode.w = pow(2., b.w) * anchor.w;
00315     decode.h = pow(2., b.h) * anchor.h;
00316     return decode;
00317 }


rail_object_detector
Author(s):
autogenerated on Sat Jun 8 2019 20:26:29