From 2c63bf05bef01f8b17299d130a84889b2cf6e91b Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Wed, 6 Feb 2019 22:24:01 +0000 Subject: [PATCH] multipl yolo morge --- include/Layer.h | 9 +- src/Yolo.cpp | 117 ++++++++++++++++++++---- tests/yolo3_berkeley/yolo3_berkeley.cpp | 18 ++-- 3 files changed, 115 insertions(+), 29 deletions(-) diff --git a/include/Layer.h b/include/Layer.h index f2b6fa0..860d73a 100644 --- a/include/Layer.h +++ b/include/Layer.h @@ -361,12 +361,13 @@ public: dnnType *bias_h, *bias_d; //anchors virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); - int computeDetections(int w, int h, int netw, int neth, float thresh); + int computeDetections(Yolo::detection *dets, int &ndets, int w, int h, int netw, int neth, float thresh); - const int MAX_DETECTIONS = 256; dnnType *predictions; - Yolo::detection *dets; - int detected; + + static const int MAX_DETECTIONS = 256; + static Yolo::detection *allocateDetections(int nboxes, int classes); + static void mergeDetections(Yolo::detection *dets, int ndets, int classes); }; /** diff --git a/src/Yolo.cpp b/src/Yolo.cpp index d43fe75..09e81ce 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -11,16 +11,6 @@ namespace tk { namespace dnn { -Yolo::detection *make_network_boxes(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; -} - Yolo::Yolo(Network *net, int classes, int num, const char* fname_weights) : Layer(net) { @@ -49,9 +39,6 @@ Yolo::Yolo(Network *net, int classes, int num, const char* fname_weights) : checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); predictions = nullptr; - - dets = make_network_boxes(MAX_DETECTIONS, classes); - detected = 0; } Yolo::~Yolo() { @@ -122,7 +109,7 @@ dnnType* Yolo::infer(dataDim_t &dim, dnnType* srcData) { return dstData; } -int Yolo::computeDetections(int w, int h, int netw, int neth, float thresh) { +int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int w, int h, int netw, int neth, float thresh) { if(predictions == nullptr) predictions = new dnnType[output_dim.tot()]; @@ -138,7 +125,7 @@ int Yolo::computeDetections(int w, int h, int netw, int neth, float thresh) { //avg_flipped_yolo(l); } int i,j,n; - int count = 0; + int count = ndets; for (i = 0; i < lw*lh; ++i){ int row = i / lw; int col = i % lw; @@ -162,11 +149,105 @@ int Yolo::computeDetections(int w, int h, int netw, int neth, float thresh) { FatalError("reach max boxes"); } } - correct_yolo_boxes(dets, count, w, h, netw, neth, relative); - std::cout<<"DETECTED: "< 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; + } + } + } + } + +} + }} diff --git a/tests/yolo3_berkeley/yolo3_berkeley.cpp b/tests/yolo3_berkeley/yolo3_berkeley.cpp index 7d8496b..b5fe737 100644 --- a/tests/yolo3_berkeley/yolo3_berkeley.cpp +++ b/tests/yolo3_berkeley/yolo3_berkeley.cpp @@ -323,20 +323,24 @@ int main() { printCenteredTitle(" compute detections ", '=', 30); TIMER_START - yolo0.computeDetections(dim.w, dim.h, net.input_dim.w, net.input_dim.h, 0.5); - yolo1.computeDetections(dim.w, dim.h, net.input_dim.w, net.input_dim.h, 0.5); - yolo2.computeDetections(dim.w, dim.h, net.input_dim.w, net.input_dim.h, 0.5); + int ndets = 0; + int classes = yolo0.classes; + tk::dnn::Yolo::detection *dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); + yolo0.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, net.input_dim.w, net.input_dim.h, 0.5); + yolo1.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, net.input_dim.w, net.input_dim.h, 0.5); + yolo2.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, net.input_dim.w, net.input_dim.h, 0.5); + tk::dnn::Yolo::mergeDetections(dets, ndets, classes); - for(int j=0; j 0) cl = c; }