#opencv #computer-vision #yolo #neural-network #object-detection #networking #yolo-v8

od_opencv

Rust编程语言中针对OpenCV生态系统中YOLO神经网络对象检测的实用工具

6个版本

0.1.6 2024年5月10日
0.1.5 2023年12月26日
0.1.4 2023年11月27日

#220多媒体

Download history 115/week @ 2024-05-06 41/week @ 2024-05-13 16/week @ 2024-05-20 6/week @ 2024-06-03 8/week @ 2024-06-10 1/week @ 2024-06-17 57/week @ 2024-06-24 8/week @ 2024-07-22 15/week @ 2024-07-29 48/week @ 2024-08-05 3/week @ 2024-08-12

每月下载量 74

MIT 许可证

57KB
535

Package

Rust编程语言中针对OpenCV生态系统中YOLO神经网络对象检测的实用工具

此crate提供了一些基本的结构和方法,用于通过OpenCV的DNN模块解决对象检测任务。目前实现和测试的工作流程

网络类型 Darknet ONNX
YOLO v3 tiny ⚠️ (需要测试)
YOLO v4 tiny ⚠️ (需要测试)
YOLO v7 tiny ⚠️ (需要测试)
YOLO v3 ⚠️ (需要测试)
YOLO v4 ⚠️ (需要测试)
YOLO v7 ⚠️ (需要测试)
YOLO v8 n ❌ (可能吗?)
YOLO v8 s ❌ (可能吗?)
YOLO v8 m ❌ (可能吗?)
YOLO v8 l ❌ (可能吗?)
YOLO v8 x ❌ (可能吗?)

目录

关于

- 为什么?

嗯,我在我的私人和公开项目中都尝试过一些样板代码(模型初始化、后处理函数等)。

- 何时有用?

嗯,在某些情况下,您可能需要这个crate

  • 您需要将YOLO作为您的神经网络基础;
  • 您不想使用Pytorch / Tensorflow / Jax或任何其他DL/ML框架(将来可能会在这个crate中使用纯ONNX,而不使用OpenCV功能 - 欢迎PR);
  • 您需要使用OpenCV的DNN模块来初始化神经网络;

- 为什么没有YOLOv5?

我认为v8和v5版本之间的后处理功能有所不同。我需要更多时间来调查如何确切地使其工作。

- 测试了哪个OpenCV版本?

我已经与v4.7.0一起测试了它。Rust绑定版本:v0.66.0

- 包装结构是否线程安全?

我不确定它是否打算在多个线程中使用(欢迎PR)。但如果你想给提供的结构提供“异步”访问,我认为你应该使用一些队列机制。

先决条件

使用方法

有一些示例,但我会一步步引导你。

  1. 将此crate添加到你的Cargo.toml中。

    cargo add od_opencv
    
  2. 也将OpenCV的绑定crate添加到Cargo.toml中。

    # I'm using 0.66 version
    cargo add opencv@0.66
    
  3. 下载预训练模型或使用你自己的神经网络。

    我将使用先决条件部分中的预训练权重。

  4. 在您的main.rs文件中导入"基本"OpenCV功能。

    use opencv::{
        core::{Scalar, Vector},
        imgcodecs::imread,
        imgcodecs::imwrite,
        imgproc::LINE_4,
        imgproc::rectangle,
        dnn::DNN_BACKEND_CUDA, // I will utilize my GPU to perform faster inference. Your way may vary
        dnn::DNN_TARGET_CUDA,
    };
    
  5. 导入crate。

    use od_opencv::{
        model_format::ModelFormat,
        // I'll use YOLOv8 by Ultralytics.
        // If you prefer traditional YOLO, then import it as:
        // model_classic::ModelYOLOClassic
        model_ultralytics::ModelUltralyticsV8
    };
    
  6. 准备模型。

    // Define classes (in this case we consider 80 COCO labels)
    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"];
    
    // Define format for OpenCV's DNN module
    let mf = ModelFormat::ONNX;
    
    // Define model's input size
    let net_width = 640;
    let net_height = 640;
    
    // Initialize optional filters.
    // E.g.: if you do want to find only dogs and cats and you can't re-train neural network, 
    // then you can just place `vec![15, 16]` to filter dogs and cats (15 - index of `cat` in class labels, 16 - `dog`)
    // let class_filters: Vec<usize> = vec![15, 16];
    let class_filters: Vec<usize> = vec![];
    
    // Initialize model itself
    let mut model = ModelUltralyticsV8::new_from_file("pretrained/yolov8n.onnx", None, (net_width, net_height), mf, DNN_BACKEND_CUDA, DNN_TARGET_CUDA, class_filters).unwrap();
    
    // Read image into the OpenCV's Mat object
    // Define it as mutable since we are going to put bounding boxes onto it.
    let mut frame = imread("images/dog.jpg", 1).unwrap();
    
    // Feed forward image through the model
    let (bboxes, class_ids, confidences) = model.forward(&frame, 0.25, 0.4).unwrap();
    
    // Process results
    for (i, bbox) in bboxes.iter().enumerate() {
        // Place bounding boxes onto the image
        rectangle(&mut frame, *bbox, Scalar::from((0.0, 255.0, 0.0)), 2, LINE_4, 0).unwrap();
        // Debug output to stdin
        println!("Class: {}", classes_labels[class_ids[i]]);
        println!("\tBounding box: {:?}", bbox);
        println!("\tConfidences: {}", confidences[i]);
    }
    
    // Finally save the updated image to the file system
    imwrite("images/dog_yolov8_n.jpg", &frame, &Vector::new()).unwrap();
    
  7. 你现在可以开始了。

    cargo run
    
  8. 如果出现问题,请随时创建一个问题

参考

依赖关系

~2–26MB
~343K SLoC