虚拟展开

2021-03-03 09:09:57

此代码库用于“虚拟展开”"文章中描述的计算管道:“通过X射线显微断层扫描成像的密封文档的自动虚拟展开来解锁历史记录。”

该代码由Amanda Ghassaei和Holly Jackson编写,并由Erik Demaine监督。这项工作是与Unlocking History小组合作完成的:Jana Dambrogio,Daniel Starza Smith,Martin Demaine,Graham Davis,David Mills,Rebekah Ahrendt,Nadine Akkerman,David van der Linden等。

注意在此存储库中,我们仍在优化和清理本文中使用的原始代码,以便可以更轻松地使用和修改它。此外,我们还修复了一些错误并显着提高了性能。大部分工作已经完成,但是我们仍在调试&segmentation"和"展平"零件和在“混合网格传播”上的端口本文中介绍的步骤。请耐心配合,我们希望在接下来的几周内完成这最后的步骤。您可以在https://doi.org/10.7910/DVN/VBWOI6上找到原始文档中使用的代码的存档版本。您可以在https://github.com/UnlockingHistory/virtual-unfolding/projects/1上跟踪重构的最后几步。

使用node.js安装程序或通过选择的程序包管理器安装node.js。当前,我们建议安装版本8.16.2(请参阅下面的注释)。

该代码库的依赖项之一(node-opencl)必须针对您计算机上的node版本进行编译。我们无法使用最新的节点版本(特别是node v14.2.8和node v11.9.0)来编译此程序包。 ,因此我们当前正在使用节点v8.16.2和节点v8.10.0。我们正在使用nvm来管理计算机上的各种节点版本。可能会使用更高版本的节点(可能是v9或v10),但是尚未经过测试。

从理论上讲,node-gyp应该可以使用多个版本的python,但是这种特定的安装似乎需要python2。如果您的计算机上安装了多个python版本,则可以通过以下方式将node-gyp配置为使用python 2:

如果在安装过程中发现任何错误,请仔细阅读上面的安装说明。目前,使用node-gyp编译node-opencl库非常复杂,这将引发许多警告-可以。

这将处理一个小文件,并将所有中间文件和最终结果放置在output / FILENAME /中。 docs / output-files.md中提供了所有输出文件的完整描述。如果您打算使用此代码库处理非常大的文件,则此处的目的是可以使用openCL在GPU上运行该文件。根据您XMT数据的大小,您可能需要一个具有显着RAM的GPU-我们目前正在NVIDIA Titan X的1/2上处理文件。

您可以在src / common / Defaults.ts中看到传递给脚本的默认参数列表。要绕过这些默认值,请传递可选的环境变量:

此回购还包括一些脚本,用于生成断层扫描数据和结果的动画和其他可视化效果。有关更多信息,请参见可视化README,并在此处找到我们的Blender渲染设置。

我们希望该代码将随着时间的推移不断发展,以提高效率和健壮性,我们欢迎您的贡献。我们也很想听听您如何使用此代码。

与各种体积3d数据格式的兼容性-当前,我们支持.tom文件格式,在此[需要资料]进行了说明。如果您有其他格式的体积数据,请与我们联系,我们可以找出一种使您的数据与该管道一起使用的方法。

来自R3的全局映射-> R2-我们目前使用增量方案将通过分段识别的连接组件映射到2D平面。由于到目前为止我们的数据集仅限于书写基板几乎没有翘曲的伪影,因此我们不必在网格中引入太多失真即可计算此映射,并且我们的增量方法通常就足够了。许多历史文物由于过度加热,水损坏或其他时间过程而变形,并且可能无法在我们当前的方案中正确映射到2D。

提高速度-由于此代码库预期体积扫描的大小很大,因此通常不可能为给定步骤在cpu / gpu ram中加载所有相关数据。为了解决这个问题,管道在很大程度上依赖于缓冲磁盘中的部分数据(BufferedTomData)。当前,分段步骤(尤其是NormalsRelaxation)受到读取/写入磁盘的时间的严重限制。这些读/写调用都是同步的,通过使用异步调用可以提高性能。

我们不使用很多内置的JS迭代器类型的函数(forEach,map,reduce,filter等),特别是在处理大量数组的繁重处理循环的代码中。 尽管这些方法非常好,但是它们迫使您在每次迭代中创建新的上下文,最终需要由垃圾收集器清理它们。 我们发现,如果初始化了许多这样的上下文,则此垃圾回收实际上会花费大量时间。 我们尝试在处理大量数据时不要初始化数组或对象。 在很多方法上 如果需要写入和返回许多值,则MutableTypedArray我们要求您传入一个数组。 这是由于与上述相同的垃圾回收原因。 因此,在跟踪数组/对象中的潜在突变时,您必须要格外小心。