Skip to content

distance-transform: Add edge handling / abyss policy property (Issue #280), some comments

From the commit descriptions:

Adds an abyss_policy parameter to the distance-transform op (displayed as "Edge handling" to the user), allowing users to choose whether areas outside the input are to be treated as above threshold or below threshold (i.e. infinitely white or black respectively) for calculating distance. This allows the op to calculate distance only from content in the input, rather than always placing a "border" around the output. The default behavior is set to "Above threshold", a change from previous behavior, which always treated the abyss as below threshold.

In the special case of an input that is entirely above threshold, with the abyss also set to above threshold (essentially producing an infinite sheet), the entire output distance is set to the input's width + height, representing an infinite distance. Any code that may want to account for this case can test any pixel for a distance equal to or greater than this value, in case it is changed to something more mathematically correct or otherwise convenient in the future.

Annotates some of the code to make some steps and workings of the algorithm easier to follow, and explain the function of the alphabet soup variables in the second pass.

Bits of note / implementation decisions:

  • Rather than the costly workaround noted in #280 (closed), the implementation here consists of some minor adjustments to the core algorithm. From my own testing, effect on the op's speed and memory use is negligible.
  • The op now uses the newly added functionality by default instead of its old behavior. For the sort of morphological operations the op would typically be used for, the concern would generally just be the shapes/regions inside the input content, which a black border around the entire output would get in the way of more often than not.
  • For the special case of operating on an entirely above-threshold input with an above-threshold abyss (an essentially infinite plane), the entire (non-normalized) output is set to the input's width + height, an impossibly large distance representing infinity. Alternatives like INFINITY, G_MAXFLOAT, etc would be more mathematically accurate options, but also probably more likely to cause headaches in any code that uses the op. Because of this open-endedness though, the commit message includes a recommendation to test "infinite distance" as equal to or greater than the width + height, in case any reason is found to change this behavior.
  • While the new parameter is named "abyss_policy" internally, it is displayed as as "Edge handling" to be more useful and descriptive for users.

Any feedback / comments / desired changes regarding code or implementation decisions here are welcome. Thanks!

Merge request reports