视频输入c++ 调用 libtorch推理

news2024/12/25 12:27:35

1、支持GPU情况

libtorch 支持GPU情况比较奇怪,目前2.3 版本需要在链接器里面加上以下命令,否则不会支持gpu

-INCLUDE:?ignore_this_library_placeholder@@YAHXZ
在这里插入图片描述

2 探测是否支持

加一个函数看你是否支持torch,不然不清楚,看到支持gpu才行

void IsSupportCuda()
{
    if (torch::cuda::is_available())
    {
        std::cout << "支持GPU" << std::endl;
    }
    else
    {
        std::cout << "不支持GPU" << std::endl;
    }
    torch::Tensor tensor = torch::rand({ 5,3 });
    torch::Device device1(torch::kCUDA);
    tensor.to(device1);
    std::cout << tensor <<"--"<< tensor.options() << std::endl;
};

int main() {
    IsSupportCuda();
    return 0;
}

转化

在这里插入图片描述
使用命令转,如下图所示

yolo export model=yolov8s.pt imgsz=640 format=torchscript

在这里插入图片描述
成功以后在目录下面生成文件yolov8s.torchscript

c++ 调用

int main() {
    //IsSupportCuda();

    //return 0;
    // Device
    torch::Device device(torch::cuda::is_available() ? torch::kCUDA : torch::kCPU);

    // Note that in this example the classes are hard-coded
    std::vector<std::string> 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" };

    try {
        // Load the model (e.g. yolov8s.torchscript)
        std::string model_path = "./yolov8s.torchscript";
        torch::jit::script::Module yolo_model;
        yolo_model = torch::jit::load(model_path);
        yolo_model.eval();
        yolo_model.to(device, torch::kFloat32);

        // Load image and preprocess
        cv::Mat image = cv::imread("d:/bus.jpg");
        cv::Mat input_image;
        letterbox(image, input_image, { 640, 640 });

        torch::Tensor image_tensor = torch::from_blob(input_image.data, { input_image.rows, input_image.cols, 3 }, torch::kByte).to(device);
        //auto image_tensor_float = image_tensor.to(torch::kFloat32);
        //image_tensor_float /= 255.0;
        image_tensor = image_tensor.toType(torch::kFloat32).div(255);
        image_tensor = image_tensor.permute({ 2, 0, 1 });
        image_tensor = image_tensor.unsqueeze(0);
        std::vector<torch::jit::IValue> inputs{ image_tensor };

        // Inference
        torch::Tensor output = yolo_model.forward(inputs).toTensor().cpu();

        // NMS
        auto keep = non_max_suppression(output)[0];
        auto boxes = keep.index({ Slice(), Slice(None, 4) });
        keep.index_put_({ Slice(), Slice(None, 4) }, scale_boxes({ input_image.rows, input_image.cols }, boxes, { image.rows, image.cols }));

        // Show the results
        for (int i = 0; i < keep.size(0); i++) {
            int x1 = keep[i][0].item().toFloat();
            int y1 = keep[i][1].item().toFloat();
            int x2 = keep[i][2].item().toFloat();
            int y2 = keep[i][3].item().toFloat();
            float conf = keep[i][4].item().toFloat();
            int cls = keep[i][5].item().toInt();
            std::cout << "Rect: [" << x1 << "," << y1 << "," << x2 << "," << y2 << "]  Conf: " << conf << "  Class: " << classes[cls] << std::endl;
        }
        getchar();
    }
    catch (const c10::Error& e) {
        std::cout << e.msg() << std::endl;
    }

    return 0;
}

解码后视频帧调用

先使用opencv,同时使用硬件加速,使用硬件解码,新版本的使用方法已经不一样了,以下先举个例子,指定使用ffmpeg


