我正在尝试在 Halide 中实现 Meijster 距离变换算法。我已经将此代码重写为 C++(使用 openCV)并且运行良好。关于这个算法的论文在这里。现在我的卤化物代码已完成 50% - 第一阶段工作正常,现在我遇到了阶段 2(扫描链接代码中的 3)的问题,它(简化)如下所示:
//g is 2 dimensional cv::Mat (something like array) - result of previous stage
// m is g.width and n is g.height
int(*functionF)(int x, int i, int g_i) = EDT_f;
int(*functionSep)(int i, int u, int g_i, int g_u, int max_value) = EDT_Sep;
cv::Mat dt = cv::Mat(n, m, CV_32SC1);
int* s = new int[m];
int* t = new int[m];
int q = 0, w;
for (int y = 0; y<n; y++)
{
q = 0;
s[0] = 0;
t[0] = 0;
// Scan 3
for (int u = 1; u<m; u++)
{
//how can i replace this loop:
while (q >= 0 && functionF(t[q], s[q], g.at<int>(y, s[q])) > functionF(t[q], u, g.at<int>(y, u)))
q--;
//some operations which might change value of q, s[] and t[]
}
// Scan 4 - not important here
}
有没有任何卤化物友好的方法来替换这个while循环?现在我到目前为止唯一的解决方案是这样的(尚未测试):
Expr calculateQ(Expr currentQValue, Expr y, Func t, Func s, Func g)
{
//while (q >= 0 && functionF(t[q], s[q], g.at<int>(y, s[q])) > functionF(t[q], u, g.at<int>(y, u)))
//q--;
return select(currentQValue >= 0 && functionF(t[q], s[q], g[s[q], y]) > functionF(t[q], u, g[u, y]), calculateQ(currentQValue - 1, y, t, s, g), currentQValue);
}
但即使这可行,halide 很可能会在检查条件之前尝试评估 select 的两个值,并且递归会使其非常慢。
如果没有办法在 Halide 中实现 while 循环,有没有办法只在 Halide 中使用部分代码?还有其他想法吗?