clustering

This commit is contained in:
2025-05-04 20:13:33 +02:00
parent 37008cbcbf
commit 66dae40de8
2 changed files with 38 additions and 19 deletions

View File

@@ -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"

View File

@@ -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());