int main() {
    // 创建一个 VideoCapture 对象,并指定使用 FFmpeg 作为后端  
    cv::ocl::setUseOpenCL(true);
    if (!cv::ocl::haveOpenCL()) {
        std::cerr << "OpenCL is not available.\n";
        return -1;
    }
    else {
        std::cout << cv::ocl::Device().getDefault().name() << std::endl;
    }

   cv::VideoCapture cap1("rtsp://127.0.0.1/99-640.mkv", cv::CAP_FFMPEG, {
            cv::CAP_PROP_HW_ACCELERATION,(int)cv::VIDEO_ACCELERATION_D3D11,
            cv::CAP_PROP_HW_DEVICE, 0
   });

   // cv::VideoCapture cap2("d:/8k.mp4", cv::CAP_FFMPEG);


    // 检查是否成功打开视频文件  
    if (!cap1.isOpened()) {
        std::cerr << "Error opening video file" << std::endl;
        return -1;
    }
   
    // 检查是否支持硬件加速
    double hw1 = cap1.get(cv::CAP_PROP_HW_ACCELERATION);
   // double hw2 = cap2.get(cv::CAP_PROP_HW_ACCELERATION);
    if (hw1 >= cv::VIDEO_ACCELERATION_ANY ) {
        // 支持硬件加速,尝试启用
        //cap.set(cv::CAP_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_ANY);
        std::cout << "Hardware acceleration enabled" << std::endl;
    }
    else {
        std::cout << "Hardware acceleration not supported or not available" << std::endl;
    }
    // 设置硬件加速(如果支持的话)  
    // 注意:不是所有的平台和驱动程序都支持硬件加速  
   // cap.set(cv::CAP_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_ANY);  
    cv::UMat uFrame,Frame; // GPU 上的 UMat 对象,用于直接接收解码后的数据  
    // 读取并处理视频帧  
    while (true) {
        // 尝试直接从 VideoCapture 读取帧到 UMat  
        cv::UMat m;

        bool ret = cap1.read(m);
        if (!ret) {
            std::cout << "End of video" << std::endl;
            break;
        }
        
        int w = m.cols;
        int h = m.rows;
        //m.copyTo(uFrame);
        
        //uFrame = m.getUMat(cv::ACCESS_READ);

        cv::UMat m1,m2,m3,m4,m5;
        //视频矫正
        rectify_umat(m, w, h, default_K0, default_D0, m1);
        //cv::Mat m1, m2, m3,m4;
        //放大增强
        cv::resize(m1, m2, cv::Size(w*2, h*2),0,0,cv::INTER_CUBIC);

        letterbox(m2, input_image, { 640, 640 });

        torch::Tensor image_tensor = torch::from_blob(input_image.data, { input_image.rows, input_image.cols, 3 }, torch::kByte).to(device);
        //auto image_tensor_float = image_tensor.to(torch::kFloat32);
        //image_tensor_float /= 255.0;
        image_tensor = image_tensor.toType(torch::kFloat32).div(255);
        image_tensor = image_tensor.permute({ 2, 0, 1 });
        image_tensor = image_tensor.unsqueeze(0);
        std::vector<torch::jit::IValue> inputs{ image_tensor };

        // Inference
        torch::Tensor output = yolo_model.forward(inputs).toTensor().cpu();

        // NMS
        auto keep = non_max_suppression(output)[0];
        auto boxes = keep.index({ Slice(), Slice(None, 4) });
        keep.index_put_({ Slice(), Slice(None, 4) }, scale_boxes({ input_image.rows, input_image.cols }, boxes, { image.rows, image.cols }));

        // Show the results
        for (int i = 0; i < keep.size(0); i++) {
            int x1 = keep[i][0].item().toFloat();
            int y1 = keep[i][1].item().toFloat();
            int x2 = keep[i][2].item().toFloat();
            int y2 = keep[i][3].item().toFloat();
            float conf = keep[i][4].item().toFloat();
            int cls = keep[i][5].item().toInt();
            std::cout << "Rect: [" << x1 << "," << y1 << "," << x2 << "," << y2 << "]  Conf: " << conf << "  Class: " << classes[cls] << std::endl;
        }

        func_3_umat(m2, m3);
        func_1_umat(m3, m4);
        func_0_umat(m4, m5);
     
        cv::imshow("m", m);
        cv::imshow("m2", m2);
        cv::imshow("res", m5);
        if (cv::waitKey(10) == 'q') {
            break;
        }
    }

    // 释放资源  
    cap1.release();
    //cap2.release();
    cv::destroyAllWindows();

    return 0;
}

改进

未完待续。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1627680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库和表创建练习

一丶要求 1.创建一个数据库db_classes 2 创建一行表db_hero 3. 将四大名著中的常见人物插入这个英雄表 二丶创建db_classes一个数据库, 使用数据库默认的字符集 create database db_classes; 三丶创建一行表db_hero 1.先切换到我们创建的db_classes;数据库中 use db_class…

HTTP的MIME 类型(2024-04-27)

1、简介 MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准&#xff0c;用来表示文档、文件或字节流的性质和格式。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。 浏览器通常使用 MIME 类型&#xff08;而不是文件扩展名&…

打包的意义 作用等前端概念集合 webpack基础配置等

基础网页是什么&#xff1f; 在学校最基础的三剑客 原生JS CSS H5就可以开发静态网页了 对于浏览器而言也能识别这些基础的文件和语法&#xff0c;真正的所见即所得&#xff0c;非常直接。 为什么要使用框架库&#xff1f; 对于常用的前端框架而言&#xff0c;无论是Vue Rea…

【面试经典 150 | 回溯】组合

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;回溯 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

企业微信开发

侧边栏开发 企业内应用 创建应用 录入必要信息 配置 网页授权及JS-SDK 需要按照提示&#xff0c;把认证的txt暴露出来&#xff0c;能够访问即可。 下图为认证成功的截图 配置侧边栏工具栏 录入页面名称&#xff08;tab页展示名&#xff09;、页面URL 配置授权可信ip 用于…

boa交叉编译(移植到arm)

