-
-
Notifications
You must be signed in to change notification settings - Fork 988
Feature: Add median filter option to blur node #3196
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
base: master
Are you sure you want to change the base?
Feature: Add median filter option to blur node #3196
Conversation
- Add median parameter to blur function for noise reduction - Implement median_filter_algorithm with efficient quickselect - Support gamma space calculations for median filtering - Preserve edges while removing noise, complementing existing blur options Feature in Issue: GraphiteEditor#912
TrueDoctor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Keavon the code looks fine, but I have not checked if the functionality behaves as you would expect
- Add median parameter to blur function for noise reduction - Implement median_filter_algorithm with efficient quickselect - Support gamma space calculations for median filtering - Preserve edges while removing noise, complementing existing blur options Feature in Issue: GraphiteEditor#912
…el neighborhood collection
2e1e713 to
d79af07
Compare
|
Please make this a separate node. |
…lzedy/Graphite into add-median-filter-blur git pull
@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? |
Yes |
- Create dedicated median_filter node separate from blur functionality - Implement median_filter_algorithm with efficient quickselect - Support gamma space calculations for consistency - Use safe NaN handling with f32::total_cmp to prevent panics - Optimize performance with memory reuse and O(n) median selection
|
@Keavon Could you review it? |
| } | ||
|
|
||
| /// Finds the median of a slice using quickselect for efficiency. | ||
| /// This avoids the cost of full sorting (O(n log n)). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By putting it at the end in parentheses, this comment is unclear to me whether the (O(n log n)) refers to this function's runtime or if it refers to the cost of full sorting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're absolutely right about the comment ambiguity. I've updated it to be clearer:
/// Finds the median of a slice using quickselect for O(n) average case performance.
/// This is more efficient than sorting the entire slice which would be O(n log n).
The original comment was confusing because the (O(n log n)) at the end could be interpreted as either this function's complexity or the complexity we're avoiding. This new version explicitly states:
This function's performance: O(n) average case
| #[range((0., 50.))] | ||
| #[hard_min(0.)] | ||
| radius: PixelLength, | ||
| /// Opt to incorrectly apply the filter with color calculations in gamma space for compatibility with the results from other software. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to test if other graphics tools use gamma or linear space for their implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we might not need to test this for the Median filter. Since gamma correction is a monotonic function, the sort order of pixel values doesn't change between Linear and Gamma space. Therefore, the median pixel selected will be mathematically identical in both, unlike arithmetic filters (e.g., Gaussian blur), where space matters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, please remove it then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will differ if the median is calculated by taking the average of the middle two elements, but I guess that should usually not be an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, you’re right, but does it really affect the output?
|
!build |
|
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
median_filternode function with its own dedicated interfacemedian_filter_algorithm()function that processes each color channel independentlymedian_quickselect()helper function usingselect_nth_unstable_by()withtotal_cmp()for safe NaN handlingWhy a Separate Node?
Median filtering serves a fundamentally different purpose than blur operations:
Use Cases
Technical Implementation
f32::total_cmp()to prevent runtime panicsThe implementation follows established patterns from other filter nodes with proper error handling and performance optimization.
Closes feature in Issue No. #912