Toybrick

yolov4-tiny C++版本推理结果错误

CQQQQQQQQQQ

新手上路

积分
35
发表于 2021-4-1 12:38:34    查看: 428|回复: 7 | [复制链接]    打印 | 显示全部楼层
本帖最后由 CQQQQQQQQQQ 于 2021-4-2 14:58 编辑

        自己训练的Yolov4-tiny模型,使用rknn-toolkite-1.6.0转换成rknn模型,在RK3399pro使用python版本的程序上能够成功运行,推理结果正确,与PC上的效果一致,且帧率可以达到50FPS,但是使用论坛上面提供的C++版本的程序之后,推理结果却不正确,无法检测出目标物体,API使用的是github上1.6.0版本的,请问大家跑通过C++版本的yolov4-tiny推理程序了吗?欢迎大佬赐教!附C++版本代码:
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <fstream>
  7. #include <atomic>
  8. #include <queue>
  9. #include <thread>
  10. #include <mutex>
  11. #include <chrono>
  12. #include <sys/time.h>
  13. #include <sys/stat.h>
  14. #include <dirent.h>
  15. #include <unistd.h>

  16. #include <rknn_api.h>
  17. #include "opencv2/core/core.hpp"
  18. #include "opencv2/imgproc/imgproc.hpp"
  19. #include "opencv2/highgui/highgui.hpp"
  20. #include <opencv2/opencv.hpp>

  21. #include <unistd.h>
  22. #include <sys/syscall.h>

  23. using namespace std;
  24. using namespace cv;


  25. int idxInputImage = 0;  // image index of input video
  26. int idxShowImage = 0;   // next frame index to be display
  27. bool bReading = true;   // flag of input

  28. typedef pair<int, Mat> imagePair;
  29. class paircomp {
  30. public:
  31.     bool operator()(const imagePair &n1, const imagePair &n2) const {
  32.         if (n1.first == n2.first) return n1.first > n2.first;
  33.         return n1.first > n2.first;
  34.     }
  35. };

  36. mutex mtxQueueInput;               // mutex of input queue
  37. mutex mtxQueueShow;                // mutex of display queue
  38. queue<pair<int, Mat>> queueInput;  // input queue
  39. priority_queue<imagePair, vector<imagePair>, paircomp> queueShow;  // display queue

  40. int multi_npu_process_initialized[2] = {0, 0};

  41. int demo_done=0;

  42. Scalar colorArray[10]={
  43.         Scalar(139,0,0,255),
  44.         Scalar(139,0,139,255),
  45.         Scalar(0,0,139,255),
  46.         Scalar(0,100,0,255),
  47.         Scalar(139,139,0,255),
  48.         Scalar(209,206,0,255),
  49.         Scalar(0,127,255,255),
  50.         Scalar(139,61,72,255),
  51.         Scalar(0,255,0,255),
  52.         Scalar(255,0,0,255),
  53. };

  54. static string labels[1]={"person"};

  55. static int GRID0=13;
  56. static int GRID1=26;
  57. static int nclasses=1;
  58. static int nyolo=2; //n yolo layers;
  59. static int nanchor=3; //n anchor per yolo layer

  60. static int nboxes_0=GRID0*GRID0*nanchor;
  61. static int nboxes_1=GRID1*GRID1*nanchor;
  62. static int nboxes_total=nboxes_0+nboxes_1;

  63. float OBJ_THRESH=0.2;
  64. float DRAW_CLASS_THRESH=0.2;
  65. float NMS_THRESH=0.4;  //darknet demo nms=0.4


  66. typedef struct{
  67.         float x,y,w,h;
  68. }box;

  69. typedef struct detection{
  70.     box bbox;
  71.     int classes;
  72.     float *prob;
  73.     float objectness;
  74.     int sort_class;
  75. } detection;

  76. void free_detections(detection *dets, int n)
  77. {
  78.     int i;
  79.     for(i = 0; i < n; ++i){
  80.         free(dets[i].prob);
  81.     }
  82.     free(dets);
  83. }

  84. double what_time_is_it_now()
  85. {
  86.     struct timeval time;
  87.     if (gettimeofday(&time,NULL)){
  88.         return 0;
  89.     }
  90.     return (double)time.tv_sec + (double)time.tv_usec * .000001;
  91. }

  92. box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int netw, int neth, int stride)
  93. {
  94.     box b;
  95.     b.x = (i + x[index + 0*stride]) / lw;
  96.     b.y = (j + x[index + 1*stride]) / lh;
  97.     b.w = exp(x[index + 2*stride]) * biases[2*n]   / netw;
  98.     b.h = exp(x[index + 3*stride]) * biases[2*n+1] / neth;
  99.     return b;
  100. }

  101. void get_network_boxes(float *predictions, int netw,int neth,int GRID,int* masks, float* anchors, int box_off, detection* dets)
  102. {
  103.         int lw=GRID;
  104.         int lh=GRID;
  105.         int nboxes=GRID*GRID*nanchor;
  106.         int LISTSIZE=1+4+nclasses;
  107.         //darkent output排列格式: box顺序为先grid再anchor
  108.         //1个anchor: 7*7*x+7*7*y+7*7*w+7*7*w+7*7*obj+7*7*classes1+7*7*classes2..+7*7*classes80,共3个anchor
  109.         //x和y(先做,或者放在后面转换到实际坐标这一步中也行),以及obj和classes做logisic
  110.         //xy做logistic
  111.         for(int n=0;n<nanchor;n++){
  112.                 int index=n*lw*lh*LISTSIZE;
  113.                 int index_end=index+2*lw*lh;
  114.                 for(int i=index;i<index_end;i++)
  115.                         predictions[i]=1./(1.+exp(-predictions[i]));                        
  116.         }
  117.         //类别和obj做logistic
  118.         for(int n=0;n<nanchor;n++){
  119.                 int index=n*lw*lh*LISTSIZE+4*lw*lh;
  120.                 int index_end=index+(1+nclasses)*lw*lh;
  121.                 for(int i=index;i<index_end;i++){
  122.                         predictions[i]=1./(1.+exp(-predictions[i]));               
  123.                 }
  124.         }
  125.         //dets将outpus重排列,dets[i]为第i个框,box顺序为先anchor再grid

  126.         int count=box_off;
  127.         for(int i=0;i<lw*lh;i++){
  128.                 int row=i/lw;
  129.                 int col=i%lw;
  130.                 for(int n=0;n<nanchor;n++){
  131.                         int box_loc=n*lw*lh+i;  
  132.                         int box_index=n*lw*lh*LISTSIZE+i;            //box的x索引,ywh索引只要依次加上lw*lh
  133.                         int obj_index=box_index+4*lw*lh;
  134.                         float objectness=predictions[obj_index];
  135.                         if(objectness<OBJ_THRESH) continue;
  136.                         dets[count].objectness=objectness;
  137.                         dets[count].classes=nclasses;
  138.                         dets[count].bbox=get_yolo_box(predictions,anchors,masks[n],box_index,col,row,lw,lh,netw,neth,lw*lh);
  139.                         for(int j=0;j<nclasses;j++){
  140.                                 int class_index=box_index+(5+j)*lw*lh;
  141.                                 float prob=objectness*predictions[class_index];
  142.                                 dets[count].prob[j]=prob;
  143.                         }
  144.                         ++count;
  145.                 }
  146.         }
  147.         //cout<<"count: "<<count-box_off<<"\n";
  148.     //return dets;
  149. }

  150. void outputs_transform(rknn_output rknn_outputs[], int net_width, int net_height, detection* dets){
  151.         float* output_0=(float*)rknn_outputs[0].buf;
  152.         float* output_1=(float*)rknn_outputs[1].buf;
  153.     int masks_0[3] = {3, 4, 5};
  154.     int masks_1[3] = {0, 1, 2};
  155.         float anchors[12] = {10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319};
  156.         //输出xywh均在0-1范围内
  157.         get_network_boxes(output_0,net_width,net_height,GRID0,masks_0,anchors,0,dets);
  158.         get_network_boxes(output_1,net_width,net_height,GRID1,masks_1,anchors,nboxes_0,dets);
  159.         //return dets;
  160. }

  161. float overlap(float x1,float w1,float x2,float w2){
  162.         float l1=x1-w1/2;
  163.         float l2=x2-w2/2;
  164.         float left=l1>l2? l1:l2;
  165.         float r1=x1+w1/2;
  166.         float r2=x2+w2/2;
  167.         float right=r1<r2? r1:r2;
  168.         return right-left;
  169. }

  170. float box_intersection(box a, box b)
  171. {
  172.     float w = overlap(a.x, a.w, b.x, b.w);
  173.     float h = overlap(a.y, a.h, b.y, b.h);
  174.     if(w < 0 || h < 0) return 0;
  175.     float area = w*h;
  176.     return area;
  177. }

  178. float box_union(box a, box b)
  179. {
  180.     float i = box_intersection(a, b);
  181.     float u = a.w*a.h + b.w*b.h - i;
  182.     return u;
  183. }

  184. float box_iou(box a, box b)
  185. {
  186.     return box_intersection(a, b)/box_union(a, b);
  187. }

  188. int nms_comparator(const void *pa, const void *pb)
  189. {
  190.     detection a = *(detection *)pa;
  191.     detection b = *(detection *)pb;
  192.     float diff = 0;
  193.     if(b.sort_class >= 0){
  194.         diff = a.prob[b.sort_class] - b.prob[b.sort_class];
  195.     } else {
  196.         diff = a.objectness - b.objectness;
  197.     }
  198.     if(diff < 0) return 1;
  199.     else if(diff > 0) return -1;
  200.     return 0;
  201. }
  202. int do_nms_sort(detection *dets, int total, int classes, float thresh)
  203. {
  204.     int i, j, k;
  205.     k = total-1;
  206.     for(i = 0; i <= k; ++i){
  207.         if(dets[i].objectness == 0){
  208.             detection swap = dets[i];
  209.             dets[i] = dets[k];
  210.             dets[k] = swap;
  211.             --k;
  212.             --i;
  213.         }
  214.     }
  215.     total = k+1;
  216.         //cout<<"total after OBJ_THRESH: "<<total<<"\n";

  217.     for(k = 0; k < classes; ++k){
  218.         for(i = 0; i < total; ++i){
  219.             dets[i].sort_class = k;
  220.         }
  221.         qsort(dets, total, sizeof(detection), nms_comparator);
  222.         for(i = 0; i < total; ++i){
  223.             if(dets[i].prob[k] == 0) continue;
  224.             box a = dets[i].bbox;
  225.             for(j = i+1; j < total; ++j){
  226.                 box b = dets[j].bbox;
  227.                 if (box_iou(a, b) > thresh){
  228.                     dets[j].prob[k] = 0;
  229.                 }
  230.             }
  231.         }
  232.     }
  233.         return total;
  234. }


  235. int draw_image(cv::Mat img,detection* dets,int total,float thresh)
  236. {
  237.         for(int i=0;i<total;i++){
  238.                 char labelstr[4096]={0};
  239.                 int class_=-1;
  240.                 int topclass=-1;
  241.                 float topclass_score=0;
  242.                 if(dets[i].objectness==0) continue;
  243.                 for(int j=0;j<nclasses;j++){
  244.                         if(dets[i].prob[j]>thresh){
  245.                                 if(topclass_score<dets[i].prob[j]){
  246.                                         topclass_score=dets[i].prob[j];
  247.                                         topclass=j;
  248.                                 }
  249.                                 if(class_<0){
  250.                                         strcat(labelstr,labels[j].data());
  251.                                         class_=j;
  252.                                 }
  253.                                 else{
  254.                                         strcat(labelstr,",");
  255.                                         strcat(labelstr,labels[j].data());
  256.                                 }
  257.                                 //printf("%s: %.02f%%\n",labels[j].data(),dets[i].prob[j]*100);
  258.                         }
  259.                 }
  260.                 //如果class>0说明框中有物体,需画框
  261.                 if(class_>=0){
  262.                         box b=dets[i].bbox;
  263.                         int x1 =(b.x-b.w/2.)*img.cols;
  264.                         int x2=(b.x+b.w/2.)*img.cols;
  265.                         int y1=(b.y-b.h/2.)*img.rows;
  266.                         int y2=(b.y+b.h/2.)*img.rows;

  267.             if(x1  < 0) x1  = 0;
  268.             if(x2> img.cols-1) x2 = img.cols-1;
  269.             if(y1 < 0) y1 = 0;
  270.             if(y2 > img.rows-1) y2 = img.rows-1;
  271.                         //std::cout << labels[topclass] << "\t@ (" << x1 << ", " << y1 << ") (" << x2 << ", " << y2 << ")" << "\n";

  272.             rectangle(img, Point(x1, y1), Point(x2, y2), colorArray[class_%10], 3);
  273.             putText(img, labelstr, Point(x1, y1 - 12), 1, 2, Scalar(0, 255, 0, 255));
  274.             }
  275.                 }
  276.         return 0;
  277. }


  278. void run_process(int thread_id)
  279. {
  280.         const char *model_path = "/tmp/yolov4_tiny.rknn";
  281.         const int net_width=416;
  282.         const int net_height=416;
  283.         const int img_channels=3;
  284.         cpu_set_t mask;
  285.         int cpuid = 0;
  286.         int ret = 0;

  287.         if (thread_id == 0)
  288.                 cpuid = 4;
  289.         else if (thread_id == 1)
  290.                 cpuid = 5;
  291.         else
  292.                 cpuid = 0;

  293.         CPU_ZERO(&mask);
  294.         CPU_SET(cpuid, &mask);

  295.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
  296.                 cerr << "set thread affinity failed" << endl;

  297.         printf("Bind NPU process(%d) to CPU %d\n", thread_id, cpuid);

  298.         rknn_input inputs[1];
  299.           rknn_output outputs[2];
  300.           rknn_tensor_attr outputs_attr[2];
  301.         detection* dets = 0;

  302.         dets =(detection*) calloc(nboxes_total,sizeof(detection));
  303.         for(int i = 0; i < nboxes_total; ++i)
  304.                 dets[i].prob = (float*) calloc(nclasses,sizeof(float));

  305.         // Load model
  306.         FILE *fp = fopen(model_path, "rb");
  307.             if(fp == NULL) {
  308.                 printf("fopen %s fail!\n", model_path);
  309.                 return;
  310.             }
  311.             fseek(fp, 0, SEEK_END);   //fp指向end,fseek(FILE *stream, long offset, int fromwhere);
  312.             int model_len = ftell(fp);   //相对文件首偏移
  313.             void *model = malloc(model_len);
  314.             fseek(fp, 0, SEEK_SET);   //SEEK_SET为文件头
  315.             if(model_len != fread(model, 1, model_len, fp)) {
  316.                 printf("fread %s fail!\n", model_path);
  317.                 free(model);
  318.                 return;
  319.             }
  320.         
  321.         //init
  322.         rknn_context ctx = 0;
  323.         ret = rknn_init(&ctx,model,model_len,RKNN_FLAG_PRIOR_MEDIUM);
  324.         if(ret < 0) {
  325.                 printf("rknn_init fail! ret=%d\n", ret);
  326.                 return;
  327.             }
  328.         
  329.         //rknn inputs
  330.         inputs[0].index = 0;
  331.         inputs[0].size = net_width * net_height * img_channels;
  332.         inputs[0].pass_through = false;         //需要type和fmt
  333.         inputs[0].type = RKNN_TENSOR_UINT8;
  334.         inputs[0].fmt = RKNN_TENSOR_NHWC;

  335.         //rknn outputs
  336.         outputs[0].want_float = true;
  337.         outputs[0].is_prealloc = false;
  338.         outputs[1].want_float = true;
  339.         outputs[1].is_prealloc = false;

  340.         //rknn outputs_attr
  341.         outputs_attr[0].index = 0;
  342.         ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(outputs_attr[0]), sizeof(outputs_attr[0]));
  343.         if(ret < 0) {
  344.             printf("rknn_query fail! ret=%d\n", ret);
  345.             return;
  346.         }

  347.         multi_npu_process_initialized[thread_id] = 1;
  348.           printf("The initialization of NPU Process %d has been completed.\n", thread_id);

  349.         while (true)
  350.         {
  351.                 double start_time,end_time;
  352.                 start_time=what_time_is_it_now();

  353.                 pair<int, Mat> pairIndexImage;
  354.                 mtxQueueInput.lock();
  355.                 if (queueInput.empty()) {
  356.                         //printf("waiting queueInput .........\n", ret);
  357.                         mtxQueueInput.unlock();
  358.                         usleep(1000);
  359.                         if (bReading) {
  360.                                 continue;
  361.                         } else {
  362.                                 rknn_destroy(ctx);
  363.                                 break;
  364.                         }
  365.                 } else {
  366.                         // Get an image from input queue
  367.                         pairIndexImage = queueInput.front();
  368.                         queueInput.pop();
  369.                         mtxQueueInput.unlock();
  370.                 }
  371.                
  372.                 //==================================================================================//
  373.                 // YOLO Process
  374.                 int nboxes_left = 0;
  375.                 cv::Mat resimg;
  376.                
  377.                 cv::resize(pairIndexImage.second, resimg, cv::Size(net_width, net_height), (0, 0), (0, 0), cv::INTER_LINEAR);
  378.                 cv::cvtColor(resimg, resimg, cv::COLOR_BGR2RGB);
  379.                
  380.                 inputs[0].buf = resimg.data;
  381.                 ret = rknn_inputs_set(ctx, 1, inputs);
  382.                 if (ret < 0) {
  383.                         printf("rknn_input_set fail! ret=%d\n", ret);
  384.                         return;
  385.                 }
  386.                
  387.                     ret = rknn_run(ctx, nullptr);
  388.                     if (ret < 0) {
  389.                         printf("rknn_run fail! ret=%d\n", ret);
  390.                         return;
  391.                     }

  392.                 ret = rknn_outputs_get(ctx, 2, outputs, NULL);
  393.                 if (ret < 0) {
  394.                         printf("rknn_outputs_get fail! ret=%d\n", ret);
  395.                         return;
  396.                 }
  397.                 end_time=what_time_is_it_now();
  398.                 //cout<<"rknn use time: "<<(end_time - start_time)<<"\n";
  399.                
  400.                 start_time = what_time_is_it_now();
  401.                 for(int i = 0; i < nboxes_total; ++i)
  402.                         dets[i].objectness = 0;
  403.                
  404.                 outputs_transform(outputs, net_width, net_height, dets);
  405.                 end_time=what_time_is_it_now();
  406.                 //cout<<"outputs_transform use time: "<<(end_time - start_time)<<"\n";

  407.                 start_time = what_time_is_it_now();
  408.                 nboxes_left=do_nms_sort(dets, nboxes_total, nclasses, NMS_THRESH);
  409.                 end_time=what_time_is_it_now();
  410.                 //cout<<"do_nms_sort use time: "<<(end_time - start_time)<<"\n";
  411.         
  412.                 start_time = what_time_is_it_now();
  413.                 draw_image(pairIndexImage.second, dets, nboxes_left, DRAW_CLASS_THRESH);
  414.                 end_time=what_time_is_it_now();
  415.                 //cout<<"draw_image use time: "<<(end_time - start_time)<<"\n";


  416.                 rknn_outputs_release(ctx, 2, outputs);
  417.                 mtxQueueShow.lock();
  418.                 // Put the processed iamge to show queue
  419.                 queueShow.push(pairIndexImage);
  420.                 mtxQueueShow.unlock();
  421.         }
  422. }

  423. void cameraRead(int index)
  424. {
  425.         int i = 0;
  426.           int initialization_finished = 1;
  427.           cpu_set_t mask;
  428.           int cpuid = 2;

  429.           CPU_ZERO(&mask);
  430.           CPU_SET(cpuid, &mask);

  431.           if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
  432.                     cerr << "set thread affinity failed" << endl;

  433.           printf("Bind CameraCapture process to CPU %d\n", cpuid);

  434.           VideoCapture camera(index);
  435.           if (!camera.isOpened()) {
  436.                   cerr << "Open camera error!" << endl;
  437.                   exit(-1);
  438.           }

  439.           while (true) {
  440.                     initialization_finished = 1;

  441.                     for (int i = 0; i < sizeof(multi_npu_process_initialized) / sizeof(int); i++) {
  442.                               //cout << i << " " << multi_npu_process_initialized << endl;
  443.                               if (multi_npu_process_initialized[i] == 0) {
  444.                                 initialization_finished = 0;
  445.                               }
  446.                     }

  447.                     if (initialization_finished)
  448.                               break;
  449.                     sleep(1);
  450.           }

  451.         while (true) {
  452.                 // read function
  453.                 usleep(1000);
  454.                 Mat img;
  455.                 camera >> img;
  456.                 if (img.empty()) {
  457.                         cerr << "Fail to read image from camera!" << endl;
  458.                         break;
  459.                 }

  460.                 mtxQueueInput.lock();
  461.                 queueInput.push(make_pair(idxInputImage++, img));
  462.                 if (queueInput.size() >= 30) {
  463.                         mtxQueueInput.unlock();
  464.                         cout << "[Warning]input queue size is " << queueInput.size() << endl;
  465.                         sleep(1);
  466.                 } else {
  467.                         mtxQueueInput.unlock();
  468.                 }
  469.                 if (bReading) {
  470.                         continue;
  471.                 } else {
  472.                         camera.release();
  473.                         break;
  474.                 }
  475.           }
  476. }

  477. void videoRead(const char *video_name)
  478. {
  479.         int i = 0;
  480.         int initialization_finished = 1;
  481.         int cpuid = 2;
  482.         cpu_set_t mask;

  483.         CPU_ZERO(&mask);
  484.         CPU_SET(cpuid, &mask);

  485.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
  486.                 cerr << "set thread affinity failed" << endl;

  487.         printf("Bind VideoCapture process to CPU %d\n", cpuid);

  488.         VideoCapture video;
  489.         if (!video.open(video_name)) {
  490.                 cout << "Fail to open " << video_name << endl;
  491.                 return;
  492.         }

  493.         int frame_cnt = video.get(CV_CAP_PROP_FRAME_COUNT);
  494.         
  495.         while (true) {
  496.                 initialization_finished = 1;
  497.                 for (int i = 0; i < sizeof(multi_npu_process_initialized) / sizeof(int); i++) {
  498.                         if (multi_npu_process_initialized[i] == 0) {
  499.                                 initialization_finished = 0;
  500.                         }
  501.                 }

  502.                 if (initialization_finished)
  503.                         break;

  504.                 sleep(1);
  505.         }

  506.         while (true)
  507.         {  
  508.                 usleep(1000);
  509.                 Mat img;

  510.                 if (queueInput.size() < 30) {
  511.                         if (!video.read(img)) {
  512.                                 cout << "read video stream failed! try replay!" << endl;
  513.                                 video.set(CV_CAP_PROP_POS_FRAMES, 0);
  514.                                 continue;
  515.                         }
  516.                         mtxQueueInput.lock();
  517.                         queueInput.push(make_pair(idxInputImage++, img));
  518.                         mtxQueueInput.unlock();

  519.                         if (frame_cnt > 0 && idxInputImage >= frame_cnt) {
  520.                                 video.set(CV_CAP_PROP_POS_FRAMES, 0);
  521.                                 continue;
  522.                         } else {
  523.                                 usleep(10);
  524.                         }
  525.                 }
  526.                 if (bReading) {
  527.                         continue;
  528.                 } else {
  529.                         video.release();
  530.                         break;
  531.                 }
  532.         }
  533. }
  534. void displayImage()
  535. {
  536.         Mat img;
  537.         cpu_set_t mask;
  538.         int cpuid = 3;

  539.         CPU_ZERO(&mask);
  540.         CPU_SET(cpuid, &mask);

  541.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
  542.                 cerr << "set thread affinity failed" << endl;

  543.         printf("Bind Display process to CPU %d\n", cpuid);

  544.         double first_time,last_time;
  545.         int fps;
  546.         first_time=what_time_is_it_now();
  547.         while (true)
  548.         {
  549.                 mtxQueueShow.lock();
  550.                 if (queueShow.empty()) {
  551.                         mtxQueueShow.unlock();
  552.                         usleep(1000);
  553.                 } else if (idxShowImage == queueShow.top().first) {
  554.                         Mat img = queueShow.top().second;
  555.                             string a = to_string(fps) + "FPS";
  556.                             cv::putText(img, a, cv::Point(15, 15), 1, 1, cv::Scalar{0, 0, 255},2);

  557.                             cv::imshow("RK3399Pro", img);  // display image
  558.                             idxShowImage++;
  559.                             queueShow.pop();
  560.                             mtxQueueShow.unlock();

  561.                             if (waitKey(1) == 27) {
  562.                                 cv::destroyAllWindows();
  563.                                 bReading = false;
  564.                                 break;
  565.                             }
  566.                         last_time=what_time_is_it_now();
  567.                         //cout<<"all use time: "<<(last_time - first_time)<<"\n";
  568.                         fps = (int)1/(last_time - first_time);
  569.                         first_time=what_time_is_it_now();
  570.                 } else {
  571.                             mtxQueueShow.unlock();
  572.                 }

  573.             }
  574. }

  575. int main(const int argc, const char** argv)
  576. {
  577.         int i, cpus = 0;
  578.         int camera_index;
  579.         cpu_set_t mask;
  580.         cpu_set_t get;
  581.         array<thread, 4> threads;

  582.         if (argc != 3) {
  583.                 cout << "Usage of this exec: ./yolov3-tiny c camera_index" << endl;
  584.                 cout << "                    ./yolov3-tiny v video_name" << endl;
  585.                 return -1;
  586.         }

  587.         cpus = sysconf(_SC_NPROCESSORS_CONF);
  588.         printf("This system has %d processor(s).\n", cpus);

  589.         string mode = argv[1];
  590.         if (mode == "c") {
  591.                 camera_index = atoi(argv[2]);
  592.                 threads = {thread(cameraRead, camera_index),
  593.                                 thread(displayImage),
  594.                                 thread(run_process, 0),
  595.                                 thread(run_process, 1)};
  596.         } else if (mode == "v") {
  597.                 threads = {thread(videoRead, argv[2]),
  598.                                 thread(displayImage),
  599.                                 thread(run_process, 0),
  600.                                 thread(run_process, 1)};
  601.         } else {
  602.                 return -1;
  603.         }

  604.         for (int i = 0; i < 4; i++)
  605.                 threads[i].join();

  606.         return 0;
  607. }
