Skip to content

Commit

Permalink
Fix polygon drawing
Browse files Browse the repository at this point in the history
* Support auto download ort feature
* Fix polygon drawing
  • Loading branch information
jamjamjon authored Sep 2, 2024
1 parent f6755a8 commit 9b969b9
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 33 deletions.
32 changes: 15 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "usls"
version = "0.0.12"
version = "0.0.13"
edition = "2021"
description = "A Rust library integrated with ONNXRuntime, providing a collection of ML models."
repository = "https://github.com/jamjamjon/usls"
Expand All @@ -12,21 +12,7 @@ exclude = ["assets/*", "examples/*", "scripts/*", "runs/*"]
[dependencies]
clap = { version = "4.2.4", features = ["derive"] }
ndarray = { version = "0.16.1", features = ["rayon"] }
ort = { version = "2.0.0-rc.5", default-features = false, features = [
"load-dynamic",
"copy-dylibs",
"half",
"cann",
"rknpu",
"ndarray",
"cuda",
"tensorrt",
"coreml",
"openvino",
"rocm",
"openvino",
"operator-libraries"
]}
ort = { version = "2.0.0-rc.5", default-features = false}
anyhow = { version = "1.0.75" }
regex = { version = "1.5.4" }
rand = { version = "0.8.5" }
Expand All @@ -45,10 +31,22 @@ imageproc = { version = "0.24" }
ab_glyph = "0.2.23"
geo = "0.28.0"
prost = "0.12.4"
human_bytes = "0.4.3"
fast_image_resize = { version = "4.2.1", features = ["image"]}


[features]
default = [
"ort/load-dynamic",
"ort/copy-dylibs",
"ort/half",
"ort/ndarray",
"ort/cuda",
"ort/tensorrt",
"ort/coreml",
"ort/operator-libraries"
]
auto = ["ort/download-binaries"]

[dev-dependencies]
criterion = "0.5.1"

Expand Down
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,27 @@
</details>


## ⛳️ Linking
## ⛳️ ONNXRuntime Linking

- #### For detailed setup instructions, refer to the [ORT documentation](https://ort.pyke.io/setup/linking).
You have two options to link the ONNXRuntime library

- ### Option 1: Manual Linking

- #### For detailed setup instructions, refer to the [ORT documentation](https://ort.pyke.io/setup/linking).

