- The problem is that when a pixel marked as weak-edge (between the two thresholds) changes to strong-edge (accepted, as described here) it is required to apply the same logic to your connected neighbors recursively (tracking the edges).
- In an imperative language, when changing from weak to strong edge, a Stack could be used to store the position (x,y). Then, at the end, process the neighbors while the stack is not empty, updating the Stack as needed. But, how to implement anything similar in pure Halide, without define_extern func?
I have used this code to hysteresis, but lacks the dynamic recursion and/or stack to do hysteresis on the neighbors when needed, which is what I can't find how to implement:
magnitude = input(x, y);
// mask receives only 0, 1, or 2.
mask(x, y) = select(magnitude > high_threshold, 2/*strong-edge*/, magnitude < low_threshold, 0/*no-edge*/, 1/*weak-edge*/);
// when mask(x,y) == 1 checks the neighbors to decide.
hysteresis(x, y) = select(mask(x, y) == 0, 0, mask(x, y) == 2, 255,
mask(x-1, y-1) == 2 || mask(x, y-1) == 2 || mask(x+1, y-1) == 2 ||
mask(x-1, y) == 2 || mask(x+1, y) == 2 ||
mask(x-1, y+1) == 2 || mask(x, y+1) == 2 || mask(x+1, y+1) == 2, 255/*weak-to-strong edge*/, 0);
The doubt, is there a way to, with recursion, stack, or anything else, do something like this:
if (hysteresis(x, y) above changes from weak to strong edge, do) {
hysteresis(x-1, y-1); hysteresis(x, y-1); hysteresis(x+1, y-1);
hysteresis(x-1, y); hysteresis(x+1, y);
hysteresis(x-1, y+1); hysteresis(x, y+1); hysteresis(x+1, y+1);
}