5月28日《Nature Methods》介绍了一项技术——InterpolAI,能够利用深度学习(deep learning)与光流(optical flow)技术,在两张真实图像(Z-stack序列)之间“创造”出新的、从未存在过的图像,从而恢复3D结构的连续性。
文章速览摘记
这项技术具有广泛的适用性,不仅是光学成像数据,对于电镜成像,甚至MRI成像的数据,都能够进行间隔帧的智能插值。
而且这种插值,还能够重建因为样品制备时撕裂形成的空隙,相当于是能够进行图像恢复,从而保证特征结构(通常是一些比较大的连续结构,而不是随机散点的小结构)具有良好的连续性。
InterpolAI在插值方面的效果,比之前常用的Linear或者XVFI方法都要好。但提升其实也不算很大,从文章结果来看,在两张真实图像之间连续插入1-3帧是比较合适的。
文章链接🔗https://www.nature.com/articles/s41592-025-02712-4
工具尝试
数据集准备
和文中说的一样,我从BossDB下载了另外一份TEM的图像数据(3D序列层扫)。
from intern import array
em = array("bossdb://witvliet2020/Dataset_1/em")
data = em[210:220, 7457:9505, 11020:13068] # 指定切片范围,返回一个numpy数组
注意可以在anaconda的base环境中简单安装 intern 这个模块。可以简单查看其中一个切层。
import numpy as np
from imageio.v3 import imwrite
for i in range(data.shape[0]):
img = data[i, :, :]
# 保存为RGB图像
img2 = np.stack([img]*3, axis=-1) # 将灰度图像转换为RGB格式
imwrite(f"interpolation/test_data2/slice_{i+1:03d}.png", img2)
注意需要保存为RGB的灰度图,而且图片序号索引要从 1 开始,不然后面会各种报错。保存的图片如下:
InterpolAI软件的安装
这个部分就参考代码仓库的说明来弄就行,需要注意的点就是 python版本是指定 3.9,而且cudnn等版本都是指定的。所以创建之后的虚拟环境最好不要再增加其它模块,以免破坏InterpolAI的底层依赖。
https://github.com/sjoshi17jhu/InterpolAI
InterpolAI软件的使用
这里我主要是使用命令行来进行测试。第一种是 auto,就是会根据文件名列表缺失的帧来补,这个比较实用。比如上方的数据中,我把有缺陷的 2,4,5,10 都删掉(放入defect子目录),它就会补2,4,5。并且 2 放在补一帧的folder(int_1)里面,45放在补2帧的folder(int_2)里。
python main.py --mode auto --tile_size 2024 2024 --pth "interpolation/test_data2"
其输出日志如下:
2025-08-23 20:57:40.515945: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2025-08-23 20:57:41.878695: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 45895 MB memory: -> device: 0, name: NVIDIA RTX A6000, pci bus id: 0000:17:00.0, compute capability: 8.6
2025-08-23 20:57:41.880273: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 45895 MB memory: -> device: 1, name: NVIDIA RTX A6000, pci bus id: 0000:73:00.0, compute capability: 8.6
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2025-08-23 20:57:41.878695: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 45895 MB memory: -> device: 0, name: NVIDIA RTX A6000, pci bus id: 0000:17:00.0, compute capability: 8.6
2025-08-23 20:57:41.880273: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 45895 MB memory: -> device: 1, name: NVIDIA RTX A6000, pci bus id: 0000:73:00.0, compute capability: 8.6
lity: 8.6
2025-08-23 20:57:41.880273: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 45895 MB memory: -> device: 1, name: NVIDIA RTX A6000, pci bus id: 0000:73:00.0, compute capability: 8.6
lity: 8.6
Interpolating for skip 1:
Stitching needed
Interpolating slice_001.png: 0%| | 0/1 [00:00<?, ?frame/s]2025-08-23 20:57:59.280101: I tensorflow/stream_executor/cuda/cuda_dnn.cc:384] Loaded cuDNN version 8100
2025-08-23 20:58:03.665599: I tensorflow/stream_executor/cuda/cuda_blas.cc:1614] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.
Interpolating slice_001.png: 100%|███████████████████████████████████████████████████████| 1/1 [00:27<00:00, 27.49s/frame]
Interpolating for skip 2:
Stitching needed
Interpolating slice_003.png: 100%|███████████████████████████████████████████████████████| 2/2 [00:15<00:00, 7.91s/frame]
再看看输出的内容:
进一步检查对比生成的缺失帧和实际帧的差异(左侧为真实但带有缺陷的图像,右侧为插值图像):
可以看到生成的帧也只能说整体上看着还行,但是和实际帧的细节部分还是对不上。而且要插值更多帧的话,误差更大。
小结
这个插值AI工具比起已有的方法来说确实有很大改善,但是插值后的图像还是非常依赖于数据,也就是图像中结构的连续性,如果结构本身比较随机且稀疏,其实也就对应了那些局部独立的细节,肯定是不行的。我感觉这个工具主要的作用还是为了方便三维重建,克服断层扫描造成的数据离散问题。