--- a +++ b/darkflow/cython_utils/nms.pyx @@ -0,0 +1,131 @@ +import numpy as np +cimport numpy as np +cimport cython +from libc.math cimport exp +from ..utils.box import BoundBox + + + +#OVERLAP +@cython.boundscheck(False) # turn off bounds-checking for entire function +@cython.wraparound(False) # turn off negative index wrapping for entire function +@cython.cdivision(True) +cdef float overlap_c(float x1, float w1 , float x2 , float w2): + cdef: + float l1,l2,left,right + l1 = x1 - w1 /2. + l2 = x2 - w2 /2. + left = max(l1,l2) + r1 = x1 + w1 /2. + r2 = x2 + w2 /2. + right = min(r1, r2) + return right - left; + +#BOX INTERSECTION +@cython.boundscheck(False) # turn off bounds-checking for entire function +@cython.wraparound(False) # turn off negative index wrapping for entire function +@cython.cdivision(True) +cdef float box_intersection_c(float ax, float ay, float aw, float ah, float bx, float by, float bw, float bh): + cdef: + float w,h,area + w = overlap_c(ax, aw, bx, bw) + h = overlap_c(ay, ah, by, bh) + if w < 0 or h < 0: return 0 + area = w * h + return area + +#BOX UNION +@cython.boundscheck(False) # turn off bounds-checking for entire function +@cython.wraparound(False) # turn off negative index wrapping for entire function +@cython.cdivision(True) +cdef float box_union_c(float ax, float ay, float aw, float ah, float bx, float by, float bw, float bh): + cdef: + float i,u + i = box_intersection_c(ax, ay, aw, ah, bx, by, bw, bh) + u = aw * ah + bw * bh -i + return u + + +#BOX IOU +@cython.boundscheck(False) # turn off bounds-checking for entire function +@cython.wraparound(False) # turn off negative index wrapping for entire function +@cython.cdivision(True) +cdef float box_iou_c(float ax, float ay, float aw, float ah, float bx, float by, float bw, float bh): + return box_intersection_c(ax, ay, aw, ah, bx, by, bw, bh) / box_union_c(ax, ay, aw, ah, bx, by, bw, bh); + + + + +#NMS +@cython.boundscheck(False) # turn off bounds-checking for entire function +@cython.wraparound(False) # turn off negative index wrapping for entire function +@cython.cdivision(True) +cdef NMS(float[:, ::1] final_probs , float[:, ::1] final_bbox): + cdef list boxes = list() + cdef set indices = set() + cdef: + np.intp_t pred_length,class_length,class_loop,index,index2 + + + pred_length = final_bbox.shape[0] + class_length = final_probs.shape[1] + for class_loop in range(class_length): + for index in range(pred_length): + if final_probs[index,class_loop] == 0: continue + for index2 in range(index+1,pred_length): + if final_probs[index2,class_loop] == 0: continue + if index==index2 : continue + if box_iou_c(final_bbox[index,0],final_bbox[index,1],final_bbox[index,2],final_bbox[index,3],final_bbox[index2,0],final_bbox[index2,1],final_bbox[index2,2],final_bbox[index2,3]) >= 0.4: + if final_probs[index2,class_loop] > final_probs[index, class_loop] : + final_probs[index, class_loop] =0 + break + final_probs[index2,class_loop]=0 + + if index not in indices: + bb=BoundBox(class_length) + bb.x = final_bbox[index, 0] + bb.y = final_bbox[index, 1] + bb.w = final_bbox[index, 2] + bb.h = final_bbox[index, 3] + bb.c = final_bbox[index, 4] + bb.probs = np.asarray(final_probs[index,:]) + boxes.append(bb) + indices.add(index) + return boxes + +# cdef NMS(float[:, ::1] final_probs , float[:, ::1] final_bbox): +# cdef list boxes = list() +# cdef: +# np.intp_t pred_length,class_length,class_loop,index,index2, i, j + + +# pred_length = final_bbox.shape[0] +# class_length = final_probs.shape[1] + +# for class_loop in range(class_length): +# order = np.argsort(final_probs[:,class_loop])[::-1] +# # First box +# for i in range(pred_length): +# index = order[i] +# if final_probs[index, class_loop] == 0.: +# continue +# # Second box +# for j in range(i+1, pred_length): +# index2 = order[j] +# if box_iou_c( +# final_bbox[index,0],final_bbox[index,1], +# final_bbox[index,2],final_bbox[index,3], +# final_bbox[index2,0],final_bbox[index2,1], +# final_bbox[index2,2],final_bbox[index2,3]) >= 0.4: +# final_probs[index2, class_loop] = 0. + +# bb = BoundBox(class_length) +# bb.x = final_bbox[index, 0] +# bb.y = final_bbox[index, 1] +# bb.w = final_bbox[index, 2] +# bb.h = final_bbox[index, 3] +# bb.c = final_bbox[index, 4] +# bb.probs = np.asarray(final_probs[index,:]) +# boxes.append(bb) + +# return boxes