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

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

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

1 回答 1

3

简短的回答:没有。

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

但是,您可以将算法重写为一种迭代扫描图像的算法,将边缘从弱到强翻转。它可以被认为是在三个状态(弱、强、非边缘)上运行到完成的元胞自动机,我们可以对每个通道进行矢量化/并行化。有关示例,请参见 Halide 存储库中的 test/correctness/gameoflife.cpp。我认为这种方法的计算复杂度很差。您将在每个像素上工作,而不仅仅是在翻转的像素的实时边缘。

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

但我不会以这些方式扭曲您的代码,而是使用不同的算法,或者使用 define_extern。

于 2017-02-14T21:28:55.893 回答