0

我最近注意到我的旋转算法输出中有异常伪影。我使用将来自目标矩阵的高密度点投影到源图像上的实现来计算来自源像素的贡献的相对比率。这些值被缓存以允许通过展开的循环进行非常快速的旋转。

问题是由舍入行为引起的,最好从一维采样策略的上下文中说明这一点:

如果中心为 0.0 并在任一方向平移 0.9,则四舍五入时仍为 0

short(+0.9) == 0
short(-0.9) == 0

但是,如果中心为 1.0 并在任一方向平移 0.9,则

short(+0.1) == 0
short(+1.9) == 1

与原点 1 个单位距离内的任何点在四舍五入时都归于原点。这会导致对源图像中靠近轴原点的点进行过采样。解决方案是在执行舍入操作时将浮点坐标深度转换为正空间,然后将其转换回原点。

我的问题:有没有办法在不转化为正空间的情况下避免这种舍入错误?

4

2 回答 2

4

看来您只需要使用该floor功能:

(short)floor(0.9) = 0
(short)floor(-0.9) = -1
于 2012-11-19T22:20:39.383 回答
1

所以显而易见的答案是使用该floor功能。这是一个很好的答案,它将解决您的问题。

它确实给您留下了(1.0/3.0)*3.0 != 3.0IEEE 浮点数学中的问题。事实上,static_cast<short>(floor((1.0/3.0)*3.0)) == 2.

You probably want to add an epsilon to your values before calling floor. And you probably don't want to use C-style casts, because there is about one legitimate reason to use a C-style cast (google "do not use C-style casts" to find out more), and that one is quirky.

So you want something like this:

short smart_round( double d, double epsilon=0.00001 ) {
  short retval = static_cast<short>(floor( d + epsilon ) );
  return retval;
}

which incorporates an epsilon, does a static_cast, and uses floor to otherwise round down (instead of the default C/C++ behavior of "round towards zero").

于 2012-11-19T22:37:24.557 回答