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

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;
}

改进

未完待续。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

axios——503响应超时重复多次请求——技能提升

今天在写后台管理系统时&#xff0c;遇到一个问题&#xff0c;就是每天早上一启动项目&#xff0c;接口会提示503超时&#xff0c;因此项目运行必须重新刷新请求成功后才可以正常使用。 后端同事说请求超时了&#xff0c;需要前端处理一下&#xff0c;如果是503的状态码&#…

封装 H.264 视频为 FLV 格式然后推流

封装 H.264 视频为 FLV 格式并通过 RTMP 推流 flyfish 协议 RTMP (Real-Time Messaging Protocol) RTSP (Real Time Streaming Protocol) SRT (Secure Reliable Transport) WebRTC RTMP&#xff08;Real Time Messaging Protocol&#xff09;是一种用于实时音视频流传输的协…

西安交通大学 915 备考常见误区

看到助教在 915 全程班群里给同学们解答问题&#xff0c;我也是感触颇深&#xff0c;想起来我当年自身的一个备考情况。接下来结合我自身情况给同学们分析一下&#xff0c;为什么有的同学基础一般&#xff0c;最后分数却很高&#xff0c;有的同学基础很好&#xff0c;分数却一般…

Linux网络编程---多进/线程并发服务器

一、多进程并发服务器 实现一个服务器可以连接多个客户端&#xff0c;每当accept函数等待到客户端进行连接时 就创建一个子进程 思路分析&#xff1a; 核心思路&#xff1a;让accept循环阻塞等待客户端&#xff0c;每当有客户端连接时就fork子进程&#xff0c;让子进程去和客户…

html+css+js+jquery实现在网页端将手动输入用户的信息转化成表格

1.实现的效果图 2.css代码 ​<style>*{background-color: antiquewhite;}#ss{font-size:20px;text-align: center;}#inputForm { margin-bottom: 20px; } #userTable { width: 100%; border-collapse: collapse; } #userTable th, #userTable td { border: 1px …

Xcode for Mac:强大易用的集成开发环境

Xcode for Mac是一款专为苹果开发者打造的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它集成了代码编辑器、编译器、调试器等一系列开发工具&#xff0c;让开发者能够在同一界面内完成应用的开发、测试和调试工作。 Xcode for Mac v15.2正式版下载 Xcode支持多种编程…

Linux进阶篇:CentOS7搭建NFS文件共享服务

CentOS7搭建NFS文件共享服务 一、NFS介绍 NFS(Network File System)意为网络文件系统&#xff0c;它最大的功能就是可以通过网络&#xff0c;让不同的机器不同的操作系统可以共享彼此的文件。简单的讲就是可以挂载远程主机的共享目录到本地&#xff0c;就像操作本地磁盘一样&…

Ubentu18.0+ORBSLAM2

Ubentu18.0ORB-SLAM2摄像头 引言&#xff1a; ​ 在视觉同步定位与地图构建&#xff08;Simultaneous Localization and Mapping, SLAM&#xff09;领域&#xff0c;ORB-SLAM2系统的出现标志着重要的技术进步。这个著名的SLAM系统由Juan D. Tards、Ral Mur-Artal等人开发&#…

RabbitMQ发布确认和消息回退(6)

概念 发布确认原理 生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm 模式&#xff0c;所有在该信道上面发布的消息都将会被指派一个唯一的 ID(从 1 开始)&#xff0c;一旦消息被投递到所有匹配的队列之后&#xff0c;broker就会发送一个确认给生产者(包含消…

git 基础知识(全能版)

文章目录 一 、git 有三个分区二、git 基本操作1、克隆—git clone2、拉取—git fetch / git pull3、查看—git status / git diff3.1 多人开发代码暂存技巧 本地代码4、提交—git add / git commit / git push5、日志—git log / git reflog6、删除—git rm ‘name’7、撤销恢…

OceanBase开发者大会实录 - 阳振坤:云时代的数据库

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase 首席科学家阳振坤的演讲实录——《云时代的数据库》。完整视频回看&#xff0c;请点击这里 >> 在去年的开发者大会中&#xff0c;我跟大家分享了我对数据库产品和技术一些看法&#xff0c;包括单机分布式一体化&…

字符函数·字符串函数·C语言内存函数—使用和模拟实现

字符函数字符串函数C语言内存函数 1.字符分类函数2. 字符转换函数3. strlen的使用和模拟实现4.strcpy的使用和模拟实现5.strcat的使用和模拟实现6.strcmp的使用和模拟实现7.strncpy的模拟和实现8.strncat的实现和模拟实现9.strncmp函数使用10.strstr的使用和模拟实现11.strtok函…

备考数通HCIE证书4点经验分享!

大家好&#xff0c;我是来自安阳工学院20级网络工程的刁同学&#xff0c;在2023年12月20日成功通过了华为Datacom HCIE认证&#xff0c;并且取得了笔试900多分&#xff0c;实验B的成绩。在此&#xff0c;我想把我的一些考证心得分享给正在备考的小伙伴们。 关于为什么考证 我…

Vue3+ts(day03:ref和reactive)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

tcp inflight 守恒算法的自动收敛

inflight 守恒算法看起来只描述理想情况&#xff0c;现实很难满足&#xff0c;是这样吗&#xff1f; 从 reno 到 bbr&#xff0c;无论哪个算法都在描述理想情况&#xff0c;以 reno 和 bbr 两个极端为例&#xff0c;它们分别描述两种理想管道&#xff0c;reno 将 buffer 从恰好…

Apollo 7周年大会:百度智能驾驶的展望与未来

本心、输入输出、结果 文章目录 Apollo 7周年大会&#xff1a;百度智能驾驶的展望与未来前言百度集团副总裁、智能驾驶事业群组总裁王云鹏发言 直播回放大会相关内容先了解 Apollo&#xfeff;开放平台 9.0架构图 发布产品Apollo 定义自己对于智能化的认知百度集团副总裁 王云鹏…

Grafana系列 | Grafana监控TDengine库数据 |Grafana自定义Dashboard

开始前可以去grafana官网看看dashboard文档 https://grafana.com/docs/grafana/latest/dashboards 本文主要是监控TDengine库数据 目录 一、TDengine介绍二、Grafana监控TDengine数据三、Grafana自定义Dashboard 监控TDengine库数据1、grafana 变量2、添加变量3、配置panel 一…

Docker——数据管理和网络通信

目录 一、Docker的数据管理 1.数据卷 2.数据卷容器 3.容器互联 二、Docker镜像的创建 1.基于现有镜像创建 2.基于本地模板创建 3.基于Dockerfile 创建 3.1联合文件系统&#xff08;UnionFS&#xff09; 3.2镜像加载原理 3.3为什么Docker里的Centos大小才200M 4.Dcok…

鸿蒙OpenHarmony【轻量系统 编写“Hello World”程序】 (基于Hi3861开发板)

编写“Hello World”程序 下方将通过修改源码的方式展示如何编写简单程序&#xff0c;输出“Hello world”。请在下载的源码目录中进行下述操作。 确定目录结构。 开发者编写业务时&#xff0c;务必先在./applications/sample/wifi-iot/app路径下新建一个目录&#xff08;或一…

CSS基础语法

CSS 标签选择器 内嵌式改变标签样式 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><!-- 属于标签选择器 --><style>p{font - size: 16px;color: red;}</style></head><bo…