【應用】YoloV3檢測推理

首先分享兩個可視化的工具。netscope,打開WEB,將文件拖動到左端空白。

http://ethereon.github.io/netscope/#/editor  

Netron支持主流各種框架的模型結構可視化工作,我給出gayhub鏈接:
https://github.com/lutzroeder/Netron

YoLov3在性能上做過優化,用來做人臉和其它識別非常地棒。YoloV3,Caffe框架都支持訓練。在部署時要寫推理部分。檢測部分的代碼網上資料較少,這裏給出一個框架。目標將YoloV3移植到嵌入式,C++平臺。下面直接給出檢測部分。

// specific language governing permissions and limitations under the License.

#include <opencv2/opencv.hpp>

#include "detection.h"

#include <fstream>

#include <iostream>

#include <algorithm>

#include <math.h>

#include <string>

#include "cpu.h"

namespace mace {

namespace yolov3{

std::string coco_classes[] = {"person","bicycle","car","motorcycle","airplane","bus","train","truck","boat","traffic light","fire hydrant","stop sign","parking meter","bench","bird","cat","dog","horse","sheep","cow","elephant","bear","zebra","giraffe","backpack","umbrella","handbag","tie","suitcase","frisbee","skis","snowboard","sports ball","kite","baseball bat","baseball glove","skateboard","surfboard","tennis racket","bottle","wine glass","cup","fork","knife","spoon","bowl","banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza","donut","cake","chair","couch","potted plant","bed","dining table","toilet","tv","laptop","mouse","remote","keyboard","cell phone","microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush"};

int coco_ids[] = {1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90};

Option::Option()

{

lightmode = true;

//num_threads = get_cpu_count();

num_threads=4;

blob_allocator = 0;

workspace_allocator = 0;

}

static Option g_default_option;

const Option& get_default_option()

{

return g_default_option;

}

int set_default_option(const Option& opt)

{

if (opt.num_threads <= 0)

{

fprintf(stderr, "invalid option num_threads %d\n", opt.num_threads);

return -1;

}

g_default_option = opt;

return 0;

}

Yolov3DetectionOutput::Yolov3DetectionOutput()

{

}

Yolov3DetectionOutput::~Yolov3DetectionOutput()

{

//delete softmax;

}

int label;

static inline float intersection_area(const BBoxRect& a, const BBoxRect& b)

{

if (a.xmin > b.xmax || a.xmax < b.xmin || a.ymin > b.ymax || a.ymax < b.ymin)

{

// no intersection

return 0.f;

}

float inter_width = std::min(a.xmax, b.xmax) - std::max(a.xmin, b.xmin);

float inter_height = std::min(a.ymax, b.ymax) - std::max(a.ymin, b.ymin);

return inter_width * inter_height;

}

template <typename T>

static void qsort_descent_inplace(std::vector<T> &datas, std::vector<float>& scores, int left, int right)

{

int i = left;

int j = right;

    int middle =(left + right) / 2;

float f = scores[middle];

while (i < j)

{

        while(scores[i]>f){

i++;

    }

        while(scores[j]<f){

            if(left==middle)break;

            j--;

        }

if (i <j)

{

// swap

std::swap(datas[i], datas[j]);

std::swap(scores[i], scores[j]);

            i++;

    j--;

}

        if(i==j)

        {

            i++;

            j--;

        }

}

if (left < j) qsort_descent_inplace(datas, scores, left, j);

if (i < right) qsort_descent_inplace(datas, scores, i, right);

}

template <typename T>

static void qsort_descent(std::vector<T>& datas, std::vector<float>& scores)

{

if (datas.empty() || scores.empty())

return;

    int left=0;

    int right=datas.size()-1;

qsort_descent_inplace(datas, scores, left,right);

}

static void nms_sorted_bboxes(const std::vector<BBoxRect>& bboxes, std::vector<BBoxRect>& picked_boxes,std::vector<size_t>& picked, float nms_threshold)

{

picked.clear();

const int n = bboxes.size();

std::vector<float> areas(n);

for (int i = 0; i < n; i++)

{

const BBoxRect& r = bboxes[i];

float width = r.xmax - r.xmin;

float height = r.ymax - r.ymin;

areas[i] = width * height;

}

    picked.push_back(0);

    picked_boxes.push_back(bboxes[0]);

for (int i = 1; i < n; i++)

{

const BBoxRect& a = bboxes[i];

int keep = 1;

for (int j = 0; j < (int)picked.size(); j++)

{

const BBoxRect& b = bboxes[picked[j]];

// intersection over union

            float ratio=areas[i]/areas[picked[j]];

            ratio=(ratio>1)?ratio:(1.0/(float)ratio);

            //ratio=sqrt(ratio);

            float inter_area = intersection_area(a, b)*ratio;

float union_area = areas[i] + areas[picked[j]] - inter_area;

// float IoU = inter_area / union_area

if (inter_area / union_area > nms_threshold)

{

                    keep = 0;

                    break;

                }

}

if (keep)

        {

picked.push_back(i);

            picked_boxes.push_back(a);

        }

}

}

static inline float sigmoid(float x)

{

return 1.f / (1.f + exp(-x));

}

int Yolov3DetectionOutput::forward_nhwc(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs,std::vector<BBoxRect>&boxes) const

{

    size_t num_class = 80;

    size_t NUMS_ANCHOR = 3;

    float confidence_threshold=0.6;

    float nms_threshold = 0.45f;

    size_t scale[3]={32,16,8};

    size_t m_[9]={6,7,8,4,5,6,1,2,3};

    size_t anchors[18] = {10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326};

    size_t num_mask=3* NUMS_ANCHOR;

    size_t len_biases=3* NUMS_ANCHOR*2;

    Mat anchors_scale(3,scale);

    Mat mask(num_mask,m_);

    Mat biases(len_biases,anchors);

    std::vector<BBoxRect> all_bbox_rects;

    std::vector<float> all_bbox_scores;

    for (size_t b = 0; b < bottom_blobs.size(); b++)

    {

        const Mat& bottom_top_blobs = bottom_blobs[b];

        size_t w = bottom_top_blobs.w;

        size_t h = bottom_top_blobs.h;

        size_t channels = bottom_top_blobs.c;

        const size_t channels_per_box = channels / NUMS_ANCHOR;

        size_t mask_offset = b * NUMS_ANCHOR;

        size_t net_w = (size_t)((reinterpret_cast<size_t *>(anchors_scale.data))[b] * w);      

        size_t net_h = (size_t)((reinterpret_cast<size_t *>(anchors_scale.data))[b] * h);

        std::cout<<"w,h,c"<<w<<":"<<h<<":"<<channels<<std::endl;

        std::cout<<"blobs w,h,channels"<<bottom_top_blobs.w<<":"<<bottom_top_blobs.h<<":"<<bottom_top_blobs.c<<std::endl;

        if((net_w!=net_h) || (net_w!=416)){

            std::cerr<<"check Data Input"<<std::endl;

            //return -1;

        }

        float *p;

#pragma omp parallel for num_threads(opt.num_threads)

        for (size_t k = 0; k < h*w; k++)

        {

            size_t i=k/w;

            size_t j=k%w;

            for (size_t pp = 0; pp < NUMS_ANCHOR; pp++)

            {

                size_t biases_index = mask[pp+NUMS_ANCHOR*b];

                const float bias_w = (reinterpret_cast<size_t *>(biases.data))[biases_index * 2];

                const float bias_h = (reinterpret_cast<size_t *>(biases.data))[biases_index * 2+1] ;

                long bias=k*channels+pp*channels_per_box;

                 p= reinterpret_cast<float*>(bottom_top_blobs.data)+bias;    

                    float bbox_w = sigmoid(*(p+2))* bias_w ;

                    float bbox_h = sigmoid(*(p+3)) * bias_h ;

                    float bbox_cx = (j + sigmoid(*(p)))*416/w;

                    float bbox_cy = (i + sigmoid(*(p+1)))*416/h;

                    //float bbox_w = pow(2,*(p+2)) * bias_w;

                    //float bbox_h = pow(2,*(p+3)) * bias_h;

                    float bbox_xmin = bbox_cx - bbox_w * 0.5f;

                    float bbox_ymin = bbox_cy - bbox_h * 0.5f;

                    float bbox_xmax = bbox_cx + bbox_w * 0.5f;

                    float bbox_ymax = bbox_cy + bbox_h * 0.5f;

                    bbox_xmin=bbox_xmin>0?bbox_xmin:0;

                    bbox_ymin=bbox_ymin>0?bbox_ymin:0;

                    bbox_xmax=bbox_xmax>416?416:bbox_xmax;

                    bbox_ymax=bbox_ymax>416?416:bbox_ymax;

                    float box_score = sigmoid(*(p+4));

                    size_t class_index = 0;

                    float class_score = 0.0f;

                    for (size_t q = 0; q < num_class; q++)

                    {

                        float score = sigmoid(*(p+5+q));

                        if (score > class_score)

                        {

                            class_score=score;

                            class_index = q;

                            //printf( "%d %f %f\n", class_index, box_score, class_score);

                        }

                    }

                    float confidence = box_score * class_score;

                    if (confidence >= confidence_threshold)

                    {

                        BBoxRect c = { bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax, class_index };

                        float area=(bbox_xmax-bbox_xmin)*(bbox_ymax-bbox_ymin);

                        if(area > 60.0){

                            all_bbox_rects.push_back(c);

                            all_bbox_scores.push_back(confidence);

                        }

                    }           

            }

        }

    }

    size_t NUMS_ANCHORes=all_bbox_rects.size();

    std::cout<<"alll: "<<NUMS_ANCHORes<<std::endl;

    if(NUMS_ANCHORes==0)return 0;

    std::vector<size_t> labelX;

    size_t lnum=0;

    size_t N=NUMS_ANCHORes;

    if(N>0){labelX.push_back(all_bbox_rects[N-1].label);lnum++;}

    while(--N)

    {   size_t la=all_bbox_rects[N-1].label;

        bool fl=true;

        for(size_t j=0;j<lnum;j++)

        {

            if(la == labelX[j])

            {

                fl=false;

                break;

            }

        }

        if(fl){

            labelX.push_back(la);

            lnum++;

        }

    }

    std::cout<<"labels:"<<lnum<<std::endl;

    std::vector<std::vector<BBoxRect> > bboxes(lnum);

    std::vector<std::vector<float> >scores(lnum);   

    //label.push_back(all_bbox_rects[0].label);

    for (size_t i = 0; i < NUMS_ANCHORes; i++)

    {

        size_t j=0;

        for(;(size_t)j<lnum;j++)

        {

            if(all_bbox_rects[i].label == labelX[j])

            {

                std::vector<BBoxRect>& rect_=bboxes[j];

                std::vector<float>& temp_=scores[j];

                //printf("%d::%f\n",j,all_bbox_scores[i]);

                rect_.push_back(all_bbox_rects[i]);

                temp_.push_back(all_bbox_scores[i]);

                break;

            }

        }

    }

    std::vector<BBoxRect>& picked=boxes;

    std::vector<float> score;   

    //size_t type=0;

    for(size_t i=0;i<(size_t)bboxes.size();i++)

    {

        std::vector<float>& s=scores[i];

        if(s.empty()) continue;

        //type++;

        // global sort inplace

        std::vector<BBoxRect>& b=bboxes[i];

        qsort_descent(b, s);

        // apply nms

        std::vector<BBoxRect> pick;

        std::vector<size_t> p;

        nms_sorted_bboxes(bboxes[i], pick,p, nms_threshold);

        picked.insert(picked.begin(),pick.begin(),pick.end());      

        for (size_t j = 0; j < (size_t)p.size(); j++)

        {   

            score.push_back(s[p[j]]);

        }   

    }

    //printf("%d\n",type);

size_t num_detected = picked.size();

    for (size_t i = 0; i < num_detected; i++)

{

const BBoxRect& r = picked[i];

        float score_ = score[i];

        //std::cout<<"class: "<< coco_classes[r.label] <<" "<< r.label <<"; score "<<score_ <<"; location (" <<r.xmin<<" "<< r.ymin<<" "<<r.xmax<<" "<<r.ymax<< " ) " <<std::endl;

    }

    std::cout<<"detected:<< num_detected<<----------------------- "<<std::endl;

    std::cout<<"-------------------------------- "<<std::endl;

    //global nms

    //std::cout<<"glabal nms: "<<std::endl;

    //std::cout<<"picked: "<<picked.size()<<std::endl;

    //#qsort_descent(all_bbox_rects, all_bbox_scores);

    //std::vector<BBoxRect> picked_gnms;

    //std::vector<size_t> p_gnms;

    //nms_sorted_bboxes(all_bbox_rects, picked_gnms,p_gnms, nms_threshold);

    //num_detected = picked_gnms.size();

    //for (size_t i = 0; i < num_detected; i++)

//{

// const BBoxRect& r = picked_gnms[i];

    //  float score_ = score[i];

    //  std::cout<<"class: "<< coco_classes[r.label] <<" "<< r.label <<"; score "<<score_ <<"; location (" <<r.xmin<<" "<< r.xmax<<" "<<r.ymin<<" "<<r.ymax<< " ) " <<std::endl;

    //}

    //std::cout<<"detected: "<<num_detected<<std::endl;

    Mat& top_blob =top_blobs[0];

return 1;

}

int Yolov3DetectionOutput::forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs,std::vector<BBoxRect>&boxes) const

{

    int num_class = 80;

    int NUMS_ANCHOR = 3;

    float confidence_threshold=0.6;

    float nms_threshold = 0.6f;

    int scale[3]={32,16,8};

    int m_[9]={8,8,8,8,8,8,8,8,8};

    int anchors[18] = {10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326};

    int num_mask=3* NUMS_ANCHOR;

    int len_biases=3* NUMS_ANCHOR*2;

    Mat anchors_scale(3,scale);

    Mat mask(num_mask,m_);

    Mat biases(len_biases,anchors);

    std::vector<BBoxRect> all_bbox_rects;

    std::vector<float> all_bbox_scores;

    for (size_t b = 0; b < bottom_blobs.size(); b++)

    {

        const Mat& bottom_top_blobs = bottom_blobs[b];

        int w = bottom_top_blobs.w;

        int h = bottom_top_blobs.h;

        int channels = bottom_top_blobs.c;

        //printf("%d %d %d\n", w, h, channels);

        const int channels_per_box = channels / NUMS_ANCHOR;

        // anchor coord + box score + num_class

        if (channels_per_box != 4 + 1 + num_class)

            return -1;

        int mask_offset = b * NUMS_ANCHOR;

        //int net_w= anchors_scale[b];

        int net_w = (int)((reinterpret_cast<int *>(anchors_scale.data))[b] * w);       

        int net_h = (int)((reinterpret_cast<int *>(anchors_scale.data))[b] * h);

        if((net_w!=net_h) || (net_w!=416)){

            std::cerr<<"check Data Input"<<std::endl;

            return -1;

        }

        //printf("%d %d\n", net_w, net_h);

        //printf("%d %d %d\n", w, h, channels);

#pragma omp parallel for num_threads(opt.num_threads)

        for (int pp = 0; pp < NUMS_ANCHOR; pp++)

        {

            int p = pp * channels_per_box;

            int biases_index = (reinterpret_cast<int *>(mask.data))[pp + mask_offset];

            //printf("%d\n", biases_index);

            const float bias_w = (reinterpret_cast<int *>(biases.data))[biases_index * 2];

            const float bias_h = (reinterpret_cast<int *>(biases.data))[biases_index * 2+1] ;

            //printf("%f %f\n", bias_w, bias_h);

            const float* xptr = bottom_top_blobs.channel(p);

            const float* yptr = bottom_top_blobs.channel(p + 1);

            const float* wptr = bottom_top_blobs.channel(p + 2);

            const float* hptr = bottom_top_blobs.channel(p + 3);

            const float* box_score_ptr = bottom_top_blobs.channel(p + 4);

            // softmax class scores

            Mat scores = bottom_top_blobs.channel_range(p + 5, num_class);

            //softmax->forward_inplace(scores, opt);

            for (int k = 0; k < h*w; k++)

            {

                    int i=k/w;

                    int j=k%w;

                    float bbox_w = exp(wptr[0]) * bias_w ;

                    float bbox_h = exp(hptr[0]) * bias_h ;

                    float bbox_cx = (j + sigmoid(xptr[0]))*416/w;

                    //float bbox_cx = (j + sigmoid(xptr[0]))*416/w;

                    float bbox_cy = (i + sigmoid(yptr[0]))*416/h;

                    //float bbox_w = pow(2,wptr[0]) * bias_w / 416;

                    //float bbox_h = pow(2,hptr[0]) * bias_h / 416;

                    float bbox_xmin = bbox_cx - bbox_w * 0.5f;

                    float bbox_ymin = bbox_cy - bbox_h * 0.5f;

                    float bbox_xmax = bbox_cx + bbox_w * 0.5f;

                    float bbox_ymax = bbox_cy + bbox_h * 0.5f;

                    bbox_xmin=bbox_xmin>0?bbox_xmin:0;

                    bbox_ymin=bbox_ymin>0?bbox_ymin:0;

                    bbox_xmax=bbox_xmax>416?416:bbox_xmax;

                    bbox_ymax=bbox_ymax>416?416:bbox_ymax;

                    // box score

                    float box_score = sigmoid(box_score_ptr[0]);

                    // find class index with max class score

                    int class_index = 0;

                    float class_score = 0.0f;

                    for (int q = 0; q < num_class; q++)

                    {

                        float score = sigmoid(scores.channel(q).row(i)[j]);

                        if (score > class_score)

                        {

                            class_index = q;

                            class_score = score;

                            //printf( "%d %f %f\n", class_index, box_score, class_score);

                        }

                    }

                    float confidence = box_score * class_score;

                    if (confidence >= confidence_threshold)

                    {

                        BBoxRect c = { bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax, class_index };

                        float area=(bbox_xmax-bbox_xmin)*(bbox_ymax-bbox_ymin);

                        if(area > 200.0){

                            all_bbox_rects.push_back(c);

                            all_bbox_scores.push_back(confidence);

                        }

                    }

                    xptr++;

                    yptr++;

                    wptr++;

                    hptr++;

                    box_score_ptr++;                

            }

        }

   } 

    std::cout<<"alll: "<<all_bbox_rects.size()<<std::endl;

    std::vector<std::vector<BBoxRect> > bboxes(80);

    std::vector<std::vector<float> >scores(80);

    int NUMS_ANCHORes=all_bbox_rects.size();

    std::vector<int> label(80);

    //label.insert(label.begin,coco_classes,coco_classes+80);

    for (int i = 0; i < 80; ++i)

    {

        label[i] = i;

    }

    //std::vector<BBoxRect> rect;

    //std::vector<float> temp;

    //label.push_back(all_bbox_rects[0].label);

    //rect.push_back(all_bbox_rects[0]);

    //temp.push_back(all_bbox_scores[0]);

    //bboxes.push_back(rect);

    //scores.push_back(temp);

    for (int i = 0; i < NUMS_ANCHORes; i++)

    {

        int j=0;

        for(;j<label.size();j++)

        {

            if(all_bbox_rects[i].label == label[j])

            {

                std::vector<BBoxRect>& rect_=bboxes[j];

                std::vector<float>& temp_=scores[j];

                //printf("%d::%f\n",j,all_bbox_scores[i]);

                rect_.push_back(all_bbox_rects[i]);

                temp_.push_back(all_bbox_scores[i]);

                break;

            }

        }/*

        if(j==(int)label.size())

        {

            //rect.pop_back();

            //temp.pop_back();

            //printf("%d::%d::%d\n",label.size(),all_bbox_rects[i].label,i);

            //int l=all_bbox_rects[i].label;

            label.push_back(all_bbox_rects[i].labels);

            //rect.push_back(all_bbox_rects[i].label);

            //temp.push_back(all_bbox_scores[i]);

            //bboxes.push_back(rect);

            //scores.push_back(temp);

        }*/

    }

    std::vector<BBoxRect>& picked=boxes;

    std::vector<float> score;   

    //int type=0;

    for(int i=0;i<(int)bboxes.size();i++)

    {

        std::vector<float>& s=scores[i];

        if(s.empty()) continue;

        //type++;

        // global sort inplace

        std::vector<BBoxRect>& b=bboxes[i];

        qsort_descent(b, s);

        // apply nms

        std::vector<BBoxRect> pick;

        std::vector<size_t> p;

        nms_sorted_bboxes(bboxes[i], pick,p, nms_threshold);

        picked.insert(picked.begin(),pick.begin(),pick.end());

        

        for (int j = 0; j < (int)p.size(); j++)

        {   

            score.push_back(s[p[j]]);

        }

        

    }

    //printf("%d\n",type);

    std::cout<<"picked: "<<picked.size()<<std::endl;

int num_detected = picked.size();

    for (int i = 0; i < num_detected; i++)

{

const BBoxRect& r = picked[i];

        float score_ = score[i];

        std::cout<<"class: "<< coco_classes[r.label+1] <<" "<< r.label <<"; score "<<score_ <<"; location (" <<r.xmin<<" "<< r.xmax<<" "<<r.ymin<<" "<<r.ymax<< " ) " <<std::endl;

    }

    std::cout<<"detected: "<<std::endl;

    //global nms

    //std::cout<<"glabal nms: "<<std::endl;

    //qsort_descent(all_bbox_rects, all_bbox_scores);

    //std::vector<BBoxRect> picked_gnms;

    //std::vector<size_t> p_gnms;

    //nms_sorted_bboxes(all_bbox_rects, picked_gnms,p_gnms, nms_threshold);

    //num_detected = picked_gnms.size();

//for (int i = 0; i < num_detected; i++)

//{

// const BBoxRect& r = picked_gnms[i];

    //  float score_ = score[i];

    //  std::cout<<"class: "<< coco_classes[r.label-1] <<" "<< r.label <<"; score "<<score_ <<"; location (" <<r.xmin<<" "<< r.xmax<<" "<<r.ymin<<" "<<r.ymax<< " ) " <<std::endl;

    //}

    //std::cout<<"detected: "<<num_detected<<std::endl;

    //Mat& top_blob =top_blobs[0];

    //top_blob.reshape(6,num_detected,4u);

    //float *p = reinterpret_cast<float*>(top_blob.data);

    /*float *p;

    for (int i = 0; i < num_detected; i++)

    {

        const BBoxRect& r = picked_gnms[i];

        float score_ = score[i];

        *(p++)=r.xmin;

        *(p++)=r.xmax;

        *(p++)=r.ymin;

        *(p++)=r.ymax;

        *(p++)=r.label+1;

        *(p++)=score[i];

    }*/

    //Mat& top_blob = top_blobs[0];

    //top_blob.create(6, num_detected,1,4U);

    //std::cout<<"success"<<std::endl;

/*if (top_blob.empty())return -100;

for (int i = 0; i < num_detected; i++)

{

const BBoxRect& r = bbox_rects[i];

float score = bbox_scores[i];

float* outptr = top_blob.row(i);

outptr[0] = r.label + 1;// +1 for prepend background class

outptr[1] = score;

outptr[2] = (r.xmin)*416;

outptr[3] = (r.ymin)*416;

outptr[4] = (r.xmax)*416;

outptr[5] = (r.ymax)*416;

        std::cout<<"class "<<outptr[0]<<"score "<< outptr[1] << " "<< outptr[2] << " "<< outptr[3] << " " <<std::endl;

} */

return 0;

}

int inline Yolov3DetectionOutput::readData2Blobs(std::string name,std::vector<int>& shape,std::vector<Mat>& bottom_blobs){

    if(shape.size()!=3){return -1;}

    std::ifstream ifs(name.c_str(),std::ios::binary);

    ifs.seekg(0,std::ios::end);

    int length=ifs.tellg();

    ifs.seekg(0,std::ios::beg);

    int len2=52*52*255*4;

    printf("%d::MAX%d\n",length,len2);

    int len=length/sizeof(float);

    float *p=new float[len];

    if(ifs.is_open()){

     ifs.read(reinterpret_cast<char*>(p),length);

    }

    Mat blob(shape[2],shape[1],shape[0],p,4u);

    bottom_blobs.push_back(blob);

    ifs.close();

    blob.~Mat();

    return 0;

}

int inline Yolov3DetectionOutput::readData_Blobs(std::string name,std::vector<Mat>& bottom_blobs){

    std::ifstream ifs(name.c_str(),std::ios::binary);

    ifs.seekg(0,std::ios::end);

    int length=ifs.tellg();

    ifs.seekg(0,std::ios::beg);

    

    int len=length/sizeof(float);

    float *p=new float[len];

    if(ifs.is_open()){

     ifs.read(reinterpret_cast<char*>(p),length);

    }

    //printf("out:%f",*p);

    int len_blob=13*13*255;

    int len_blob2=26*26*255;

    Mat blob(255,13,13,p,4u);

    Mat blob2(255,26,26,p+len_blob,4u);

    Mat blob3(255,52,52,p+len_blob2,4u);

    bottom_blobs.push_back(blob);

    bottom_blobs.push_back(blob2);

    bottom_blobs.push_back(blob3);

    ifs.close();

    blob.~Mat();

    return 0;

}


int Main(int argc, char **argv) {

    std::cout<<"usage: detect implem "<<std::endl;

    std::vector<Mat> bottom_blobs;

    std::vector<Mat> top_blobs;

    int a[3]={255,13,13};

    int b[3]={255,26,26};

    int c[3]={255,52,52};

    std::vector<int> shape(a,a+3);

    std::vector<int> shape2(b,b+3);

    std::vector<int> shape3(c,c+3);

    std::vector<Mat> bottom_blobs_tiny;

    std::vector<Mat> bottom_blobs_caffe;

    std::vector<Mat> top_blobs_caffe;

    std::vector<Mat> bottom_blobs_darknet;

    std::vector<Mat> top_blobs_darknet;

    Yolov3DetectionOutput::readData2Blobs("1216/model_out_layer16_conv",shape,bottom_blobs_tiny);

    Yolov3DetectionOutput::readData2Blobs("1216/model_out_layer23_conv",shape2,bottom_blobs_tiny);

    std::cout<<"Blobs"<<std::endl;

    Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/YOLOV3/model_out_layer82_conv",shape,bottom_blobs);

    Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/YOLOV3/model_out_layer94_conv",shape2,bottom_blobs);

    Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/YOLOV3/model_out_layer106_conv",shape3,bottom_blobs);

    std::cout<<"Blobs"<<std::endl;

    Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/13x13",shape,bottom_blobs_caffe);

    Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/26x26",shape2,bottom_blobs_caffe);

    //Yolov3DetectionOutput::readData2Blobs("/home/jefff/MACE/52x52",shape3,bottom_blobs_caffe);

    Yolov3DetectionOutput::readData_Blobs("v3/416X416darknetout",bottom_blobs_darknet);

    std::cout<<"darknetElement0: ";

    std::cout<<reinterpret_cast<float *>(bottom_blobs_darknet[0].data)[0]<<std::endl;

    

    Yolov3DetectionOutput* y= new Yolov3DetectionOutput();

    std::vector<BBoxRect> boxes2;std::vector<BBoxRect> boxes3;

    //y->forward(bottom_blobs_tiny,top_blobs);

    y->forward(bottom_blobs,top_blobs,boxes2);

    //y->forward_nhwc(bottom_blobs,top_blobs,boxes2);

    //const Mat& bottom_top_blobs = bottom_blobs[0];

    //const float* xptr = bottom_top_blobs.channel(0);

    

    //y->forward(bottom_blobs_caffe,top_blobs_caffe);

    //y->forward_nhwc(bottom_blobs_caffe,top_blobs_caffe,boxes3);

    //y->forward(bottom_blobs_darknet,top_blobs_darknet);

   std::string imgFilename="/home/jefff/MACE/DOG_416.jpg";

    cv::Mat img = cv::imread(imgFilename);

    std::vector<BBoxRect>&boxes= boxes2;

    int num=boxes.size();

    while(num--){

        int left=ceil(boxes[num].xmin);

        int top=ceil(boxes[num].ymin);

        int right=ceil(boxes[num].xmax);

        int bot=ceil(boxes[num].ymax);

        printf("left = %d,right = %d,top = %d,bot = %d\n",left,right,top,bot);

        cv::rectangle(img,cv::Point(left,top),cv::Point(right,bot),cv::Scalar(0,0,255),3,8,0);

        char l[]={boxes[num].label/10+48,boxes[num].label%10+48};

        std::string ll =l;

        cv::putText(img,ll,cv::Point(right,bot),cv::FONT_HERSHEY_PLAIN,1.0,cv::Scalar(0,0,0),1,1);

    }

cv::namedWindow("show",CV_WINDOW_AUTOSIZE);

cv::imshow("show",img);

cv::waitKey(0);

//free_detections(dets,nboxes);

//free_image(im);

//free_image(sized);

    return 0;   

}

}

}// namespace mace