复制代码










回复

使用道具 举报

sunkai

注册会员

积分
157
发表于 2021-4-1 15:10:59 | 显示全部楼层
请问一下,c++版本的代码在哪里获取的
回复

使用道具 举报

CQQQQQQQQQQ

新手上路

积分
35
 楼主| 发表于 2021-4-1 16:36:28 | 显示全部楼层
sunkai 发表于 2021-4-1 15:10
请问一下,c++版本的代码在哪里获取的

http://t.rock-chips.com/forum.ph ... ight=C%2B%2B%2Byolo
这个帖子里面的附件有C++版本的代码,你需要注册账号,登陆后才能看到
回复

使用道具 举报

CQQQQQQQQQQ

新手上路

积分
35
 楼主| 发表于 2021-4-2 11:50:41 | 显示全部楼层
本帖最后由 CQQQQQQQQQQ 于 2021-4-2 14:02 编辑

找到原因了,opencv存储的图片是BGR模式,改成RGB模式就ok了。即程序里面run_process函数中关于cvtColor的地方要打开,cv::cvtColor(resimg, resimg, cv::COLOR_BGR2RGB);

回复

使用道具 举报

sunkai

注册会员

积分
157
发表于 2021-4-2 14:11:43 | 显示全部楼层
CQQQQQQQQQQ 发表于 2021-4-2 11:50
找到原因了,opencv存储的图片是BGR模式,改成RGB模式就ok了。即程序里面run_process函数中关于cvtColor的 ...

请问一下,你是在3399上面跑的,运行步骤能大概说下吗,是需要添加opencv的包先进行编译再运行吗
回复

使用道具 举报

CQQQQQQQQQQ

新手上路

积分
35
 楼主| 发表于 2021-4-2 14:57:06 | 显示全部楼层
sunkai 发表于 2021-4-2 14:11
请问一下,你是在3399上面跑的,运行步骤能大概说下吗,是需要添加opencv的包先进行编译再运行吗 ...

我是在3399pro上面跑的,要先编译安装opencv,然后按照api文件夹里面的使用说明书操作就可以了,即编译好工程之后,拷贝生成的可执行文件到/tmp文件夹里面运行
回复

使用道具 举报

sunkai

注册会员

积分
157
发表于 6 天前 | 显示全部楼层
你好,官方给的opencv中好像不能直接调用   videocapture方法吧,请问您是怎么处理的,编译opencv源文件吗
回复

使用道具 举报

Devin

中级会员

积分
346
发表于 5 天前 | 显示全部楼层
你测的20ms是推理时间还是包括了nms等后处理时间?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表