darknet  v3
box.c
Go to the documentation of this file.
1 #include "box.h"
2 #include <stdio.h>
3 #include <math.h>
4 #include <stdlib.h>
5 
6 int nms_comparator(const void *pa, const void *pb)
7 {
8  detection a = *(detection *)pa;
9  detection b = *(detection *)pb;
10  float diff = 0;
11  if(b.sort_class >= 0){
12  diff = a.prob[b.sort_class] - b.prob[b.sort_class];
13  } else {
14  diff = a.objectness - b.objectness;
15  }
16  if(diff < 0) return 1;
17  else if(diff > 0) return -1;
18  return 0;
19 }
20 
21 void do_nms_obj(detection *dets, int total, int classes, float thresh)
22 {
23  int i, j, k;
24  k = total-1;
25  for(i = 0; i <= k; ++i){
26  if(dets[i].objectness == 0){
27  detection swap = dets[i];
28  dets[i] = dets[k];
29  dets[k] = swap;
30  --k;
31  --i;
32  }
33  }
34  total = k+1;
35 
36  for(i = 0; i < total; ++i){
37  dets[i].sort_class = -1;
38  }
39 
40  qsort(dets, total, sizeof(detection), nms_comparator);
41  for(i = 0; i < total; ++i){
42  if(dets[i].objectness == 0) continue;
43  box a = dets[i].bbox;
44  for(j = i+1; j < total; ++j){
45  if(dets[j].objectness == 0) continue;
46  box b = dets[j].bbox;
47  if (box_iou(a, b) > thresh){
48  dets[j].objectness = 0;
49  for(k = 0; k < classes; ++k){
50  dets[j].prob[k] = 0;
51  }
52  }
53  }
54  }
55 }
56 
57 
58 void do_nms_sort(detection *dets, int total, int classes, float thresh)
59 {
60  int i, j, k;
61  k = total-1;
62  for(i = 0; i <= k; ++i){
63  if(dets[i].objectness == 0){
64  detection swap = dets[i];
65  dets[i] = dets[k];
66  dets[k] = swap;
67  --k;
68  --i;
69  }
70  }
71  total = k+1;
72 
73  for(k = 0; k < classes; ++k){
74  for(i = 0; i < total; ++i){
75  dets[i].sort_class = k;
76  }
77  qsort(dets, total, sizeof(detection), nms_comparator);
78  for(i = 0; i < total; ++i){
79  if(dets[i].prob[k] == 0) continue;
80  box a = dets[i].bbox;
81  for(j = i+1; j < total; ++j){
82  box b = dets[j].bbox;
83  if (box_iou(a, b) > thresh){
84  dets[j].prob[k] = 0;
85  }
86  }
87  }
88  }
89 }
90 
91 box float_to_box(float *f, int stride)
92 {
93  box b = {0};
94  b.x = f[0];
95  b.y = f[1*stride];
96  b.w = f[2*stride];
97  b.h = f[3*stride];
98  return b;
99 }
100 
102 {
103  dbox d;
104  d.dx = 0;
105  d.dw = 0;
106  float l1 = a.x - a.w/2;
107  float l2 = b.x - b.w/2;
108  if (l1 > l2){
109  d.dx -= 1;
110  d.dw += .5;
111  }
112  float r1 = a.x + a.w/2;
113  float r2 = b.x + b.w/2;
114  if(r1 < r2){
115  d.dx += 1;
116  d.dw += .5;
117  }
118  if (l1 > r2) {
119  d.dx = -1;
120  d.dw = 0;
121  }
122  if (r1 < l2){
123  d.dx = 1;
124  d.dw = 0;
125  }
126 
127  d.dy = 0;
128  d.dh = 0;
129  float t1 = a.y - a.h/2;
130  float t2 = b.y - b.h/2;
131  if (t1 > t2){
132  d.dy -= 1;
133  d.dh += .5;
134  }
135  float b1 = a.y + a.h/2;
136  float b2 = b.y + b.h/2;
137  if(b1 < b2){
138  d.dy += 1;
139  d.dh += .5;
140  }
141  if (t1 > b2) {
142  d.dy = -1;
143  d.dh = 0;
144  }
145  if (b1 < t2){
146  d.dy = 1;
147  d.dh = 0;
148  }
149  return d;
150 }
151 
152 float overlap(float x1, float w1, float x2, float w2)
153 {
154  float l1 = x1 - w1/2;
155  float l2 = x2 - w2/2;
156  float left = l1 > l2 ? l1 : l2;
157  float r1 = x1 + w1/2;
158  float r2 = x2 + w2/2;
159  float right = r1 < r2 ? r1 : r2;
160  return right - left;
161 }
162 
164 {
165  float w = overlap(a.x, a.w, b.x, b.w);
166  float h = overlap(a.y, a.h, b.y, b.h);
167  if(w < 0 || h < 0) return 0;
168  float area = w*h;
169  return area;
170 }
171 
172 float box_union(box a, box b)
173 {
174  float i = box_intersection(a, b);
175  float u = a.w*a.h + b.w*b.h - i;
176  return u;
177 }
178 
179 float box_iou(box a, box b)
180 {
181  return box_intersection(a, b)/box_union(a, b);
182 }
183 
184 float box_rmse(box a, box b)
185 {
186  return sqrt(pow(a.x-b.x, 2) +
187  pow(a.y-b.y, 2) +
188  pow(a.w-b.w, 2) +
189  pow(a.h-b.h, 2));
190 }
191 
193 {
194  float w = overlap(a.x, a.w, b.x, b.w);
195  float h = overlap(a.y, a.h, b.y, b.h);
196  dbox dover = derivative(a, b);
197  dbox di;
198 
199  di.dw = dover.dw*h;
200  di.dx = dover.dx*h;
201  di.dh = dover.dh*w;
202  di.dy = dover.dy*w;
203 
204  return di;
205 }
206 
208 {
209  dbox du;
210 
211  dbox di = dintersect(a, b);
212  du.dw = a.h - di.dw;
213  du.dh = a.w - di.dh;
214  du.dx = -di.dx;
215  du.dy = -di.dy;
216 
217  return du;
218 }
219 
220 
222 {
223  box a = {0, 0, 1, 1};
224  box dxa= {0+.0001, 0, 1, 1};
225  box dya= {0, 0+.0001, 1, 1};
226  box dwa= {0, 0, 1+.0001, 1};
227  box dha= {0, 0, 1, 1+.0001};
228 
229  box b = {.5, .5, .2, .2};
230  dbox di = dunion(a,b);
231  printf("Union: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
232  float inter = box_union(a, b);
233  float xinter = box_union(dxa, b);
234  float yinter = box_union(dya, b);
235  float winter = box_union(dwa, b);
236  float hinter = box_union(dha, b);
237  xinter = (xinter - inter)/(.0001);
238  yinter = (yinter - inter)/(.0001);
239  winter = (winter - inter)/(.0001);
240  hinter = (hinter - inter)/(.0001);
241  printf("Union Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
242 }
244 {
245  box a = {0, 0, 1, 1};
246  box dxa= {0+.0001, 0, 1, 1};
247  box dya= {0, 0+.0001, 1, 1};
248  box dwa= {0, 0, 1+.0001, 1};
249  box dha= {0, 0, 1, 1+.0001};
250 
251  box b = {.5, .5, .2, .2};
252  dbox di = dintersect(a,b);
253  printf("Inter: %f %f %f %f\n", di.dx, di.dy, di.dw, di.dh);
254  float inter = box_intersection(a, b);
255  float xinter = box_intersection(dxa, b);
256  float yinter = box_intersection(dya, b);
257  float winter = box_intersection(dwa, b);
258  float hinter = box_intersection(dha, b);
259  xinter = (xinter - inter)/(.0001);
260  yinter = (yinter - inter)/(.0001);
261  winter = (winter - inter)/(.0001);
262  hinter = (hinter - inter)/(.0001);
263  printf("Inter Manual %f %f %f %f\n", xinter, yinter, winter, hinter);
264 }
265 
266 void test_box()
267 {
268  test_dintersect();
269  test_dunion();
270  box a = {0, 0, 1, 1};
271  box dxa= {0+.00001, 0, 1, 1};
272  box dya= {0, 0+.00001, 1, 1};
273  box dwa= {0, 0, 1+.00001, 1};
274  box dha= {0, 0, 1, 1+.00001};
275 
276  box b = {.5, 0, .2, .2};
277 
278  float iou = box_iou(a,b);
279  iou = (1-iou)*(1-iou);
280  printf("%f\n", iou);
281  dbox d = diou(a, b);
282  printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh);
283 
284  float xiou = box_iou(dxa, b);
285  float yiou = box_iou(dya, b);
286  float wiou = box_iou(dwa, b);
287  float hiou = box_iou(dha, b);
288  xiou = ((1-xiou)*(1-xiou) - iou)/(.00001);
289  yiou = ((1-yiou)*(1-yiou) - iou)/(.00001);
290  wiou = ((1-wiou)*(1-wiou) - iou)/(.00001);
291  hiou = ((1-hiou)*(1-hiou) - iou)/(.00001);
292  printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou);
293 }
294 
296 {
297  float u = box_union(a,b);
298  float i = box_intersection(a,b);
299  dbox di = dintersect(a,b);
300  dbox du = dunion(a,b);
301  dbox dd = {0,0,0,0};
302 
303  if(i <= 0 || 1) {
304  dd.dx = b.x - a.x;
305  dd.dy = b.y - a.y;
306  dd.dw = b.w - a.w;
307  dd.dh = b.h - a.h;
308  return dd;
309  }
310 
311  dd.dx = 2*pow((1-(i/u)),1)*(di.dx*u - du.dx*i)/(u*u);
312  dd.dy = 2*pow((1-(i/u)),1)*(di.dy*u - du.dy*i)/(u*u);
313  dd.dw = 2*pow((1-(i/u)),1)*(di.dw*u - du.dw*i)/(u*u);
314  dd.dh = 2*pow((1-(i/u)),1)*(di.dh*u - du.dh*i)/(u*u);
315  return dd;
316 }
317 
318 
319 void do_nms(box *boxes, float **probs, int total, int classes, float thresh)
320 {
321  int i, j, k;
322  for(i = 0; i < total; ++i){
323  int any = 0;
324  for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0);
325  if(!any) {
326  continue;
327  }
328  for(j = i+1; j < total; ++j){
329  if (box_iou(boxes[i], boxes[j]) > thresh){
330  for(k = 0; k < classes; ++k){
331  if (probs[i][k] < probs[j][k]) probs[i][k] = 0;
332  else probs[j][k] = 0;
333  }
334  }
335  }
336  }
337 }
338 
339 box encode_box(box b, box anchor)
340 {
341  box encode;
342  encode.x = (b.x - anchor.x) / anchor.w;
343  encode.y = (b.y - anchor.y) / anchor.h;
344  encode.w = log2(b.w / anchor.w);
345  encode.h = log2(b.h / anchor.h);
346  return encode;
347 }
348 
349 box decode_box(box b, box anchor)
350 {
351  box decode;
352  decode.x = b.x * anchor.w + anchor.x;
353  decode.y = b.y * anchor.h + anchor.y;
354  decode.w = pow(2., b.w) * anchor.w;
355  decode.h = pow(2., b.h) * anchor.h;
356  return decode;
357 }
void test_dunion()
Definition: box.c:221
Definition: box.h:5
box float_to_box(float *f, int stride)
Definition: box.c:91
float dy
Definition: box.h:6
float h
Definition: darknet.h:520
box encode_box(box b, box anchor)
Definition: box.c:339
float overlap(float x1, float w1, float x2, float w2)
Definition: box.c:152
dbox derivative(box a, box b)
Definition: box.c:101
void test_box()
Definition: box.c:266
void do_nms_obj(detection *dets, int total, int classes, float thresh)
Definition: box.c:21
float w
Definition: darknet.h:520
float box_rmse(box a, box b)
Definition: box.c:184
float x
Definition: darknet.h:520
int sort_class
Definition: darknet.h:529
float dx
Definition: box.h:6
int nms_comparator(const void *pa, const void *pb)
Definition: box.c:6
box decode_box(box b, box anchor)
Definition: box.c:349
float * prob
Definition: darknet.h:526
void do_nms(box *boxes, float **probs, int total, int classes, float thresh)
Definition: box.c:319
float objectness
Definition: darknet.h:528
box bbox
Definition: darknet.h:524
dbox dunion(box a, box b)
Definition: box.c:207
float box_iou(box a, box b)
Definition: box.c:179
float box_union(box a, box b)
Definition: box.c:172
void test_dintersect()
Definition: box.c:243
dbox diou(box a, box b)
Definition: box.c:295
dbox dintersect(box a, box b)
Definition: box.c:192
float box_intersection(box a, box b)
Definition: box.c:163
float dw
Definition: box.h:6
float y
Definition: darknet.h:520
float dh
Definition: box.h:6
void do_nms_sort(detection *dets, int total, int classes, float thresh)
Definition: box.c:58
list classes
Definition: voc_label.py:9
Definition: darknet.h:519