Graphite icon indicating copy to clipboard operation
Graphite copied to clipboard

Feature: Add median filter option to blur node

Open youssefelzedy opened this issue 3 months ago • 9 comments

This PR adds a new dedicated median filter node to the Raster: Filter category, providing users with an effective tool for noise reduction while preserving edges.

Changes Made

  • Added new median_filter node function with its own dedicated interface
  • Implemented median_filter_algorithm() function that processes each color channel independently
  • Added median_quickselect() helper function using select_nth_unstable_by() with total_cmp() for safe NaN handling
  • Uses O(n) quickselect algorithm instead of O(n log n) full sorting for better performance

Why a Separate Node?

Median filtering serves a fundamentally different purpose than blur operations:

  • Primary use case: Noise reduction (especially salt-and-pepper noise) while preserving sharp edges
  • Different behavior: Does not create smooth blur effects like Gaussian/box blur
  • Distinct parameters: Optimal radius ranges and use cases differ from blur filters
  • UI clarity: Users can easily distinguish between blur effects and noise reduction

Use Cases

  • Removing salt-and-pepper noise from scanned images
  • Cleaning up digital photography noise without edge destruction
  • Pre-processing images before applying other effects
  • Situations where traditional blur would be too destructive to image details

Technical Implementation

  • Uses quickselect algorithm (O(n) average case) for efficient median calculation
  • Operates on square neighborhoods defined by radius parameter
  • Processes RGBA channels independently to maintain color fidelity
  • Safe NaN handling with f32::total_cmp() to prevent runtime panics
  • Consistent gamma space processing with existing filter nodes

The implementation follows established patterns from other filter nodes with proper error handling and performance optimization.

Closes feature in Issue No. #912

youssefelzedy avatar Sep 19 '25 11:09 youssefelzedy

Please make this a separate node.

Keavon avatar Nov 20 '25 13:11 Keavon

Please make this a separate node.

@Keavon Could you explain more? What do you mean by that?

You mean separating the node for the median filter functionality instead of adding it as an option to the existing blur node?

youssefelzedy avatar Nov 20 '25 19:11 youssefelzedy

You mean separating the node for the median filter functionality instead of adding it as an option to the existing blur node?

Yes

Keavon avatar Nov 20 '25 20:11 Keavon

@Keavon Could you review it?

youssefelzedy avatar Nov 20 '25 20:11 youssefelzedy

!build

Keavon avatar Nov 21 '25 03:11 Keavon

📦 Build Complete for a6b538ad1df037ff77800c01425b1dad9340cc2b
https://fb96ac02.graphite.pages.dev

github-actions[bot] avatar Nov 21 '25 03:11 github-actions[bot]

@Keavon , any updates?

youssefelzedy avatar Nov 25 '25 08:11 youssefelzedy

!build

Keavon avatar Nov 25 '25 08:11 Keavon

📦 Build Complete for d19c7ff074f0fc17b9a0584083d0645edba1424b
https://b98c1796.graphite.pages.dev

github-actions[bot] avatar Nov 25 '25 09:11 github-actions[bot]