init
This commit is contained in:
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "line_detection_ros2"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 2 # Maximum optimization for release
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
image = "0.25.6"
|
||||||
|
show-image = "0.14.1"
|
||||||
|
rand = "0.9.1"
|
||||||
|
rayon = "1.10.0"
|
||||||
|
linfa = "0.7.1"
|
||||||
|
linfa-clustering = "0.7.1"
|
||||||
|
ndarray = "0.16.1"
|
||||||
BIN
images/lane_detection_loop_20.png
Normal file
BIN
images/lane_detection_loop_20.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
BIN
images/lane_detection_loop_60.png
Normal file
BIN
images/lane_detection_loop_60.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
BIN
images/lane_detection_loop_80.png
Normal file
BIN
images/lane_detection_loop_80.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 274 KiB |
63
src/main.rs
Normal file
63
src/main.rs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
use linfa::traits::Transformer;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use image::{DynamicImage, ImageReader, Rgb};
|
||||||
|
use linfa_clustering::Dbscan;
|
||||||
|
use rand::{Rng};
|
||||||
|
use show_image::{create_window, ImageInfo, ImageView, PixelFormat};
|
||||||
|
use rayon::prelude::*;
|
||||||
|
use ndarray::{Array2, Axis};
|
||||||
|
|
||||||
|
use linfa::prelude::*;
|
||||||
|
// We'll build our dataset on our own using ndarray and rand
|
||||||
|
use ndarray::prelude::*;
|
||||||
|
|
||||||
|
|
||||||
|
fn extract_highlights(image: &Vec<u8>, width: u32, threshold: u8, downsample: f64) -> Array2<u32> {
|
||||||
|
let max_rng = (u32::MAX as f64 * downsample) as u32;
|
||||||
|
let poi = image
|
||||||
|
.par_iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(move |(_, pixel)| pixel > &&threshold)
|
||||||
|
.filter(move |_| {
|
||||||
|
let mut rng = rand::rng();
|
||||||
|
rng.random::<u32>() < max_rng
|
||||||
|
})
|
||||||
|
.map(move |(i, _)| [ i as u32 % width, i as u32 / width ]);
|
||||||
|
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
vec.par_extend(poi);
|
||||||
|
Array2::from(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[show_image::main]
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let img: DynamicImage = ImageReader::open("./images/lane_detection_loop_80.png").unwrap().decode().unwrap();
|
||||||
|
let width: u32 = img.width();
|
||||||
|
let height: u32 = img.height();
|
||||||
|
let img_data: Vec<u8> = img.clone().into_bytes();
|
||||||
|
|
||||||
|
let window = create_window("image", Default::default()).unwrap();
|
||||||
|
let mut t: VecDeque<Duration> = VecDeque::with_capacity(25);
|
||||||
|
loop {
|
||||||
|
let start = Instant::now();
|
||||||
|
let poi = extract_highlights(&img_data, width, 196, 1.0);
|
||||||
|
|
||||||
|
let mut rgb_image = img.to_rgb8();
|
||||||
|
|
||||||
|
|
||||||
|
poi.outer_iter().for_each(|pixel| {
|
||||||
|
rgb_image.put_pixel(pixel[0], pixel[1], Rgb([255, 0, 0]))
|
||||||
|
});
|
||||||
|
|
||||||
|
let image = ImageView::new(ImageInfo::new(PixelFormat::Rgb8, width, height), rgb_image.iter().as_slice());
|
||||||
|
window.set_image("camera", image).unwrap();
|
||||||
|
|
||||||
|
if t.len() == 25 {
|
||||||
|
t.pop_front();
|
||||||
|
}
|
||||||
|
t.push_back(Instant::now() - start);
|
||||||
|
println!("Avg: {} FPS", 1.0 / (t.iter().map(|d| d.as_secs_f64()).sum::<f64>() / t.len() as f64));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user