@@ -6,7 +6,7 @@ use raster_types::Image;
66use raster_types:: { Bitmap , BitmapMut } ;
77use raster_types:: { CPU , Raster } ;
88
9- /// Blurs the image with a Gaussian, blur kernel or Median filter.
9+ /// Blurs the image with a Gaussian or box blur kernel filter.
1010#[ node_macro:: node( category( "Raster: Filter" ) ) ]
1111async fn blur (
1212 _: impl Ctx ,
@@ -18,8 +18,6 @@ async fn blur(
1818 radius : PixelLength ,
1919 /// Use a lower-quality box kernel instead of a circular Gaussian kernel. This is faster but produces boxy artifacts.
2020 box_blur : bool ,
21- /// Use a median filter instead of a blur. This is good for removing noise while preserving edges, but does not produce a smooth blur effect.
22- median : bool ,
2321 /// Opt to incorrectly apply the filter with color calculations in gamma space for compatibility with the results from other software.
2422 gamma : bool ,
2523) -> Table < Raster < CPU > > {
@@ -34,8 +32,6 @@ async fn blur(
3432 image. clone ( )
3533 } else if box_blur {
3634 Raster :: new_cpu ( box_blur_algorithm ( image. into_data ( ) , radius, gamma) )
37- } else if median {
38- Raster :: new_cpu ( median_filter_algorithm ( image. into_data ( ) , radius as u32 , gamma) )
3935 } else {
4036 Raster :: new_cpu ( gaussian_blur_algorithm ( image. into_data ( ) , radius, gamma) )
4137 } ;
@@ -46,6 +42,38 @@ async fn blur(
4642 . collect ( )
4743}
4844
45+ /// Applies a median filter to reduce noise while preserving edges.
46+ #[ node_macro:: node( category( "Raster: Filter" ) ) ]
47+ async fn median_filter (
48+ _: impl Ctx ,
49+ /// The image to be filtered.
50+ image_frame : Table < Raster < CPU > > ,
51+ /// The radius of the filter kernel. Larger values remove more noise but may blur fine details.
52+ #[ range( ( 0. , 50. ) ) ]
53+ #[ hard_min( 0. ) ]
54+ radius : PixelLength ,
55+ /// Opt to incorrectly apply the filter with color calculations in gamma space for compatibility with the results from other software.
56+ gamma : bool ,
57+ ) -> Table < Raster < CPU > > {
58+ image_frame
59+ . into_iter ( )
60+ . map ( |mut row| {
61+ let image = row. element . clone ( ) ;
62+
63+ // Apply median filter
64+ let filtered_image = if radius < 0.5 {
65+ // Minimum filter radius
66+ image. clone ( )
67+ } else {
68+ Raster :: new_cpu ( median_filter_algorithm ( image. into_data ( ) , radius as u32 , gamma) )
69+ } ;
70+
71+ row. element = filtered_image;
72+ row
73+ } )
74+ . collect ( )
75+ }
76+
4977// 1D gaussian kernel
5078fn gaussian_kernel ( radius : f64 ) -> Vec < f64 > {
5179 // Given radius, compute the size of the kernel that's approximately three times the radius
0 commit comments