yolov5部署 单线程与多线程对比

news/2024/7/10 22:56:57 标签: YOLO

单线程

部署代码可参考:

Yolov5 ONNX Runtime 的 C++部署_爱钓鱼的歪猴的博客-CSDN博客

main.cpp

#include "detector.h"
#include <chrono>
using namespace std;



// 识别线程
void *detect_thread_entry(void *para){

}

int main(int argc, char *argv[])
{
    auto start1 = std::chrono::system_clock::now();
    Detector detector;
    bool isGPU=false;
    Utils utils;
    const vector<string> classNames=utils.loadNames("/home/lrj/work/file/coco.names");

    if(classNames.empty()){
        cerr<<"Error: Empty class names file"<<endl;
        return -1;
    }
    cv::Mat image;
    vector<Detection> result;

    cv::VideoCapture capture(2);
    if (!capture.isOpened())
        return 1;

    auto end1 = std::chrono::system_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start1);

    cout << " " << endl;
    printf("init time use: %ld ms", duration);

    while(1){
        auto start2 = std::chrono::system_clock::now();
        capture >> image;

        try{
            detector.YOLODetector(isGPU,cv::Size(640,640));
            cout<<"Model was initialized......"<<endl;

            int ret = detector.detect(image,0.4,0.4, result);

            }catch(const exception& e){
                cerr<<e.what()<<endl;
                return -1;
            }

    utils.visualizeDetection(image,result,classNames);


    auto end2 = std::chrono::system_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - start2);
    string text = "time use: " + std::to_string(duration.count()) + "ms";
    cv::putText(image, text, cv::Point(30, 30), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255,0,0),2);

    imshow("result", image);
    if(cv::waitKey(1) == 'q') break;

    }
    return 0;
}

这里是单线程,每帧获取耗时200ms左右,也就是fps大概为5;

多线程

#include "detector.h"
#include <chrono>
#include <pthread.h>
#include <unistd.h>
#include "utils.h"

using namespace std;

struct ThreadParams {
    vector<Detection> result_;
};

cv::Mat algorithm_image = cv::Mat::zeros(480,640,CV_8UC3);
//pthread_cond_t img_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t img_lock;
pthread_mutex_t result_lock;

Utils utils;
const vector<string> classNames=utils.loadNames("/home/lrj/work/file/coco.names");

 //识别线程
void *detect_thread_entry(void *para){

    // 初始化
    Detector detector;
    bool isGPU=false;
    detector.YOLODetector(isGPU,cv::Size(640,640));
    cout<<"Model was initialized......"<<endl;

    ThreadParams *pThreadParams = (ThreadParams *) para;
//    vector<Detection> result = pThreadParams->result_;
    cv::Mat image;
    while(1){

            auto start = std::chrono::system_clock::now();

            // 阻塞等待图像可用
            if(algorithm_image.empty()){
                cerr << "Error: Failed to retrieve image frame" << endl;
                usleep(5);
                continue;

            }

            pthread_mutex_lock(&img_lock); // 加锁
            image = algorithm_image.clone(); // 复制图片
            pthread_mutex_unlock(&img_lock); // 解锁



            pthread_mutex_lock(&result_lock); // 加锁
            int ret = detector.detect(image,0.4,0.4, pThreadParams->result_); // 检测
            pthread_mutex_unlock(&result_lock); // 解锁


            auto end = std::chrono::system_clock::now();
            auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
            string text = "yolov5n detect time use: " + std::to_string(duration.count()) + "ms";
            cout << text + "\n" + "\n" << endl;

            if(pThreadParams->result_.size() <=0){
                usleep(1000);
                continue;
            }

    }
    return NULL;
}

