我已经将此代码用于滞后,但缺少动态递归和/或堆栈以在需要时对邻居进行滞后,这是我无法找到的实现方法:
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);
怀疑,有没有办法,通过递归,堆栈或其他任何东西,做这样的事情:
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);
}
答案 0 :(得分:3)
简短回答:不。
没有办法使用非图像数据结构(如堆栈),也无法进行动态递归。目前尚不清楚Halide会在这里真正增加多少价值,因为该算法在编写时似乎没有可平铺,可并行化或可矢量化。
然而,您可以重新编写算法,将算法在图像上进行迭代扫描,将边缘从弱到强翻转。它可以被认为是三个状态(弱,强,不是边缘)运行完成的细胞自动机,我们可以对每个传递进行矢量化/并行化。有关示例,请参阅Halide仓库中的test / correctness / gameoflife.cpp。我认为这样做会产生糟糕的计算复杂性。您可以在每个像素上工作,而不仅仅是在翻转像素的实时边缘。
您还可以将其作为细胞自动机运行,沿某些波阵面进行就地更新,例如:从上到下,从下到上,从左到右,从右到左进行扫描。然后,您可以沿波前进行矢量化。时间表类似于IIR(见https://github.com/halide/CVPR2015/blob/master/RecursiveFilter/IirBlur.cpp)。这种方法可以处理任何方向的线性边缘,但是任何固定数量的扫描都会错过从弱到强的螺旋。
但是,不是以这些方式扭曲你的代码,我只是使用不同的算法,或使用define_extern。