Fix polygon drawing
* Support auto download ort feature * Fix polygon drawing
This commit is contained in:
parent
f6755a8be4
commit
9b969b9203
32
Cargo.toml
32
Cargo.toml
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "usls"
|
name = "usls"
|
||||||
version = "0.0.12"
|
version = "0.0.13"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A Rust library integrated with ONNXRuntime, providing a collection of ML models."
|
description = "A Rust library integrated with ONNXRuntime, providing a collection of ML models."
|
||||||
repository = "https://github.com/jamjamjon/usls"
|
repository = "https://github.com/jamjamjon/usls"
|
||||||
|
|
@ -12,21 +12,7 @@ exclude = ["assets/*", "examples/*", "scripts/*", "runs/*"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.2.4", features = ["derive"] }
|
clap = { version = "4.2.4", features = ["derive"] }
|
||||||
ndarray = { version = "0.16.1", features = ["rayon"] }
|
ndarray = { version = "0.16.1", features = ["rayon"] }
|
||||||
ort = { version = "2.0.0-rc.5", default-features = false, features = [
|
ort = { version = "2.0.0-rc.5", default-features = false}
|
||||||
"load-dynamic",
|
|
||||||
"copy-dylibs",
|
|
||||||
"half",
|
|
||||||
"cann",
|
|
||||||
"rknpu",
|
|
||||||
"ndarray",
|
|
||||||
"cuda",
|
|
||||||
"tensorrt",
|
|
||||||
"coreml",
|
|
||||||
"openvino",
|
|
||||||
"rocm",
|
|
||||||
"openvino",
|
|
||||||
"operator-libraries"
|
|
||||||
]}
|
|
||||||
anyhow = { version = "1.0.75" }
|
anyhow = { version = "1.0.75" }
|
||||||
regex = { version = "1.5.4" }
|
regex = { version = "1.5.4" }
|
||||||
rand = { version = "0.8.5" }
|
rand = { version = "0.8.5" }
|
||||||
|
|
@ -45,10 +31,22 @@ imageproc = { version = "0.24" }
|
||||||
ab_glyph = "0.2.23"
|
ab_glyph = "0.2.23"
|
||||||
geo = "0.28.0"
|
geo = "0.28.0"
|
||||||
prost = "0.12.4"
|
prost = "0.12.4"
|
||||||
human_bytes = "0.4.3"
|
|
||||||
fast_image_resize = { version = "4.2.1", features = ["image"]}
|
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]
|
[dev-dependencies]
|
||||||
criterion = "0.5.1"
|
criterion = "0.5.1"
|
||||||
|
|
||||||
|
|
|
||||||
27
README.md
27
README.md
|
|
@ -75,16 +75,27 @@
|
||||||
</details>
|
</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
|
## 🎈 Quick Start
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use half::f16;
|
use half::f16;
|
||||||
use human_bytes::human_bytes;
|
|
||||||
use ndarray::{Array, IxDyn};
|
use ndarray::{Array, IxDyn};
|
||||||
use ort::{
|
use ort::{
|
||||||
ExecutionProvider, Session, SessionBuilder, TensorElementType, TensorRTExecutionProvider,
|
ExecutionProvider, Session, SessionBuilder, TensorElementType, TensorRTExecutionProvider,
|
||||||
|
|
@ -8,7 +7,9 @@ use ort::{
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use std::collections::HashSet;
|
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
|
/// Ort Tensor Attrs: name, data_type, dims
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -169,10 +170,9 @@ impl OrtEngine {
|
||||||
|
|
||||||
// summary
|
// summary
|
||||||
println!(
|
println!(
|
||||||
"{CHECK_MARK} Backend: ONNXRuntime | OpSet: {} | EP: {:?} | DType: {:?} | Params: {}",
|
"{CHECK_MARK} Backend: ONNXRuntime | Opset: {} | Device: {:?} | Params: {}",
|
||||||
model_proto.opset_import[0].version,
|
model_proto.opset_import[0].version,
|
||||||
device,
|
device,
|
||||||
inputs_attrs.dtypes,
|
|
||||||
human_bytes(params as f64),
|
human_bytes(params as f64),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,8 @@ impl DB {
|
||||||
.unclip(delta, image_width as f64, image_height as f64)
|
.unclip(delta, image_width as f64, image_height as f64)
|
||||||
.resample(50)
|
.resample(50)
|
||||||
// .simplify(6e-4)
|
// .simplify(6e-4)
|
||||||
.convex_hull();
|
.convex_hull()
|
||||||
|
.verify();
|
||||||
|
|
||||||
if let Some(bbox) = polygon.bbox() {
|
if let Some(bbox) = polygon.bbox() {
|
||||||
if bbox.height() < self.min_height || bbox.width() < self.min_width {
|
if bbox.height() < self.min_height || bbox.width() < self.min_width {
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ impl SAM {
|
||||||
let contours: Vec<imageproc::contours::Contour<i32>> =
|
let contours: Vec<imageproc::contours::Contour<i32>> =
|
||||||
imageproc::contours::find_contours_with_threshold(&luma, 0);
|
imageproc::contours::find_contours_with_threshold(&luma, 0);
|
||||||
for c in contours.iter() {
|
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));
|
y_polygons.push(polygon.with_confidence(iou[0]).with_id(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,8 @@ impl Sapiens {
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
let mut polygon = Polygon::default()
|
let mut polygon = Polygon::default()
|
||||||
.with_id(*i as _)
|
.with_id(*i as _)
|
||||||
.with_points_imageproc(&x.points);
|
.with_points_imageproc(&x.points)
|
||||||
|
.verify();
|
||||||
if let Some(names_body) = &self.names_body {
|
if let Some(names_body) = &self.names_body {
|
||||||
polygon = polygon.with_name(&names_body[*i]);
|
polygon = polygon.with_name(&names_body[*i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -463,7 +463,8 @@ impl Vision for YOLO {
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
let mut polygon = Polygon::default()
|
let mut polygon = Polygon::default()
|
||||||
.with_id(bbox.id())
|
.with_id(bbox.id())
|
||||||
.with_points_imageproc(&x.points);
|
.with_points_imageproc(&x.points)
|
||||||
|
.verify();
|
||||||
if let Some(name) = bbox.name() {
|
if let Some(name) = bbox.name() {
|
||||||
polygon = polygon.with_name(name);
|
polygon = polygon.with_name(name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ impl YOLOPv2 {
|
||||||
.with_id(0)
|
.with_id(0)
|
||||||
.with_points_imageproc(&x.points)
|
.with_points_imageproc(&x.points)
|
||||||
.with_name("Drivable area")
|
.with_name("Drivable area")
|
||||||
|
.verify()
|
||||||
})
|
})
|
||||||
.max_by(|x, y| x.area().total_cmp(&y.area()))
|
.max_by(|x, y| x.area().total_cmp(&y.area()))
|
||||||
{
|
{
|
||||||
|
|
@ -152,6 +153,7 @@ impl YOLOPv2 {
|
||||||
.with_id(1)
|
.with_id(1)
|
||||||
.with_points_imageproc(&x.points)
|
.with_points_imageproc(&x.points)
|
||||||
.with_name("Lane line")
|
.with_name("Lane line")
|
||||||
|
.verify()
|
||||||
})
|
})
|
||||||
.max_by(|x, y| x.area().total_cmp(&y.area()))
|
.max_by(|x, y| x.area().total_cmp(&y.area()))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,20 @@ pub(crate) const CHECK_MARK: &str = "✅";
|
||||||
pub(crate) const CROSS_MARK: &str = "❌";
|
pub(crate) const CROSS_MARK: &str = "❌";
|
||||||
pub(crate) const SAFE_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> {
|
pub(crate) fn auto_load<P: AsRef<Path>>(src: P, sub: Option<&str>) -> Result<String> {
|
||||||
let src = src.as_ref();
|
let src = src.as_ref();
|
||||||
let p = if src.is_file() {
|
let p = if src.is_file() {
|
||||||
|
|
|
||||||
|
|
@ -214,4 +214,33 @@ impl Polygon {
|
||||||
self.polygon = geo::Polygon::new(LineString::from(new_points), vec![]);
|
self.polygon = geo::Polygon::new(LineString::from(new_points), vec![]);
|
||||||
self
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue