#onnx #object-detection #yolo #opencv #computer-vision

yolo_detector

YOLO object detection wrapper for OpenCV and ONNX in Rust

11 releases (5 breaking)

new 0.6.0 May 6, 2025
0.5.0 May 6, 2025
0.4.2 May 5, 2025
0.3.1 May 5, 2025
0.1.1 May 3, 2025

#575 in Machine learning

Download history 322/week @ 2025-04-29

322 downloads per month

MIT/Apache

38KB
581 lines

yolo_detector

Pre-launch installation

sudo apt update -y
sudo apt install libopencv-dev pkg-config build-essential cmake libgtk-3-dev libcanberra-gtk3-module llvm-dev libclang-dev clang

Converting the model to onnx

This library uses tipo models.onnx

pip install ultralytics

Download the model you need.

https://huggingface.co/Ultralytics/YOLOv8/tree/main
yolo export model=yolov8m.pt format=onnx opset=12 dynamic=True

You also need to download the class file (coco.names)

https://github.com/pjreddie/darknet/blob/master/data/coco.names

Sample code

Detection

use opencv::{highgui, imgcodecs};
use yolo_detector::YoloDetector;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m.onnx", "coco.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, original_size) = detector.detect(&mat.clone())?;

    let result = detector.draw_detections(mat.clone(), detections, 0.5, original_size)?;

    highgui::imshow("YOLOv8 Video", &result)?;
    highgui::wait_key(0)?;

    Ok(())
}
use yolo_detector::YoloDetector;
use opencv::imgcodecs;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m.onnx", "coco.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, original_size) = detector.detect(&mat.clone())?;

    let detections_with_classes =
        detector.get_detections_with_classes(detections, 0.5, original_size);

    for (class_name, rect) in detections_with_classes {
        println!("Class: {}, Position: {:?}", class_name, rect);
    }

    Ok(())

//returns values
//Class: person, Position: Rect_ { x: 74, y: 875, width: 41, height: 112 }
//Class: car, Position: Rect_ { x: 184, y: 899, width: 499, height: 141 }
}

Weights

use opencv::{highgui, imgcodecs};
use yolo_detector::YoloDetectorWeights;

fn main() -> opencv::Result<()> {
    let mut detector =
        YoloDetectorWeights::new("yolov4.weights", "yolov4.cfg", "coco.names").unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (class_ids, confidences, boxes) = detector.detect(&mat.clone(), 0.7, 0.4)?;

    let result = detector.draw_detections(&mut mat.clone(), class_ids, confidences, boxes)?;

    highgui::imshow("YOLOv8 Video", &result)?;
    highgui::wait_key(0)?;

    Ok(())
}

OBB

DOTAv1.names

plane
ship
storage tank
baseball diamond
tennis court
basketball court
ground track field
harbor
bridge
large vehicle
small vehicle
helicopter
roundabout
soccer ball field
swimming pool
use opencv::{highgui, imgcodecs};
use yolo_detector::YoloDetector;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m-obb.onnx", "DOTAv1.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, original_size) = detector.detect(&mat.clone())?;

    let result = detector.draw_detections_obb(mat.clone(), detections, 0.5, original_size)?;

    highgui::imshow("YOLOv8 Video", &result)?;
    highgui::wait_key(0)?;

    Ok(())
}
use yolo_detector::YoloDetector;
use opencv::imgcodecs;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m-obb.onnx", "DOTAv1.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, original_size) = detector.detect(&mat.clone())?;

    let detections_with_classes =
        detector.get_detections_with_classes_obb(detections, 0.5, original_size);

    for (class_name, rect, rotation_angle) in detections_with_classes {
        println!(
            "Class: {}, Position: {:?}, Rotation Angle: {}°",
            class_name, rect, rotation_angle
        );
    }

    Ok(())

//returns values
// Class: ship, Position: Rect_ { x: 110, y: 738, width: 84, height: 25 }, Rotation Angle: 77.65746°
// Class: ship, Position: Rect_ { x: 576, y: 733, width: 65, height: 23 }, Rotation Angle: 56.169453°
}

Classification

ImageNet.names

https://github.com/Elieren/yolo_detector/blob/main/ImageNet.names
use yolo_detector::YoloDetector;
use opencv::imgcodecs;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m-cls.onnx", "ImageNet.names", 224).unwrap();

    let mat = imgcodecs::imread("zebra.jpg", imgcodecs::IMREAD_COLOR)?;

    let result = detector.classify(&mat.clone(), 0.5)?;

    for (class_name, score) in result {
        println!("Class: {}, Score: {}", class_name, score);
    }
    
    Ok(())

//returns values
// Class: zebra, Score: 0.99995613
}

Segmentation

use opencv::{highgui, imgcodecs};
use yolo_detector::YoloDetector;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m-seg.onnx", "coco.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, mask, original_size) = detector.detect_mask(&mat.clone())?;

    let result = detector.draw_detections_masked(mat.clone(), detections, mask, original_size, 0.5)?;

    highgui::imshow("YOLOv8 Video", &result)?;
    highgui::wait_key(0)?;

    Ok(())
}
use yolo_detector::YoloDetector;
use opencv::imgcodecs;

fn main() -> opencv::Result<()> {
    let detector = YoloDetector::new("yolov8m-seg.onnx", "coco.names", 640).unwrap();

    let mat = imgcodecs::imread("image.jpg", imgcodecs::IMREAD_COLOR)?;

    let (detections, mask, original_size) = detector.detect_mask(&mat.clone())?;

    let detections =
        detector.get_detections_with_classes_masks(detections, mask, 0.5, original_size)?;

    // Обработка результатов
    for (class_name, rect, conf, mask) in detections {
        println!(
            "Class: {}, Confidence: {}, BoundingBox: {:?}, Mask: {:?}",
            class_name, conf, rect, mask
        );
    }

    Ok(())
//returns values
// Class: car, Confidence: 0.92939186, BoundingBox: Rect_ { x: 185, y: 900, width: 500, height: 142 }, Mask: Mat { type: "CV_8UC1", flags: "0x42FF4000 (continuous)", channels: 1, depth: "CV_8U", dims: 2, size: Size_ { width: 1680, height: 1116 }, rows: 1116, cols: 1680, elem_size: 1, elem_size1: 1, total: 1874880, is_continuous: true, is_submatrix: false, data: <element count is higher than threshold: 1000> }
// Class: person, Confidence: 0.7530618, BoundingBox: Rect_ { x: 1091, y: 860, width: 78, height: 133 }, Mask: Mat { type: "CV_8UC1", flags: "0x42FF4000 (continuous)", channels: 1, depth: "CV_8U", dims: 2, size: Size_ { width: 1680, height: 1116 }, rows: 1116, cols: 1680, elem_size: 1, elem_size1: 1, total: 1874880, is_continuous: true, is_submatrix: false, data: <element count is higher than threshold: 1000> }
}

Project roadmap

  • Detection
  • Weights
  • OBB
  • Classification
  • Pose
  • Segmentation

Author

Developed by Elieren https://github.com/Elieren .

When using the library, keep an indication of the author.

Dependencies

~5–30MB
~381K SLoC