专门用于连接组学数据类型和过程的图像金字塔生成。
tinybrain的Python项目详细描述
锡合金
专门用于连接组学数据类型和过程的图像金字塔生成。如果你的大脑以前不是很小的话,现在就可以了
importtinybrainimg=load_3d_em_stack()# factors (2,2), (2,2,1), and (2,2,1,1) are on a fast pathimg_pyramid=tinybrain.downsample_with_averaging(img,factor=(2,2,1),num_mips=5)labels=load_3d_labels()label_pyramid=tinybrain.downsample_segmentation(labels,factor=(2,2,1),num_mips=5)
安装
pip install numpy pip install tinybrain
动机
连接组学中的图像继承使用几种不同的技术 可视化数据,但我们主要创建uint8灰度的图像金字塔 使用2x2平均池和uint8到uint64分割标签的图像 2x2模式池。
可以使用numpy计算这两个包,但是找到了多个包 复制下采样函数很有用,将这些函数形式化是有意义的 进入位于pypi上的一个单独的库。
考虑到它们将在不同的环境中使用,这些函数应该可以工作 尽可能快,内存使用率低,避免整数截断等数值问题 同时生成多个mip级别。
注意事项:使用平均值进行下采样
建议一次生成多个mip级别,而不是递归计算。
对于整数类型的图像,这会导致整数截断问题。共同点
在2x2x1下采样的情况下,递归计算的图像将丢失0.75亮度/a
mip水平因此,利用num_mips
参数来达到平衡
这将整数截断损失限制为每4个mip级别一次。这种妥协允许
对于整数运算和不超过2倍的内存使用,输入图像包括
输出降低采样。如果你想消除超过4mip的损失,试着提升
下采样前的类型
一个C++高性能路径被触发为UXT8、UIT16、FLUAT32上的2x2x1x1下采样因子; 和float64数据类型(按Fortran顺序)其他因素、数据类型和顺序是使用速度慢得多、内存密集度高的numpy路径计算的
示例基准
在1024x1024x100 uint8图像上,我运行了以下代码pil和opencv实际上比这个基准测试显示的要快得多,因为大部分时间都花在了向numpy数组写入数据上。tinybrain在处理3D和4D阵列方面有很大的优势当然,这是一个非常简单的基准测试,可以对这些方法中的每一种进行调优。在单张纸上,枕头比锡纸快。
img=np.load("image.npy")s=time.time()downsample_with_averaging(img,(2,2,1))print("Original ",time.time()-s)s=time.time()out=tinybrain.downsample_with_averaging(img,(2,2,1))print("tinybrain ",time.time()-s)s=time.time()out=np.zeros(shape=(512,512,100))forzinrange(img.shape[2]):out[:,:,z]=cv2.resize(img[:,:,z],dsize=(512,512))print("OpenCV ",time.time()-s)s=time.time()out=np.zeros(shape=(512,512,100))forzinrange(img.shape[2]):pilimg=Image.fromarray(img[:,:,z])out[:,:,z]=pilimg.resize((512,512))print("Pillow ",time.time()-s)# Method Run Time Rel. Perf.# Original 1820 ms +/- 3.73 ms 1.0x# tinybrain 67 ms +/- 0.40 ms 27.2x # OpenCV 469 ms +/- 1.12 ms 3.9x# Pillow 937 ms +/- 7.63 ms 1.9x
注意事项:下采样分割
如果下采样因子是2的幂,则downsample_segmentation
函数执行模式池操作,包括在三维中如果因子是非二次幂,则使用跨距通常需要的模式池是递归计算的模式池优于striding,但递归计算会在高于1的mip级别引入缺陷这在未来可能会得到改善。
计算的方法实际上是使用几种不同方法的集合对于(2,2,1,1)下采样,选择了一个实现countless if的Cython快速、低内存路径对于(4,4,1)或2的其他2d幂,使用countless 2d算法。对于(2,2,2),(4,4,4)等,使用dynamic countless 3d算法。对于2的2d幂,如果启用了稀疏标志,则使用stippled countless 2d。对于所有其他配置,使用跨步。
无数的2d路径也很快,但是占用的内存和时间稍微多一些。数不清的3D对于(2,2,2)和(4,4,4)来说是可以的,但是在维度的乘积中会使用时间和内存指数这种状态可以通过在Cython /C++中实现基于计数的算法来改进不递归计算的任意因素。在我知道如何编写cython和包库之前,已经开发了无数的算法。然而,数不清的C++实现比计算第一个MIP级别要快得多。特别是,avx2 simd实现可以使内存带宽饱和。
无数算法fami的文档ly位于这里:https://github.com/william-silversmith/countless