使用 Rust 和 OpenCV 进行物体检测

我们将利用 Rust 的 opencv 库来封装 OpenCV 的功能,加载 YOLOv3 模型并进行图像的物体检测。YOLO(You Only Look Once)是一个非常高效的实时目标检测模型,能够在图片中快速定位出物体并标注出边界框。

环境准备

  1. 安装 Rust
    如果你还没有安装 Rust,可以使用下面的命令进行安装:

bash

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
然后通过以下命令更新 Rust:

bash

rustup update
2. 安装 OpenCV
为了在 Rust 中使用 OpenCV,我们需要安装 OpenCV 库,并通过 opencv crate 来访问它。首先,确保你已经安装了 OpenCV(可以参考 OpenCV 官方安装文档 进行安装)。

在 Ubuntu 上,可以使用以下命令安装 OpenCV:

bash

sudo apt update
sudo apt install libopencv-dev
3. 设置 Cargo.toml
在项目的 Cargo.toml 文件中,添加 opencv 依赖项:

toml

[dependencies]
opencv = "0.67"
然后运行以下命令来下载依赖:

bash

cargo build
4. 下载 YOLO 模型和配置文件
下载 YOLOv3 配置文件:yolov3.cfg
下载 YOLOv3 权重文件:yolov3.weights
代码实现
下面是一个用 Rust 和 OpenCV 实现 YOLOv3 物体检测的示例。

rust

extern crate opencv;

use opencv::{
core::{Mat, Scalar, Size},
dnn::{read_net, Net},
highgui::{imshow, wait_key, named_window},
imgcodecs::imread,
imgproc::{cvt_color, COLOR_BGR2RGB},
prelude:😗,
types::{VectorOfMat, VectorOfString},
};

const CONFIDENCE_THRESHOLD: f32 = 0.5;
const NMS_THRESHOLD: f32 = 0.4;
const INPUT_WIDTH: i32 = 416;
const INPUT_HEIGHT: i32 = 416;

fn main() -> opencv::Result<()> {
// 加载 YOLO 模型
let model_path = "yolov3.weights";
let config_path = "yolov3.cfg";
let net = read_net(config_path, model_path)?;

// 加载类别标签
let class_names = vec![
    "person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", "boat", "traffic light",
];

// 加载输入图像
let image = imread("input_image.jpg", opencv::imgcodecs::IMREAD_COLOR)?;
let mut blob = Mat::default();
cvt_color(&image, &mut blob, COLOR_BGR2RGB, 0)?;
let blob = dnn::blob_from_image(&image, 1.0 / 255.0, Size::new(INPUT_WIDTH, INPUT_HEIGHT), Scalar::new(0.0, 0.0, 0.0, 0.0), true, false)?;

// 将输入数据传递给网络
net.set_input(&blob, "", 1.0, Scalar::new(0.0, 0.0, 0.0, 0.0));

// 获取网络输出层
let output_layer_names = net.get_unconnected_out_layers_names()?;

// 前向推理
let mut outs = VectorOfMat::new();
net.forward(&mut outs, &output_layer_names)?;

// 后处理,提取物体框
let (boxes, confidences, class_ids) = post_process(&image, &outs);

// 对物体框进行非最大抑制
let indices = dnn::nms_boxes(&boxes, &confidences, CONFIDENCE_THRESHOLD, NMS_THRESHOLD)?;

// 绘制物体框
for i in 0..indices.len() {
    let box_ = boxes[indices[i] as usize];
    let label = format!(
        "{}: {:.2}%",
        class_names[class_ids[indices[i] as usize] as usize],
        confidences[indices[i] as usize] * 100.0
    );

    opencv::imgproc::rectangle(
        &mut image,
        box_,
        Scalar::new(0.0, 255.0, 0.0, 0.0),
        2,
        8,
        0,
    )?;

    opencv::imgproc::put_text(
        &mut image,
        &label,
        opencv::core::Point::new(box_.x, box_.y - 10),
        opencv::imgproc::FONT_HERSHEY_SIMPLEX,
        0.5,
        Scalar::new(0.0, 255.0, 0.0, 0.0),
        1,
        8,
        false,
    )?;
}

// 显示结果
named_window("Object Detection", opencv::highgui::WINDOW_NORMAL)?;
imshow("Object Detection", &image)?;
wait_key(0)?;

Ok(())

}

// 后处理:提取物体框、置信度和类别
fn post_process(image: &Mat, outs: &VectorOfMat) -> (Veccv::core::Rect, Vec, Vec) {
let mut boxes = Vec::new();
let mut confidences = Vec::new();
let mut class_ids = Vec::new();

for i in 0..outs.len() {
    let mat = outs.get(i)?.clone();
    let mut data = mat.data()?;
    let rows = mat.rows();
    let cols = mat.cols();

    for r in 0..rows {
        let score = &data[(r * cols)..];
        let confidence = score[5];

        if confidence > CONFIDENCE_THRESHOLD {
            let center_x = (score[0] * image.cols() as f32) as i32;
            let center_y = (score[1] * image.rows() as f32) as i32;
            let width = (score[2] * image.cols() as f32) as i32;
            let height = (score[3] * image.rows() as f32) as i32;
            let box_ = cv::core::Rect::new(center_x - width / 2, center_y - height / 2, width, height);

            boxes.push(box_);
            confidences.push(confidence);
            class_ids.push(score[4] as i32);
        }
    }
}更多内容访问ttocr.com或联系1436423940

(boxes, confidences, class_ids)

}
代码解析
加载 YOLO 模型和配置文件: 使用 opencv::dnn::read_net() 函数加载 YOLO 配置文件和权重文件,形成一个深度神经网络对象。

图像预处理: 通过 opencv::dnn::blob_from_image() 将输入图像转换为 YOLO 模型需要的格式。

前向推理: 使用 net.forward() 对输入图像进行前向推理,获取物体检测的结果。

后处理: 提取预测结果,包括物体框、置信度和类别,并进行非最大抑制(NMS)。

绘制结果: 使用 OpenCV 绘制检测到的物体框,并标注出类别和置信度。

posted @   ttocr、com  阅读(123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示