医学影像处理项目中,处理vtkImageData数据时经常涉及到一类问题:给了一个空间坐标或者位置,如何计算对应像素索引或者距离。
从原理上,是这样一个公式:pixel_num = floor((postion1 - postion0) / spacing) . 有一些计算可能使用round函数,实质是一样。从一个空间位置有关的浮点数要推导出ImageData对应的整数索引。
但是,在开发过程中,发现当浮点数x接近边界值的时候,floor、round的结果和vtk内部计算可能不一致。
常规C++代码有三种典型实现方式:
// 以floor为例
int_val = static_cast<int>(float_val);
int_val = std::floor(float_val); // c or c++ library
int_val = vtkMath::Floor(float_val) // vtkmath method
// round 可以看成 floor(float_val + 0.5)
经过调研发现,vtk处理image data涉及到这些计算的时候,都添加了一个tolerance = 7.62939453125e-06。直接搜索“7.6293”可以看到相关的类。涵盖了reslice、stencil、interpolate这些基本算法。
vtkImageInerporlatorInsternals.h中的vtkInterpolationMath提供了一组典型实现。不同类实际实现方式略有不同,本质上可以归结为这种方法。
x += tolerance;
int_val = static_cast<int>(x);
int_val = std::floor(x); // c or c++ library
int_val = vtkMath::Floor(x) // vtkmath method