#include #ifdef OPENCV #include #include #include #endif #include "Layer.h" #include "kernels.h" namespace tk { namespace dnn { Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks) : Layer(net) { this->classes = classes; this->num = num; this->n_masks = n_masks; // load anchors if(fname_weights != "") { int seek = 0; readBinaryFile(fname_weights, n_masks, &mask_h, &mask_d, seek); seek += n_masks; readBinaryFile(fname_weights, n_masks*num*2, &bias_h, &bias_d, seek); //for(int i=0; i thresh) ? prob : 0; } ++count; if(count >= MAX_DETECTIONS) FatalError("reach max boxes"); } } correct_yolo_boxes(dets + ndets, count, netw, neth, netw, neth, 0); ndets = count; return count; } ////////////////////////////////////////////////////////////////// float yolo_overlap(float x1, float w1, float x2, float w2) { float l1 = x1 - w1/2; float l2 = x2 - w2/2; float left = l1 > l2 ? l1 : l2; float r1 = x1 + w1/2; float r2 = x2 + w2/2; float right = r1 < r2 ? r1 : r2; return right - left; } float yolo_box_intersection(Yolo::box a, Yolo::box b) { float w = yolo_overlap(a.x, a.w, b.x, b.w); float h = yolo_overlap(a.y, a.h, b.y, b.h); if(w < 0 || h < 0) return 0; float area = w*h; return area; } float yolo_box_union(Yolo::box a, Yolo::box b) { float i = yolo_box_intersection(a, b); float u = a.w*a.h + b.w*b.h - i; return u; } float yolo_box_iou(Yolo::box a, Yolo::box b) { return yolo_box_intersection(a, b)/yolo_box_union(a, b); } int yolo_nms_comparator(const void *pa, const void *pb) { Yolo::detection a = *(Yolo::detection *)pa; Yolo::detection b = *(Yolo::detection *)pb; float diff = 0; if(b.sort_class >= 0){ diff = a.prob[b.sort_class] - b.prob[b.sort_class]; } else { diff = a.objectness - b.objectness; } if(diff < 0) return 1; else if(diff > 0) return -1; return 0; } //////////////////////////////////////////////////////////////////7 Yolo::detection *Yolo::allocateDetections(int nboxes, int classes) { int i; Yolo::detection *dets = (Yolo::detection*) calloc(nboxes, sizeof(Yolo::detection)); for(i = 0; i < nboxes; ++i){ dets[i].prob = (float*) calloc(classes, sizeof(float)); } return dets; } void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) { double nms_thresh = 0.45; int total = ndets; int i, j, k; k = total-1; for(i = 0; i <= k; ++i){ if(dets[i].objectness == 0){ detection swap = dets[i]; dets[i] = dets[k]; dets[k] = swap; --k; --i; } } total = k+1; for(k = 0; k < classes; ++k){ for(i = 0; i < total; ++i){ dets[i].sort_class = k; } qsort(dets, total, sizeof(detection), yolo_nms_comparator); for(i = 0; i < total; ++i){ if(dets[i].prob[k] == 0) continue; box a = dets[i].bbox; for(j = i+1; j < total; ++j){ box b = dets[j].bbox; if (yolo_box_iou(a, b) > nms_thresh){ dets[j].prob[k] = 0; } } } } } }}