yolo_detector 0.5.0

YOLO object detection wrapper for OpenCV and ONNX in Rust
Documentation

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.