clustering
This commit is contained in:
@@ -11,6 +11,4 @@ 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"
|
||||
hdbscan = "0.10.0"
|
||||
53
src/main.rs
53
src/main.rs
@@ -1,20 +1,15 @@
|
||||
use linfa::traits::Transformer;
|
||||
use std::collections::VecDeque;
|
||||
use std::iter::zip;
|
||||
use std::time::{Duration, Instant};
|
||||
use image::{DynamicImage, ImageReader, Rgb};
|
||||
use linfa_clustering::Dbscan;
|
||||
use hdbscan::{Hdbscan, HdbscanHyperParams};
|
||||
use image::{DynamicImage, ImageReader, Rgb, RgbImage};
|
||||
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> {
|
||||
fn extract_highlights_and_distort(image: &Vec<u8>, width: u32, threshold: u8, downsample: f64) -> Vec<Vec<f64>> {
|
||||
let max_rng = (u32::MAX as f64 * downsample) as u32;
|
||||
let width_2 = width as f64 / 2.0;
|
||||
let poi = image
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
@@ -23,11 +18,13 @@ fn extract_highlights(image: &Vec<u8>, width: u32, threshold: u8, downsample: f6
|
||||
let mut rng = rand::rng();
|
||||
rng.random::<u32>() < max_rng
|
||||
})
|
||||
.map(move |(i, _)| [ i as u32 % width, i as u32 / width ]);
|
||||
.map(move |(i, _)| {
|
||||
vec![ i as f64 % width as f64 - width_2, i as f64 / width as f64 ]
|
||||
});
|
||||
|
||||
let mut vec = Vec::new();
|
||||
vec.par_extend(poi);
|
||||
Array2::from(vec)
|
||||
vec
|
||||
}
|
||||
|
||||
#[show_image::main]
|
||||
@@ -40,15 +37,39 @@ fn main() {
|
||||
|
||||
let window = create_window("image", Default::default()).unwrap();
|
||||
let mut t: VecDeque<Duration> = VecDeque::with_capacity(25);
|
||||
let params = HdbscanHyperParams::builder()
|
||||
.epsilon(5.0)
|
||||
.min_samples(5)
|
||||
.min_cluster_size(100)
|
||||
.build();
|
||||
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
let poi = extract_highlights(&img_data, width, 196, 1.0);
|
||||
let poi = extract_highlights_and_distort(&img_data, width, 196, 0.05);
|
||||
|
||||
let mut rgb_image = img.to_rgb8();
|
||||
let clusterer = Hdbscan::new(&poi, params.clone());
|
||||
let labels = clusterer.cluster().unwrap();
|
||||
|
||||
let mut rgb_image = RgbImage::new(width, height);
|
||||
|
||||
poi.outer_iter().for_each(|pixel| {
|
||||
rgb_image.put_pixel(pixel[0], pixel[1], Rgb([255, 0, 0]))
|
||||
zip(poi, labels).for_each(|(pixel, label)| {
|
||||
if label != -1 {
|
||||
let color = vec![Rgb([255, 0, 0]), Rgb([0, 255, 0]), Rgb([0, 0, 255]), Rgb([0, 0, 0])][label as usize];
|
||||
let x = (pixel[0] + width as f64 / 2.0) as u32;
|
||||
rgb_image.put_pixel(x, pixel[1] as u32, color);
|
||||
if pixel[0] > 0.0 {
|
||||
rgb_image.put_pixel(x - 1, pixel[1] as u32, color);
|
||||
}
|
||||
if pixel[0] < width as f64 - 1.0 {
|
||||
rgb_image.put_pixel(x + 1, pixel[1] as u32, color);
|
||||
}
|
||||
if pixel[1] > 0.0 {
|
||||
rgb_image.put_pixel(x, pixel[1] as u32 - 1, color);
|
||||
}
|
||||
if pixel[1] < height as f64 - 1.0 {
|
||||
rgb_image.put_pixel(x, pixel[1] as u32 + 1, Rgb([label as u8 * 8, 0, 0]));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let image = ImageView::new(ImageInfo::new(PixelFormat::Rgb8, width, height), rgb_image.iter().as_slice());
|
||||
|
||||
Reference in New Issue
Block a user