首页 > 其他分享 >rust中使用opencv和cuda

rust中使用opencv和cuda

时间:2024-11-28 11:21:37浏览次数:5  
标签:mut unwrap max opencv let cuda rust bbox

最近公司有个要识别的项目需要计算机识别,于是就找到了opencv来进行,opencv的cuda版本需要自己来进行编译需要去opencv官网下载,我下载的版本是opencv4.10
https://github.com/opencv/opencv/archive/refs/tags/4.10.0.zip
还有需要opencv_contrib-4.10.0和cmake下载
下载之前需要检查自己的cuda和cudnn
cmd输入nvidia-smi查看自己的cuda版本去官网下载对于的版本来安装

我这边使用的是之前安装的12.6了就不更新了 https://developer.nvidia.com/cuda-downloads

现在对于cuda的cudnn版本https://developer.nvidia.com/cudnn-downloads

需要记下自己的cudnn地址我是默认的在C:\Program Files\NVIDIA\CUDNN\v9.5 需要将对应的bin include lib和对应的版本号下的文件移动到对应的cuda下载地址C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6的bin include lib下这样cudnn就设置好了
rust一般都是下载过c++环境的这边就不安装了 直接进行的编译 E:/opencv/opencv-4.10.0是自己的opencv解压后的包E:/opencv/opencv-4是自己的编译到的地址选择完以后

点击configure 选择自己的vs版本和x64

等done以后搜索OPENCV_EXTRA_MODULES_PATH选择自己解压opencv_contrib的models

再搜索OPENCV_ENABLE_NONFREE勾选

搜索cuda全部勾选

最后再搜索wor勾选

点击configure 中间可能会出现 raw.githubusercontent.com/文件下载出问题的 去找一下github更改host的文件的即可
rust的opencv是调用c++的代码的如果没有py和java等环境需要搜索以后全部取消勾选

Configuring done以后点击generate等待generate done以后点击 open project打开vs

选择release x64 选择CMakeTargets 先ALL_BUILD 生成 然后再INSTALL编译出包

opencv的环境配置参考https://www.cnblogs.com/-CO-/p/18075315
开发流程
我使用的手机的ip摄像头软件进行连接摄像头 需要局域网不行的话需要电脑连接手机热点

创建一个项目 添加opencv cargo add opencv
导入使用的模块

use opencv::{
    core::{self, Mat, Rect, Size, Vector, Point,CV_32F, CV_8UC3}, dnn::{self, DNN_BACKEND_CUDA, DNN_TARGET_CUDA}, highgui::{self, imshow}, prelude::*, videoio::{self, VideoCapture}
};
const SOURCE_WINDOW: &str = "Video Stream";