- #### For Linux or macOS Users:
- Download the ONNX Runtime package from the [Releases page](https://github.com/microsoft/onnxruntime/releases).
- Set up the library path by exporting the `ORT_DYLIB_PATH` environment variable:
```shell
export ORT_DYLIB_PATH=/path/to/onnxruntime/lib/libonnxruntime.so.1.19.0
```

- ### Option 2: Automatic Download
Just use `--features auto`
```shell
cargo run -r --example yolo --features auto
```

- #### For Linux or macOS users</summary>
1. Download the ONNXRuntime package from the [Releases page](https://github.com/microsoft/onnxruntime/releases).
2. Set up the library path by exporting the `ORT_DYLIB_PATH` environment variable:
```shell
export ORT_DYLIB_PATH=/path/to/onnxruntime/lib/libonnxruntime.so.1.19.0
```


## 🎈 Quick Start
Expand Down
8 changes: 4 additions & 4 deletions src/core/ort_engine.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use anyhow::Result;
use half::f16;
use human_bytes::human_bytes;
use ndarray::{Array, IxDyn};
use ort::{
ExecutionProvider, Session, SessionBuilder, TensorElementType, TensorRTExecutionProvider,
};
use prost::Message;
use std::collections::HashSet;

use crate::{home_dir, onnx, Device, MinOptMax, Ops, Options, Ts, Xs, CHECK_MARK, CROSS_MARK, X};
use crate::{
home_dir, human_bytes, onnx, Device, MinOptMax, Ops, Options, Ts, Xs, CHECK_MARK, CROSS_MARK, X,
};

/// Ort Tensor Attrs: name, data_type, dims
#[derive(Debug)]
Expand Down Expand Up @@ -169,10 +170,9 @@ impl OrtEngine {

// summary
println!(
"{CHECK_MARK} Backend: ONNXRuntime | OpSet: {} | EP: {:?} | DType: {:?} | Params: {}",
"{CHECK_MARK} Backend: ONNXRuntime | Opset: {} | Device: {:?} | Params: {}",
model_proto.opset_import[0].version,
device,
inputs_attrs.dtypes,
human_bytes(params as f64),
);

Expand Down
3 changes: 2 additions & 1 deletion src/models/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ impl DB {
.unclip(delta, image_width as f64, image_height as f64)
.resample(50)
// .simplify(6e-4)
.convex_hull();
.convex_hull()
.verify();

if let Some(bbox) = polygon.bbox() {
if bbox.height() < self.min_height || bbox.width() < self.min_width {
Expand Down
2 changes: 1 addition & 1 deletion src/models/sam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ impl SAM {
let contours: Vec<imageproc::contours::Contour<i32>> =
imageproc::contours::find_contours_with_threshold(&luma, 0);
for c in contours.iter() {
let polygon = Polygon::default().with_points_imageproc(&c.points);
let polygon = Polygon::default().with_points_imageproc(&c.points).verify();
y_polygons.push(polygon.with_confidence(iou[0]).with_id(id));
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/models/sapiens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ impl Sapiens {
.map(|x| {
let mut polygon = Polygon::default()
.with_id(*i as _)
.with_points_imageproc(&x.points);
.with_points_imageproc(&x.points)
.verify();
if let Some(names_body) = &self.names_body {
polygon = polygon.with_name(&names_body[*i]);
}
Expand Down
3 changes: 2 additions & 1 deletion src/models/yolo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,8 @@ impl Vision for YOLO {
.map(|x| {
let mut polygon = Polygon::default()
.with_id(bbox.id())
.with_points_imageproc(&x.points);
.with_points_imageproc(&x.points)
.verify();
if let Some(name) = bbox.name() {
polygon = polygon.with_name(name);
}
Expand Down
2 changes: 2 additions & 0 deletions src/models/yolop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl YOLOPv2 {
.with_id(0)
.with_points_imageproc(&x.points)
.with_name("Drivable area")
.verify()
})
.max_by(|x, y| x.area().total_cmp(&y.area()))
{
Expand All @@ -152,6 +153,7 @@ impl YOLOPv2 {
.with_id(1)
.with_points_imageproc(&x.points)
.with_name("Lane line")
.verify()
})
.max_by(|x, y| x.area().total_cmp(&y.area()))
{
Expand Down
14 changes: 14 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ pub(crate) const CHECK_MARK: &str = "✅";
pub(crate) const CROSS_MARK: &str = "❌";
pub(crate) const SAFE_CROSS_MARK: &str = "❎";

pub fn human_bytes(size: f64) -> String {
let units = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
let mut size = size;
let mut unit_index = 0;
let k = 1024.;

while size >= k && unit_index < units.len() - 1 {
size /= k;
unit_index += 1;
}

format!("{:.1} {}", size, units[unit_index])
}

pub(crate) fn auto_load<P: AsRef<Path>>(src: P, sub: Option<&str>) -> Result<String> {
let src = src.as_ref();
let p = if src.is_file() {
Expand Down
29 changes: 29 additions & 0 deletions src/ys/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,33 @@ impl Polygon {
self.polygon = geo::Polygon::new(LineString::from(new_points), vec![]);
self
}

pub fn verify(mut self) -> Self {
// Remove duplicates and redundant points
let mut points = self.polygon.exterior().points().collect::<Vec<_>>();
Self::remove_duplicates(&mut points);
self.polygon = geo::Polygon::new(LineString::from(points), vec![]);
self
}

fn remove_duplicates(xs: &mut Vec<Point>) {
// Step 1: Remove elements from the end if they match the first element
if let Some(first) = xs.first() {
let p_1st_x = first.x() as i32;
let p_1st_y = first.y() as i32;
while xs.len() > 1 {
if let Some(last) = xs.last() {
if last.x() as i32 == p_1st_x && last.y() as i32 == p_1st_y {
xs.pop();
} else {
break;
}
}
}
}

// Step 2: Remove duplicates
let mut seen = std::collections::HashSet::new();
xs.retain(|point| seen.insert((point.x() as i32, point.y() as i32)));
}
}

0 comments on commit 9b969b9

Please sign in to comment.