参考&#xff1a;CentOS7 boa服务器的搭建和配置-CSDN博客 以下操作在宿主机/编译平台操作&#xff1a; 1. 先执行[参考]1到3、 4.2、4.3、4.4、4.5 2. 修改MakeFile # 由以下&#xff1a; CC gcc CPP gcc -E # 改为&#xff1a; CC arm-linux-gnueabihf-gcc CPP arm-l…

019基于JavaWeb的在线音乐系统(含论文)

019基于JavaWeb的在线音乐系统&#xff08;含论文&#xff09; 开发环境&#xff1a; Jdk7(8)Tomcat7(8)MysqlIntelliJ IDEA(Eclipse) 数据库&#xff1a; MySQL 技术&#xff1a; JavaServletJqueryJavaScriptAjaxJSPBootstrap 适用于&#xff1a; 课程设计&#xff0c;毕…

Prometheus数据模型与查询语言:构建高效监控系统的关键

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Prometheus&#xff1a;监控的神》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Prometheus诞生史 二、Prometheus的数据模型与查询语…

零基础HTML教程(31)--HTML5多媒体

文章目录 1. 背景2. audio音频3. video视频4. audio与video常用属性5. 小结 1. 背景 在H5之前&#xff0c;我们要在网页上播放音频、视频&#xff0c;需要借助第三方插件。 这些插件里面最火的就是Flash了&#xff0c;使用它有几个问题&#xff1a; 首先要单独安装Flash&…

物资管理的挑战与机遇:利用技术提升效率与可持续性

引言 物资管理在企业运营中扮演着至关重要的角色。有效的物资管理不仅能够确保企业正常生产和运营所需的物资供应&#xff0c;还能够最大程度地优化资源利用、降低成本、提高效率&#xff0c;从而增强企业的竞争力和可持续发展能力。然而&#xff0c;在当今复杂的全球供应链环境…

WebSocket的原理、作用、API、常见注解和生命周期的简单介绍,附带SpringBoot示例

文章目录 原理作用客户端 API服务端 API生命周期常见注解SpringBoot示例 WebSocket是一种 通信协议 &#xff0c;它在 客户端和服务器之间建立了一个双向通信的网络连接 。WebSocket是一种基于TCP连接上进行 全双工通信 的 协议 。 WebSocket允许客户端和服务器在 单个TCP连接上…

逆数对(树状数组的方法)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 5 4 5 1 3 2 输出 7 思路&#xff1a; 根据题意&#xff0c;求逆序对总数。 逆序对含义&#xff1a;如果数组中的两个不同位置&#xff0c;前面的数字比后面的数字严格大&…

websocket爬虫

人群看板需求分析 先找到策略中心具体的数据。对应数据库中的数据 看看接口是否需要被逆向 点开消费者细分&#xff0c;可以找到人群包&#xff08;人群名称&#xff09; 点击查看透视 label字段分类: 在这里插入图片描述 预测年龄&#xff1a;tagTitle 苹果id&#x…

【源码】2024最新在线客服系统优化版/客服金额结算+后台翻译+可对接自己平台客户

【源码说明】 测试环境&#xff1a;宝塔、Linux系统、PHP7.2、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态thinkPHP&#xff0c;【不要开启ssl&#xff0c;用http就行】 config/database.php 修改数据库信息 public/index.php 修改域名信息 cgwl_pusher/config.php …

Leetcode662_二叉树最大宽度

1.leetcode原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 2.题目描述 给你一棵二叉树的根节点 root &#xff0c;返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每一层的 宽度 被定义为该层最左和最右的非空节点&#xff08;即&#xff0…

Angular创建项目

Angular创建项目 文章目录 Angular创建项目1. 创建项目1.1 直接安装1.2 跳过npm i安装 2. 运行程序 1. 创建项目 ng new 项目名称 1.1 直接安装 ng new angulardemo --同时会安装依赖包&#xff0c;执行的命令就是npm i 1.2 跳过npm i安装 ng new angulardemo --skip-inst…

关于权限的设计

首先系统权限&#xff0c;每个账号登录后&#xff0c;都需要知道这个账号允许访问哪些api&#xff0c;哪些数据权限&#xff08;一般是指其他账号的一些数据&#xff09; 这里就需要通过角色来关联。 --1.角色绑定菜单&#xff0c;每个菜单设计的时候包含了这个菜单会用到的所…

MySql基础二之【MySql增删改查操作】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言MYSQL数据的插入操作MYSQL数据的修改操作MYSQL数据的删除操作MYSQL数据的…

【八大排序(二)】选择排序与堆排序

❣博主主页: 33的博客❣ ▶️文章专栏分类:八大排序◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多排序知识 目录 1.前言2.选择排序2.1基本思想2.2画图理解2.3单向选择排序代码实现2.4双向选择排序代码…

创建Spring Boot项目

选择Maven Archetype,之后再Archetype选择webapp 两个都打勾 这是当前的打勾 这个是以后都默认勾上 打开对应的路径&#xff0c;用vscode打开settings.xml 加入国内源 阿里云 若没有此文件可上网查找 若jar包出现问题&#xff0c;可在repostitory文件内全删除 之后在Maven刷…