使用 Rust 调用 YOLOv3 模型进行物体检测

  1. 环境准备
    在 Rust 中,我们可以通过调用 C 库或使用绑定来加载 YOLOv3 模型。为了简单起见,我们将使用 Rust 的 opencv crate 进行图像处理,并借助 YOLOv3 模型进行推理。

安装依赖:
Rust 环境: 首先,确保你已经安装了 Rust 开发环境,使用以下命令安装 Rust:

bash

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装 OpenCV: 在 Rust 中使用 OpenCV 需要依赖 OpenCV 库,因此你需要先安装它。具体方法可以参考 OpenCV 安装文档。

在 Ubuntu 中安装:

bash

sudo apt-get install libopencv-dev
Rust 的 opencv crate: 使用 OpenCV 的 Rust 绑定来进行图像处理,首先需要在项目中添加 opencv crate。

在 Cargo.toml 中添加:

toml

[dependencies]
opencv = "0.67"
2. 编写 Rust 程序
接下来我们编写一个简单的 Rust 程序来进行物体检测。我们使用 YOLOv3 模型进行推理,并使用 OpenCV 来加载和处理图像。

Rust 程序 (yolo_detect.rs)
rust

use opencv::{
core::{Mat, Scalar, Size},
dnn::{read_net_from_darknet, Net},
highgui::{imshow, waitKey},
imgcodecs::imread,
imgproc::{resize, rectangle},
prelude:😗,
objdetect::CascadeClassifier,
types::{VectorOfRect, VectorOfString},
};

fn main() -> opencv::Result<()> {
// YOLO 模型配置和权重文件
let model_cfg = "cfg/yolov3.cfg";
let model_weights = "yolov3.weights";
let class_file = "cfg/coco.names";

// 读取类别名称
let classes = load_classes(class_file)?;

// 加载 YOLO 模型
let net = read_net_from_darknet(model_cfg, model_weights)?;

// 加载图片
let image = imread("test.jpg", opencv::imgcodecs::IMREAD_COLOR)?;

// 检测物体
detect_objects(&image, &net, &classes)?;

// 显示结果
imshow("YOLO Object Detection", &image)?;
waitKey(0)?;

Ok(())

}

// 加载类别名称
fn load_classes(class_file: &str) -> opencv::Result<Vec> {
let mut classes = Vec::new();
let file = std::fs::File::open(class_file)?;
let reader = std::io::BufReader::new(file);

for line in reader.lines() {
    let class = line?;
    classes.push(class);
}

Ok(classes)

}

// 物体检测函数
fn detect_objects(image: &Mat, net: &Net, classes: &[String]) -> opencv::Result<()> {
// 将图像转换为 Blob
let mut blob = Mat::default();
dnn::blob_from_image(
&image,
&mut blob,
1.0 / 255.0,
Size::new(416, 416),
Scalar::default(),
true,
false,
)?;

// 将 Blob 设置为网络输入
net.set_input(&blob, "", 1.0, Size::new(416, 416), Scalar::default(), false, false)?;

// 获取网络的输出层
let output_layers = net.get_unconnected_out_layers_names()?;
let mut outs: VectorOfMat = VectorOfMat::new();
net.forward_into(&mut outs, &output_layers)?;

// 解析 YOLO 输出
for i in 0..outs.len() {
    let data = outs.get(i)?;
    let rows = data.rows();
    let cols = data.cols();

    for r in 0..rows {
        let row = data.row(r)?;
        let mut class_id = -1;
        let mut max_prob = 0.0;
        for c in 5..cols {
            let prob = row.at_2d::<f32>(0, c)?;
            if prob > max_prob {
                max_prob = prob;
                class_id = (c - 5) as i32;
            }
        }

        if max_prob > 0.5 {
            // 获取框的坐标
            let x = (row.at_2d::<f32>(0, 0)? * image.cols() as f32) as i32;
            let y = (row.at_2d::<f32>(0, 1)? * image.rows() as f32) as i32;
            let w = (row.at_2d::<f32>(0, 2)? * image.cols() as f32) as i32;
            let h = (row.at_2d::<f32>(0, 3)? * image.rows() as f32) as i32;

            // 绘制矩形框
            rectangle(image, opencv::core::Point::new(x, y), opencv::core::Point::new(x + w, y + h), Scalar::new(0.0, 255.0, 0.0, 0.0), 2)?;

            // 在框内写上类别名称
            let label = &classes[class_id as usize];
            opencv::imgproc::put_text(
                image,
                label,
                opencv::core::Point::new(x, y - 5),
                opencv::imgproc::FONT_HERSHEY_SIMPLEX,
                0.5,
                Scalar::new(0.0, 255.0, 0.0, 0.0),
                2,
                opencv::imgproc::LINE_AA,
                false,
            )?;
        }
    }
}

Ok(())

}
3. 编译和运行

  1. 添加依赖:
    在 Cargo.toml 中,添加以下依赖项:

toml

[dependencies]
opencv = "0.67"
2. 编译和运行:
编译程序:

在项目目录下,使用 cargo 编译:

bash

cargo build --release
运行程序:

编译完成后,可以使用以下命令运行:更多内容访问ttocr.com或联系1436423940

bash

cargo run
4. 程序解释
加载 YOLO 模型: 使用 opencv::dnn::read_net_from_darknet 函数加载 YOLOv3 的配置文件和权重文件。
读取图像: 使用 imread 函数加载输入图像。
物体检测: 使用 YOLOv3 模型进行推理,解析输出结果,并绘制边界框和标签。
显示图像: 使用 imshow 显示处理后的图像,检测到的物体会在图像中用绿色框标出。

posted @   ttocr、com  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示