#[derive(Debug)]
pub struct BoxDetection {
    pub xmin: i32, // bounding box left-top x
    pub ymin: i32, // bounding box left-top y
    pub xmax: i32, // bounding box right-bottom x
    pub ymax: i32, // bounding box right-bottom y
    pub class: i32, // class index
    pub conf: f32  // confidence score
}
#[derive(Debug)]
pub struct Detections {
    pub detections: Vec<BoxDetection>
}
//net获取模型onnx
let mut net = dnn::read_net_from_onnx("mx/yolov8s.onnx").unwrap();
//设置cuda后端
net.set_preferable_backend(DNN_BACKEND_CUDA).unwrap();
net.set_preferable_target(DNN_TARGET_CUDA).unwrap();
//设置窗口id
let _ = highgui::named_window(SOURCE_WINDOW, highgui::WindowFlags::WINDOW_FREERATIO as i32);
//需要修改ip为自己手机ip摄像头的ip
let vide = "http://admin:admin@192.168.254.36:8081/";
//创建视频流
let mut vc = VideoCapture::default().unwrap();
//通过ip打开视频流
let bool = vc.open_file(&vide, videoio::CAP_FFMPEG).unwrap();
//模型id对应合集
let classes_labels: Vec<&str> = vec!["person", "bicycle", "car", "motorbike", "aeroplane", "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", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"];
if bool {
        loop {
            //读取视频流
            if vc.read(&mut Mat::default()).unwrap() {
                // 显示帧
                let mut frame = Mat::default();
                vc.read(&mut frame).unwrap();
                
                let h = frame.rows();
                let w = frame.cols();
                let _max = std::cmp::max(w, h);
                let mut image = Mat::zeros(_max, _max, CV_8UC3).unwrap().to_mat().unwrap();
                frame.copy_to(&mut image).unwrap();
                //
                let  fr =  dnn::blob_from_image(
                    &image,
                    1.0 / 255.0,
                    Size::new(640, 640),
                    core::Scalar::new(0f64,0f64,0f64,0f64),
                    true,
                    false,
                    CV_32F
                ).unwrap();
                net.set_input(&fr, "", 1.0, core::Scalar::default()).unwrap();
                let mut output_blobs: Vector<Mat> = Vector::default();
                let name = net.get_unconnected_out_layers_names().unwrap();
                //进行推理
                net.forward(&mut output_blobs, &name).unwrap();
                let dets = output_blobs.get(0).unwrap();
                let rows = dets.mat_size().get(2).unwrap(); // 8400
                let cols = dets.mat_size().get(1).unwrap(); 
                
                let mut boxes: Vector<Rect> = Vector::default();
                let mut scores: Vector<f32> = Vector::default();
                let mut indices: Vector<i32> = Vector::default();
                let mut class_index_list: Vector<i32> = Vector::default();
                let x_scale = 1;
                let y_scale = 1;

                for row in 0..rows {
                    let mut vec = Vec::new();
                    let mut max_score = 0f32;
                    let mut max_index = 0;
                    for col in 0..cols {
                        let value: f32 = *dets.at_3d::<f32>(0, col, row).unwrap();
                        if col > 3 {
                            if value > max_score {
                                max_score = value;
                                max_index = col - 4;
                            }
                        }
                        vec.push(value);
                    }
                    if max_score > 0.25 {
                        scores.push(max_score);
                        class_index_list.push(max_index as i32);
                        let cx = vec[0];
                        let cy = vec[1];
                        let w = vec[2];
                        let h = vec[3]; 
                        boxes.push( Rect{
                            x: (((cx) - ((w) / 2.0)) * x_scale as f32).round() as i32, 
                            y: (((cy) - ((h) / 2.0)) * y_scale as f32).round() as i32, 
                            width: (w * x_scale as f32).round() as i32, 
                            height: (h * y_scale as f32).round() as i32
                        });
                        indices.push(row as i32);
                    }
                }

                dnn::nms_boxes(&boxes, &scores, 0.5, 0.5, &mut indices, 1.0, 0).unwrap();
    
                let mut final_boxes : Vec<BoxDetection> = Vec::default();
                
                for i in &indices {
                    let class = class_index_list.get(i as usize).unwrap();
                    // println!("{}", class);
                    let rect = boxes.get(i as usize).unwrap();

                    let bbox = BoxDetection{
                        xmin: rect.x,
                        ymin: rect.y,
                        xmax: rect.x + rect.width,
                        ymax: rect.y + rect.height,
                        conf: scores.get(i as usize).unwrap(),
                        class: class
                    };
                    // println!("bbox  111111{:?}", bbox);

                    final_boxes.push(bbox);
                }
                //绘制图像
                for i in 0..final_boxes.len() {
                    let bbox = &final_boxes[i];
                    let rect = Rect::new(bbox.xmin, bbox.ymin, bbox.xmax - bbox.xmin, bbox.ymax - bbox.ymin);
                    let label = classes_labels.get(bbox.class as usize);
                    let label = match label {
                        Some(label) => label,
                        None => "Unknown",
                    };
                    
                    let box_color = core::Scalar::new(0.0, 255.0, 0.0, 0.0);
                    opencv::imgproc::rectangle(&mut image, rect, box_color, 2, opencv::imgproc::LINE_8, 0).unwrap();
                    let _ = opencv::imgproc::put_text_def(&mut image, label, Point{x: bbox.xmax, y: bbox.ymax/ 2}, 1,1.0,box_color);
                }
                 //显示视频
                imshow(SOURCE_WINDOW, &image).unwrap();

                // 等待按键事件
                if highgui::wait_key(10).unwrap() > 0 {
                    break;
                }
                
            } else {
                println!("Error: Unable to read mat.");
                break;
            }
        }
    }

现在推理耗时很久每次需要300ms 正在尝试用多线程去写 有问题请发邮箱至anmingle@163.com

标签:mut,unwrap,max,opencv,let,cuda,rust,bbox
From: https://www.cnblogs.com/yuwenshan/p/18573935

相关文章

  • CudaSPONGE之Python接口
    技术背景在上一篇博客中我们介绍了CudaSPONGE的基本安装和使用方法。为了性能考虑,CudaSPONGE是基于纯CUDAC开发的,但是现在很多轮子都是Python开发的。为兼容更多的框架和平台,CudaSPONGE也提供了相应的PythonAPI,方便Python开发者调用与二次开发。接口逻辑虽然安装和操作的过程......
  • rust学习十二、测试
    测试从来不是一件简单的事情,我本人深有体会!书本作者引用了很重要的话:软件测试是证明bug存在的有效方法,而证明其不存在时则显得令人绝望的不足 (EdsgerW.Dijkstra在其1972年的文章【谦卑的程序员】(“TheHumbleProgrammer”))注:EdsgerW.Dijkstra在1972获得图灵奖 本......
  • CudaSPONGE高性能GPU分子模拟
    技术背景CudaSPONGE是基于CUDAC开发的一款纯GPU分子动力学模拟软件,具有模块化和高性能的特点。官方基本介绍内容如下:分子动力学(MolecularDynamics,MD)模拟是化学、物理学、生物学、材料科学和许多其他领域的有用工具。在过去40年中,人们开发了各种高效的计算算法和MD程序,用......
  • 基于OpenCV视觉库让机械手根据视觉判断物体有无和分类抓取的例程
    项目实例,在一个无人封闭的隔绝场景中,根据视觉判断物件的有无,通过机械手进行物件分类提取,并且返回状态结果;实际的场景是有一个类似采血的固件支架盘,上面很多采血管,采血管帽颜色可能不同,也有可能支架盘上只有空位,没有放置采血管,需要机器操作。图像的大小,支架和物件的位置、大......
  • C/C++ openCV实现实时课室管理系统
    该系统能实时展示教室的使用状态,它通过分析摄像头传回的视频信息来判断教室中是否有课程正在进行,并将这些信息即时更新到教学楼大厅的显示屏上。由于各种不可预见的原因,预先制定的课程表可能无法准确反映教室的实际使用情况,因此这个实时系统提供了更加准确的参考。核心功能:(1)......
  • OpenCV 模板匹配全解析:从单模板到多模板的实战指南
    简介:本文深入探讨OpenCV中的模板匹配技术。详细介绍构建输入图像与模板图像的步骤,包括读取、截取、滤波与存储等操作。剖析cv2.matchTemplate语法及其参数含义,阐述不同匹配方法下结果值的意义。同时讲解cv2.minMaxLoc语法,并通过代码示例展示单模板匹配查找最小值与最......
  • component 'rust-std' for target 'aarch64-linux-android' is up to date
    lipan@ubuntu:~/rustdesk$rustuptargetaddaarch64-linux-androidinfo:component'rust-std'fortarget'aarch64-linux-android'isuptodate出现这种错误:首先设置androidsdk的路径:exportANDROID_NDK_HOME=/home/lipan/android-ndk-r23c然后使用......
  • CUDA:out of memory的解决方法(实测有效)
    一、问题概述    1.问题分析     CUDAoutofmemory问题通常发生在深度学习训练过程中,当GPU的显存不足以容纳模型、输入数据以及中间计算结果时就会触发。这个问题可能由几个因素引起:模型和数据规模:深度学习模型尤其是大型模型,如Transformer或大型CNN,拥有......
  • OpenCV从入门到精通实战(七)——探索图像处理:自定义滤波与OpenCV卷积核
    本文主要介绍如何使用Python和OpenCV库通过卷积操作来应用不同的图像滤波效果。主要分为几个步骤:图像的读取与处理、自定义卷积函数的实现、不同卷积核的应用,以及结果的展示。卷积在图像处理中,卷积是一种重要的操作,它通过将图像与一个小的矩阵(称为卷积核或滤波器)进行运算......
  • Rust中怎样实现链式调用?
    在Rust中,链式调用是通过方法调用返回self或者&self/&mutself来实现的。这种方式允许多个方法在一行内连续调用,非常适合构建器模式或函数式风格的代码。基础知识•self:表示所有权转移。调用后,原来的实例不能再使用。•&self:表示方法可以通过不可变引用调用。......