难以在没有define_extern函数的情况下在Halide中实现Canny算法的滞后步骤

时间:2017-02-14 12:12:46

标签: halide

  • 问题在于,当标记为弱边缘的像素(在两个阈值之间)变为强边缘(接受,如所述here)时,需要递归地将相同的逻辑应用于连接的邻居(跟踪边缘)。
  • 在命令式语言中,当从弱边缘变为强边缘时,可以使用Stack来存储位置(x,y)。然后,最后,在堆栈不为空时处理邻居,根据需要更新堆栈。但是,如何在没有define_extern func?
  • 的情况下在纯Halide中实现类似的东西

我已经将此代码用于滞后,但缺少动态递归和/或堆栈以在需要时对邻居进行滞后,这是我无法找到的实现方法:

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);
}

1 个答案:

答案 0 :(得分:3)

简短回答:不。

没有办法使用非图像数据结构(如堆栈),也无法进行动态递归。目前尚不清楚Halide会在这里真正增加多少价值,因为该算法在编写时似乎没有可平铺,可并行化或可矢量化。

然而,您可以重新编写算法,将算法在图像上进行迭代扫描,将边缘从弱到强翻转。它可以被认为是三个状态(弱,强,不是边缘)运行完成的细胞自动机,我们可以对每个传递进行矢量化/并行化。有关示例,请参阅Halide仓库中的test / correctness / gameoflife.cpp。我认为这样做会产生糟糕的计算复杂性。您可以在每个像素上工作,而不仅仅是在翻转像素的实时边缘。

您还可以将其作为细胞自动机运行,沿某些波阵面进行就地更新,例如:从上到下,从下到上,从左到右,从右到左进行扫描。然后,您可以沿波​​前进行矢量化。时间表类似于IIR(见https://github.com/halide/CVPR2015/blob/master/RecursiveFilter/IirBlur.cpp)。这种方法可以处理任何方向的线性边缘,但是任何固定数量的扫描都会错过从弱到强的螺旋。

但是,不是以这些方式扭曲你的代码,我只是使用不同的算法,或使用define_extern。