这篇博文展示了一个案例研究,其中一位研究人员使用 Dask 进行图像镶嵌融合。图像镶嵌融合是指将多个在已知位置拍摄的较小图像组合在一起,并将它们拼接成一个具有超大视野的单一图像。完整的代码示例可在 GitHub 的 DaskFusion 仓库中获取:https://github.com/VolkerH/DaskFusion
在光学显微镜中,使用 20 倍物镜捕获的单个视野通常对角线尺寸约为几百微米(精确尺寸取决于光学系统的其他部分,包括相机芯片的尺寸)。典型的样本载玻片尺寸为 25 毫米 x 75 毫米。因此,在对整个载玻片成像时,必须采集数百张图像,通常在单个图块之间存在一些重叠。随着放大倍数的增加,所需的图像数量也会相应增加。
为了获得全景,必须将大量单个图像图块融合成一个大型镶嵌图像。在这里,我们假设定位和对齐单个图像图块所需的信息是已知的。在本例中,此信息可作为显微镜记录的元数据获取,即显微镜载物台位置和像素比例。另外,此信息也可以直接从图像数据中导出,例如通过在图块重叠区域匹配相应图像特征的配准步骤。
用于保存最终镶嵌图像的数组通常尺寸太大,无法放入 RAM 中,因此我们将使用 Dask 数组和 map_blocks 函数来实现核心外处理。map_blocks 函数将单独处理输出数组的较小块(也称为分块),从而无需将整个输出数组保留在内存中。如果资源充足,dask 还会将块的处理分布到多个工作节点上,这样我们就可以免费获得并行处理能力,这有助于加快融合过程。
通常,无论何时我们想要连接 Dask 数组,我们都会使用 Stack、Concatenate 和 Block。然而,这些工具不适合图像镶嵌融合,因为
这个镶嵌原型代码的起点是一些读取所有图块的载物台元数据并计算每个图块的仿射变换的代码,该变换会将图块放置在输出数组中的正确位置。
下图显示了使用 napari 图像查看器将镶嵌图像图块放置到正确位置的初步工作。这里展示了一个包含 63 个图像图块的小示例。
这里是放置单个图块的动画。
为了利用 Dask 进行处理,我们创建了一个 fuse 函数,该函数生成最终镶嵌图像的一个小块,并由 map_blocks 为输出数组的每个分块调用。每次调用 fuse 函数时,map_blocks 都会传递一个字典(block_info)。根据 Dask 文档
您的块函数通过接受特殊的 block_info 或 block_id 关键字参数来获取其在数组中的位置信息。
镶嵌工作流中 fuse 函数的基本流程如下。对于输出数组的每个分块
使用最大投影法混合重叠区域的图块可能会导致伪影,例如重影和可见的图块接缝,因此在实际生产中通常会使用更复杂的算法。
对于包含许多图像图块(约 500-1000 个图块)的数据集,使用这种基于 Dask 的方法,可以将镶嵌图像生成的速度从几个小时缩短到几十分钟(与之前在同一工作站上运行 ImageJ 插件的工作流相比)。由于 Dask 能够处理核心外数据以及使用 zarr 进行分块数组存储,因此也可以在 RAM 有限的硬件上运行融合过程。
最后,我们得到了最终的图像镶嵌融合结果。
与此图像镶嵌融合项目相关的代码可在以下 DaskFusion GitHub 仓库中找到:https://github.com/VolkerH/DaskFusion
在此 笔记本 中有一个独立的示例,它会下载缩减尺寸的示例数据以演示该过程。
目前,DaskFusion 代码是用于单通道 2D 图像和在重叠区域混合图块的简单最大投影的概念验证,它不是生产代码。然而,如果将图块分块相交计算扩展到更高维度的数组,同样的原理也可用于融合多通道图像体,例如来自光片数据。通过利用 dask,这些甚至更大的数据集将受益更多,因为可以使用 dask jobqueue 将处理分布到 HPC 集群的多个节点上。
Marvin 关于多视图图像融合的闪电演讲:YouTube 上提供 15 分钟视频
Marvin 在视频中提到的 GitHub 仓库 MVRegFus 可在此处获取:https://github.com/m-albert/MVRegFus
这项计算工作由 Volker Hilsenstein 完成,Marvin Albert 参与合作。Volker Hilsenstein 是 EMBL Theodore Alexandrov 实验室 的一名科学软件开发人员,专注于空间代谢组学和生物图像分析。
样本图像由 EMBL Heidelberg Alexandrov 实验室的 Mohammed Shahraz 准备和成像。
Genevieve Buckley 和 Volker Hilsenstein 撰写了这篇博文。