我有一个小的python VTK 函数,用于计算嵌入TIFF图像堆栈中的对象的体积和表面积。要将TIFF's读入VTK,我使用了vtkTIFFReader并使用vtkImageThreshold处理了结果。然后,我使用vtkMassProperties提取阈值化后确定的对象的体积和表面积。
使用VTK-5.04,此函数返回测试堆栈的正确值(3902像素)。但是,使用VTK-5.4.2相同的函数将返回不同的值(422像素)。有人可以解释吗?

代码

def testvtk():
    # read 36 TIFF images. Each TIFF is 27x27 pixels
    v16=vtk.vtkTIFFReader()
    v16.SetFilePrefix("d:/test/slice")
    v16.SetDataExtent(0,27,0,27,1,36)
    v16.SetFilePattern("%s%04d.tif")
    v16.SetDataSpacing (1,1,1)
    v16.Update()

    # Threshold level for seperating background/foreground pixels
    maxthres=81

    # Threshold the image stack
    thres=vtk.vtkImageThreshold()
    thres.SetInputConnection(v16.GetOutputPort())
    thres.ThresholdByLower(0)
    thres.ThresholdByUpper(maxthres)

    # create ISO surface from thresholded images
    iso=vtk.vtkImageMarchingCubes()
    iso.SetInputConnection(thres.GetOutputPort())

    # Have VTK calculate the Mass (volume) and surface area
    Mass = vtk.vtkMassProperties()
    Mass.SetInputConnection(iso.GetOutputPort())
    Mass.Update()

    # just print the results
    print "Volume = ", Mass.GetVolume()
    print "Surface = ", Mass.GetSurfaceArea()

笔记
通过测试VTK-5.4.2和VTK-5.2.1,我将范围缩小了一点,并相信此行为是在5.0.4和5.2.1版本之间引入的。
更新
在VTK-5.4.2中,vtkTIFFReader似乎忽略了SetDataSpacing方法中设置的x和y值。而是vtkTIFFReader从TIFF文件报告的分辨率计算x和y数据空间。

最佳答案

我以前从未听说过VTK,但是现在就开始了。

开源软件的好处是您可以直接检查源代码。更好的是,如果有基于Web的版本控制浏览器,我们可以像这样在线讨论它。

让我们看看有问题的 vtkMassProperties 。 5.0.4使用r1.28,而5.4.2使用r1.30。这是diff between r1.28 and r.30。可能影响体积计算的部分是

vol[2] += (area * (double)u[2] * (double)zavg); // 5.0.4
vol[2] += (area * u[2] * zavg); // 5.4.2


kxyz[0] = (munc[0] + (wxyz/3.0) + ((wxy+wxz)/2.0)) /(double)(numCells); // 5.0.4
kxyz[0] = (munc[0] + (wxyz/3.0) + ((wxy+wxz)/2.0)) /numCells; // 5.4.2

但所有更改对我来说都是可以的。

下一个可疑的是 vtkMarchingCubes Diff between r1.1.6.1 and 1.5
self->UpdateProgress ((double) k / ((double) dims[2] - 1)); // 5.0.4
self->UpdateProgress (k / static_cast<double>(dims[2] - 1)); // 5.4.2


estimatedSize = (int) pow ((double) (dims[0] * dims[1] * dims[2]), .75); // 5.0.4
estimatedSize = static_cast<int>(
             pow(static_cast<double>(dims[0]*dims[1]*dims[2]),0.75)); // 5.4.2

同样,他们正在固定类型转换零件,但是看起来还可以。

也可能会看到 vtkImageThreshold Diff between r1.50 and r1.52
lowerThreshold = (IT) inData->GetScalarTypeMin(); // 5.0.4
lowerThreshold = static_cast<IT>(inData->GetScalarTypeMin()); // 5.4.2

还有很多,但他们都是 Actor 。

vtkTIFFReader 变得更加有趣。 Diff between 1.51 and 1.63。从版本号的差异可以看出,与其他版本相比,该类有所发展。以下是签到注释:
  • ENH:为标量添加名称。在Paraview中可见。
  • ENH:vtkDataArray现在具有新的父类(super class)-vtkAbstractArray ...
  • ENH:为缺少此元数据的文件设置每个像素的默认样本数。
  • ENH:仅阅读您需要的内容。
  • ENH:添加多页TIFF文件支持
  • ENH:打印ivars
  • 错误:TIFF Reader无法正确处理RLE编码的数据。另外,ExecuteInformation
    覆盖用户指定的间距和原点。
  • 错误:从当前CVS VTKData读取beach.tif时,图像将上下颠倒加载。
  • 样式:s/OrientationTypeSpecifiedFlag/OriginSpecifiedFlag/g和s/OrientationTypeSpecifiedFlag/SpacingSpecifiedFlag/g
  • 错误:读取器无法正确处理扩展数据块。
  • COMP:修复警告。
  • COMP:摆脱警告。

  • 从vtkTIFFReader中所做的更改量来看,我猜想行为的差异就在于此。例如,它可能已开始将您的Tiff识别为其他格式,并更改了内部像素值。尝试打印出像素值,看看是否有任何区别。如果像素值已更改,maxthres=81可能会太高。

    10-06 09:56