Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement gaussian_blur #191

Open
edgarriba opened this issue Dec 23, 2024 · 0 comments
Open

Implement gaussian_blur #191

edgarriba opened this issue Dec 23, 2024 · 0 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@edgarriba
Copy link
Member

Implement Gaussian Blur using separable filters -> imgproc::filters::gaussian_filter2d_separable

Links of interest:

Reference implementation (need to be adjusted for gaussian):

fn box_blur(input: &[f32], width: usize, height: usize, radius: usize) -> Vec<f32> {
    let mut output = input.to_vec();

    for _ in 0..3 { // Repeat 3 iterations for Gaussian approximation
        output = horizontal_box_blur(&output, width, height, radius);
        output = vertical_box_blur(&output, width, height, radius);
    }

    output
}

fn horizontal_box_blur(input: &[f32], width: usize, height: usize, radius: usize) -> Vec<f32> {
    let mut output = vec![0.0; input.len()];

    for y in 0..height {
        for x in 0..width {
            let mut sum = 0.0;
            let mut count = 0;

            for k in -(radius as isize)..=(radius as isize) {
                let nx = x as isize + k;
                if nx >= 0 && nx < width as isize {
                    sum += input[y * width + nx as usize];
                    count += 1;
                }
            }

            output[y * width + x] = sum / count as f32;
        }
    }

    output
}

fn vertical_box_blur(input: &[f32], width: usize, height: usize, radius: usize) -> Vec<f32> {
    let mut output = vec![0.0; input.len()];

    for x in 0..width {
        for y in 0..height {
            let mut sum = 0.0;
            let mut count = 0;

            for k in -(radius as isize)..=(radius as isize) {
                let ny = y as isize + k;
                if ny >= 0 && ny < height as isize {
                    sum += input[ny as usize * width + x];
                    count += 1;
                }
            }

            output[y * width + x] = sum / count as f32;
        }
    }

    output
}

fn main() {
    let input = vec![
        1.0, 2.0, 3.0, 4.0, 5.0,
        6.0, 7.0, 8.0, 9.0, 10.0,
        11.0, 12.0, 13.0, 14.0, 15.0,
        16.0, 17.0, 18.0, 19.0, 20.0,
        21.0, 22.0, 23.0, 24.0, 25.0,
    ];
    let width = 5;
    let height = 5;
    let radius = 1;

    let blurred = box_blur(&input, width, height, radius);

    for y in 0..height {
        for x in 0..width {
            print!("{:.2} ", blurred[y * width + x]);
        }
        println!();
    }
}
@edgarriba edgarriba added enhancement New feature or request help wanted Extra attention is needed labels Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant