使用 Rust 和 OpenCV 进行物体检测
我们将利用 Rust 的 opencv 库来封装 OpenCV 的功能,加载 YOLOv3 模型并进行图像的物体检测。YOLO(You Only Look Once)是一个非常高效的实时目标检测模型,能够在图片中快速定位出物体并标注出边界框。
环境准备
- 安装 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
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 绘制检测到的物体框,并标注出类别和置信度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异