我正在对维度图像执行 NxN 图像卷积 w 和 h,其中 N 远小于 w 或 h。给定一个坐标 alpha,我想计算一个保证位于边界内的新坐标 safe_alpha。边界之外的坐标应该被镜像。
即,如果
alpha = (w-1) +2;
然后
safe_alpha = (w-1) -2;
这将在 GPU 上运行,因此我希望在计算中避免条件。
仅在外边界上进行镜像很简单:
safe_alpha = -| (w-1) - alpha| + alpha;
但我需要对两者进行镜像。
编辑:
这里有一些似乎有效的方法,但我不确定它是否是最快的:
safe_alpha = |alpha| + (alpha/(w-1)) * (alpha - (w-1));
我不知道openCL的细节,但是你可以在边缘使用适当的卷积窗口来避免边缘数据镜像:卷积窗口值将使图片边缘值加倍。对于每 4 个边,您将需要 N/2 卷积窗口数组(曾经简单地从原始 N*N 窗口派生),对于角则需要更多一些,但没有条件,也没有任何设备。
size_t inline mirror_if_out_of_bounds(
const int x,
const int nx
)
{
const int r = abs(x%(2*nx));
// avoid branching
return select((size_t)(2*nx-r-1),(size_t)(r),(size_t)(r<nx));
}
在你的情况下,你不需要模数,因为你知道你总是在边界之外小于nx或在边界之内。
你的解决方案,如果它能按预期工作,速度会一样快,只是除法会让它慢一点。但我认为不会,因为坐标在你的方程中是二次的。