医学图像最显著的一个特征就是“大”,如何处理这种“大”,目前常用的一种方法就是切割,将一个大的WSI切割成多个小tile,然后分别对多个tile进行处理,“化大为小”。
WSI 经常用到的一个格式是.svs 。python 中常用来处理 .svs文件的一个包是openslide。对于openslide 中常用到的一些函数方法,许多博主都给出了简单的例子,下面是一些我认为还不错的文章链接,以供参考:https://blog.csdn.net/formlsl/article/details/80681488
https://blog.csdn.net/hjxu2016/article/details/70211198
openslide官网 :https://openslide.org/api/python/
但是,这些博客以及官网上对某些常用的比较重要的方法的使用以及输出结果的含义没有进行介绍,所以实际我在参考这些博客进行学习的时候,也花费了不少的时间,走了不少弯路。这里就对这些函数的使用进行具体介绍,方便后续使用。
1. 读取文件
img_path = 'D:/Server download/test_slide.svs'
result_path = 'D:/result'
slide = openslide.open_slide(img_path)
2. 图像原始大小(获得图像原始大小有多种方法,这只是其中一种)
[w,h] = slide.level_dimensions[0]
3. 切块方法
各参数及其含义,参考官方说明:
class openslide.deepzoom.DeepZoomGenerator(osr, tile_size=a, overlap=1, limit_bounds=False)
data_gen = DeepZoomGenerator(slide, tile_size=50, overlap=0, limit_bounds=False)
(实际上,只需要上方这一行代码,就实现了切割操作,将原始WSI根据不同分辨率分成多层,并在不同分辨率下切割成多个块)
4. 层数(不同分辨率数)(不同图像会生成不同层数,这个具体怎么定义的我也没有具体研究,还望大家不吝赐教)
print('生成的层数:',data_gen.level_count)
结果:
生成的层数: 19
5. 切割的块数
print('切分成的块数:',data_gen.tile_count)
结果:切分成的块数: 2251661
6. 每层尺寸大小
print('每层尺寸大小:',data_gen.level_dimensions)
返回结果:每层尺寸大小: ((1, 1), (2, 1), (3, 1), (5, 1), (9, 2), (17, 4), (34, 8), (67, 16), (133, 31), (265, 61), (529, 122), (1057, 244), (2114, 488), (4227, 975), (8454, 1950), (16907, 3899), (33814, 7797), (67627, 15594), (135253, 31188))
7. 切分后每层的块数(返回参数参照官方文档)
print('切分的每层的块数:',data_gen.level_tiles)
返回结果:切分的每层的块数: ((1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (2, 1), (3, 1), (6, 2), (11, 3), (22, 5), (43, 10), (85, 20), (170, 39), (339, 78), (677, 156), (1353, 312), (2706, 624))
解释:我刚开始就是不能理解这种返回的参数是什么含义,其实很简单,我们要综合 3、6、7这3条语句来看:
对data_gen(切割后的变量)而言,它的每层分辨率是随着层数增加而增加的(参考6)(与第2,slide的顺序刚好相反),我们定义的窗口(名称可能不太严谨,参考2)大小为50*50。以第0层为例,它的尺寸大小为(1,1),小于窗口大小,所以在这一层,切割完只有一块(1,1)(参考7)。同理,对第7层,它的尺寸大小为(67,16),宽大于窗口大小,所以会进行切割,该层的切割结果为(2,1)。
对第7层进行切割的输出结果如下:
第1张切割大小为 50*16
第2张切割大小为(67-50)*16
以上就是个人对图像切割的一些简单理解,如果错误,还请各位不吝赐教!