int main(int argc, char *argv[])
{
    if(classNames.empty()){
            cerr<<"Error: Empty class names file"<<endl;
            return -1;
    }

    ThreadParams threadParams;
    threadParams.result_ = std::vector<Detection> ();
    pthread_t mTid;


    // 1.打开摄像头
    cv::VideoCapture camera(2);
    if (!camera.isOpened())
            return -1;
    int width = camera.get(cv::CAP_PROP_FRAME_WIDTH);
    int height = camera.get(cv::CAP_PROP_FRAME_HEIGHT);
    int fps = camera.get(cv::CAP_PROP_FPS);
    cout << width << "  ||" <<height << fps << endl;


    // 跳过前10帧
    int skip = 10;
    while(skip--){
            camera >> algorithm_image;
    }

    // 2创建识别线程,以及图像互斥锁
    pthread_mutex_init(&img_lock, NULL);
    pthread_mutex_init(&result_lock, NULL);

    pthread_create(&mTid, NULL, detect_thread_entry,(void*)&threadParams);


    // 3.(取流 + 显示)循环
    cv::Mat img;
    while(1){
            // 4.1 取流
            pthread_mutex_lock(&img_lock);
            camera >> algorithm_image;
            img = algorithm_image.clone();
//            pthread_cond_signal(&img_cond); // 通知识别线程图像可用
            pthread_mutex_unlock(&img_lock);

            // 4.2 显示
            pthread_mutex_lock(&result_lock); // 加锁
            utils.visualizeDetection(img,threadParams.result_,classNames);
            pthread_mutex_unlock(&result_lock); // 解锁
            cv::imshow("result", img);
            if(cv::waitKey(1) == 'q') break;
//            usleep(150*1000);
    }

//    pthread_join(mTid, NULL); // 等待识别线程的结束
    pthread_mutex_destroy(&img_lock);
    pthread_mutex_destroy(&result_lock);
    return 0;
}

这里主线程(main函数)负责获取图像及展示图像;识别线程负责yolov5检测,每帧耗时170ms左右(CPU是比较慢)。

其实这里获取主线程获取图像很快,主要是检测比较耗时;我感觉主线程获取的图像一直在排队等待被检测。

 


http://www.niftyadmin.cn/n/4935274.html

相关文章

golang专栏

GOLANG专栏订阅会员 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教…

JAVA 实训报告心得体会

一开始想做计算器那个课题&#xff0c;原因很简单&#xff0c;就是因为我感觉那个课题很简 单&#xff0c;在百度里一搜就搜到了一模一样的源程序。只是感觉没什么意思&#xff0c;那个界面也 不是很好看&#xff0c;又不好玩。所以就做了现在这个猜数游戏。一直想编个游戏程序…

Python学习笔记合集(Pandas总结)

Python学习笔记合集 Python学习笔记合集(Pandas总结)Python学习笔记第五十二天&#xff08;Pandas 安装&#xff09;Python学习笔记第五十三天&#xff08;Pandas Series&#xff09;Python学习笔记第五十四天&#xff08;Pandas DataFrame&#xff09;Python学习笔记第五十五天…

物流行业数据分析

文章目录 物流行业数据分析一、数据预处理1、数据清洗① 重复值、缺失值、格式调整② 异常值处理 2、数据规整 二、 数据分析1、配送服务是否存在问题2、是否存在尚有潜力的销售区域3、商品是否存在质量问题 三、总结参考 物流行业数据分析 Excel适合处理低量级数据&#xff0…

一文囊括风控模型搭建(原理+Python实现),持续更新。。。

风控模型已在各大银行和公司都实际运用于业务&#xff0c;用于营销和风险控制等。本文梳理风控模型搭建的原理和Python实现&#xff0c;按顺序做成清单的形式&#xff0c;点击即可进入相应文章链接。方便大家系统地掌握风控模型的搭建和上线运用。    风控建模整体流程    …

python小白之matplotlib使用实战项目:随机漫步

文章目录 随机漫步1.1 创建RandomWalk类1.2 选择方向1.3 绘制随机漫步图1.4 模拟多次随机漫步1.5 设置随机漫步图样式1.5.1 给点着色1.5.2 重新绘制起点和终点1.5.3 隐藏坐标轴1.5.4 增加点数1.5.5 调整图片尺寸以适应屏幕 附录&#xff08;项目代码&#xff09;random_walk.py…

【人工智能124种任务大集合】-集齐了自然语言处理(NLP),计算机视觉(CV),语音识别,多模态等任务

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能124种任务大集合&#xff0c;任务集合主要包括4大类&#xff1a;自然语言处理&#xff08;NLP&#xff09;、计算机视觉&#xff08;CV&#xff09;、语音识别、多模态任务。 我这里整理了124种应用场景任…

Kotlin 基础教程一

Kotlin 基本数据类型 Java | Kotlin byte Byte short Short int Int long Long float Float double Double boolean Boolean c…