int main(int argc, char **argv) { mace::yolov3::Main(argc, argv);}

頭文件

#ifndef __DETECTION_H

#define __DETECTION_H

#include <memory>

#include "mat.h"

#include "allocator.h"

#include <vector>

#include <string>

namespace mace{

namespace yolov3{

struct BBoxRect

{

float xmin;

float ymin;

float xmax;

float ymax;

    int label;

};

class Yolov3DetectionOutput

{

public:

    Yolov3DetectionOutput();

~Yolov3DetectionOutput();

int load_param();

static int readData2Blobs(std::string name,std::vector<int>& shape,std::vector<Mat>& bottom_blobs);

static int readData_Blobs(std::string name,std::vector<Mat>& bottom_blobs);

//virtual int load_param(const ParamDict& pd);

//int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs,const Option& opt) const;

int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs,std::vector<BBoxRect>& boxes) const;

int forward_nhwc(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs,std::vector<BBoxRect>& boxes) const;

public:

//int num_class;

//int num_box;

//float confidence_threshold;

//float nms_threshold;

//float class_score;

//Mat biases;

    //Mat mask;

    //Mat anchors_scale;

    int mask_group_num;

//ncnn::Layer* softmax;

};

class Option

{

public:

// default option

Option();

public:

// light mode

// intermediate blob will be recycled when enabled

// enabled by default

bool lightmode;

// thread count

// default value is the one returned by get_cpu_count()

int num_threads;

// blob memory allocator

Allocator* blob_allocator;

// workspace memory allocator

Allocator* workspace_allocator;

};

const Option& get_default_option();

int set_default_option(const Option& opt);

}

} // namespace mace

#endif // LAYER_YOLODETECTIONOUTPUT_H

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章