implement blur

This commit is contained in:
Vinzenz Schroeter 2025-02-28 11:58:04 +01:00
parent c3aaf609ef
commit 5b77dac176
2 changed files with 47 additions and 13 deletions

View file

@ -1,6 +1,6 @@
//! Based on https://github.com/WarkerAnhaltRanger/CCCB_Ledwand
use image::GrayImage;
use image::{GenericImage, GrayImage};
use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH};
pub struct LedwandDither {
@ -50,13 +50,13 @@ impl LedwandDither {
image: &GrayImage,
histogram: GrayHistogram,
) -> HistogramCorrection {
let adjustment_pixels = image.len() / 100;
let adjustment_pixels = image.len() / PIXEL_HEIGHT;
let mut num_pixels = 0;
let mut brightness = 0;
let mincut = loop {
num_pixels += histogram[brightness as usize] as usize;
num_pixels += histogram[brightness as usize];
brightness += 1;
if num_pixels >= adjustment_pixels {
break u8::min(brightness, 20);
@ -64,7 +64,7 @@ impl LedwandDither {
};
let minshift = loop {
num_pixels += histogram[brightness as usize] as usize;
num_pixels += histogram[brightness as usize];
brightness += 1;
if num_pixels >= 2 * adjustment_pixels {
break u8::min(brightness, 64);
@ -74,7 +74,7 @@ impl LedwandDither {
brightness = u8::MAX;
num_pixels = 0;
let maxshift = loop {
num_pixels += histogram[brightness as usize] as usize;
num_pixels += histogram[brightness as usize];
brightness -= 1;
if num_pixels >= 2 * adjustment_pixels {
break u8::max(brightness, 192);
@ -92,12 +92,7 @@ impl LedwandDither {
}
fn apply_histogram_correction(image: &mut GrayImage, correction: HistogramCorrection) {
let midpoint = image.width() / 2;
for (x, _, pixel) in image.enumerate_pixels_mut() {
if x > midpoint {
continue;
}
for pixel in image.pixels_mut() {
let pixel = &mut pixel.0[0];
let value = (*pixel as f32 + correction.pre_offset) * correction.factor
+ correction.post_offset;
@ -116,7 +111,7 @@ impl LedwandDither {
let mut num_pixels = 0;
for brightness in u8::MIN..=u8::MAX {
num_pixels += histogram[brightness as usize] as usize;
num_pixels += histogram[brightness as usize];
if num_pixels >= midpoint {
return brightness;
}
@ -124,4 +119,42 @@ impl LedwandDither {
unreachable!("Somehow less pixels where counted in the histogram than exist in the image")
}
pub fn blur(source: &GrayImage, destination: &mut GrayImage) {
assert_eq!(source.len(), destination.len());
Self::copy_border(source, destination);
Self::blur_inner_pixels(source, destination);
}
fn copy_border(source: &GrayImage, destination: &mut GrayImage) {
let last_row = source.height() -1;
for x in 0..source.width() {
destination[(x, 0)] = source[(x, 0)];
destination[(x, last_row)] = source[(x, last_row)];
}
let last_col = source.width() - 1;
for y in 0..source.height() {
destination[(0, y)] = source[(0, y)];
destination[(last_col, y)] = source[(last_col, y)];
}
}
fn blur_inner_pixels(source: &GrayImage, destination: &mut GrayImage) {
for y in 1..source.height() - 2 {
for x in 1..source.width() - 2 {
let weighted_sum = source.get_pixel(x - 1, y - 1).0[0] as u32
+ source.get_pixel(x, y - 1).0[0] as u32
+ source.get_pixel(x + 1, y - 1).0[0] as u32
+ source.get_pixel(x - 1, y).0[0] as u32
+ 8 * source.get_pixel(x, y).0[0] as u32
+ source.get_pixel(x + 1, y).0[0] as u32
+ source.get_pixel(x - 1, y + 1).0[0] as u32
+ source.get_pixel(x, y + 1).0[0] as u32
+ source.get_pixel(x + 1, y + 1).0[0] as u32;
let blurred = weighted_sum / 16;
destination.get_pixel_mut(x, y).0[0] = blurred.clamp(u8::MIN as u32, u8::MAX as u32) as u8;
}
}
}
}

View file

@ -29,10 +29,11 @@ pub fn stream_window(connection: &Connection, options: StreamScreenOptions) {
loop {
let mut frame = get_next_frame(&capturer);
LedwandDither::histogram_correction(&mut frame);
let cutoff = if options.no_dither {
LedwandDither::median_brightness(&frame)
} else {
LedwandDither::histogram_correction(&mut frame);
LedwandDither::blur(&frame.clone(), &mut frame);
dither(&mut frame, &BiLevel);
u8::MAX / 2
};