首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何合并使用openslide-python获得的切片

如何合并使用openslide-python获得的切片
EN

Stack Overflow用户
提问于 2021-01-11 13:03:47
回答 1查看 594关注 0票数 3

我正在尝试以正确的顺序组合瓷砖,以便它们最终成为相同的整个幻灯片图像(.svs文件)。

根据下面的函数从文件路径读取.svs文件:

代码语言:javascript
复制
def open_slide(filepath = None):
try:
    slide = openslide.open_slide(filepath)
   
except OpenSlideError as o:
    print("Error" + str(o))
    
    slide = None
except FileNotFoundError as f:
    print("Error" +  str(f))
    slide = None
return slide

在下面的图片中,我尝试使用openslide-python的DeepZoom生成器合并我得到的瓦片(参见下面的代码片段)

代码语言:javascript
复制
def create_tile_generator(slide, tile_size, overlap):
 gen = DeepZoomGenerator(slide, tile_size=tile_size, overlap=overlap, limit_bounds=False)

下面是我如何将.svs拆分成磁贴的方法:

代码语言:javascript
复制
def split_wsi_to_tiles(wsi_path = None):
print("splitting wsi into tiles")
tile_indices = process_slide(slide_num = SLIDE_NUM , filepath= wsi_path, tile_size = TILE_SIZE, overlap = OVERLAP)
i = 0
tile_indices_savepath  = os.path.join(os.getcwd(),"saved","tile_indices")
save_file(filepath = tile_indices_savepath,filename=name,file= tile_indices)
for ti in tile_indices:
    suffix =  str(i)
    (slide_num,tile) = process_tile_index(tile_index =ti,filepath = svs_path )
    tile = cv2.cvtColor(tile, cv2.COLOR_BGR2RGB)
    cv2.imwrite(save_path + suffix + ext,tile)
    i = i + 1
print("done splitting wsi into tiles")
return tile_indices_savepath

助手函数process_slide和process_tile_index如下所示

代码语言:javascript
复制
def process_slide(slide_num =1 , filepath= None, tile_size = 256, overlap = 0):
slide = open_slide(filepath = filepath)
generator = create_tile_generator(slide, tile_size, overlap)
zoom_level = get_40x_zoom_level(slide, generator)
print("zoom level set to " + str(zoom_level))
cols, rows = generator.level_tiles[zoom_level - 1]
tile_indices = [(slide_num, tile_size, overlap, zoom_level, col, row)
              for col in range(cols) for row in range(rows)]
return tile_indices
def process_tile_index(tile_index=None,filepath= None):
    slide_num, tile_size, overlap, zoom_level, col, row = tile_index
    slide = open_slide(filepath = filepath)
    generator = create_tile_generator(slide, tile_size, overlap)
    tile = np.asarray(generator.get_tile(zoom_level, (col, row)))
    return (slide_num, tile)

get_40x_zoom_level函数说明:

代码语言:javascript
复制
def get_40x_zoom_level(slide, generator):
global level
highest_zoom_level = generator.level_count - 1  # 0-based indexing
try:
    mag = int(slide.properties[openslide.PROPERTY_NAME_OBJECTIVE_POWER])
    
    offset = math.floor((mag / 40) / 2)
    level = highest_zoom_level - offset
except (ValueError, KeyError) as e:
    level = highest_zoom_level
print("zoom level set at " +str(level) )
save_file(filepath= os.path.join(os.getcwd(),"saved"),filename = "level.pickle",file = level)
return level

这就是我尝试将磁贴合并回其整个幻灯片图像的方式(不一定是.svs格式,但相同的图像):

代码语言:javascript
复制
def merge_tiles_to_wsi(tile_path= None,wsi_path = None):
print("merging tiles into wsi")
tile_indices = load_file(filepath = tile_indices_savepath,filename = name)
slide = open_slide(filepath = wsi_path)

level = load_file(filepath= os.path.join(os.getcwd(),"saved"),filename = "level.pickle")
generator = create_tile_generator(slide, TILE_SIZE, OVERLAP)
slide_dims = generator.level_dimensions[level]
row_size = slide_dims[0]
col_size = slide_dims[1]
channel_size = 3
slide_shape = (row_size,col_size,channel_size)
print("shape of slide is " + str(slide_shape))
wsi = np.zeros(slide_shape)
for ti in tile_indices:
    slide_num, tile_size, overlap, zoom_level, col, row  = ti
    generator = create_tile_generator(slide, tile_size, overlap)
    tile = np.asarray(generator.get_tile(zoom_level, (col, row)))
    
    row_length = tile.shape[0]
    col_length = tile.shape[1]
    row_end = row + row_length
    col_end = col + col_length
    print("col: " + str(col) + " row: " + str(row) + str(wsi[row:row_end,col:col_end].shape) + " " + str(tile.shape))
    wsi[row:row_end,col:col_end] = tile
    # view_image(img= wsi)
print("merging tiles into wsi")

return wsi

out.png的最终输出如下所示

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-11 17:25:27

libvips可以为您执行此合并和连接操作。您可以从pyvips调用它,Python绑定。

要加载svs图像并将其拆分成磁贴,您可以这样写:

代码语言:javascript
复制
import pyvips

image = pyvips.Image.new_from_file("my-slide.svs")
image.dzsave("my-deepzoom")

它将写入my-deepzoom.dzi和一个名为my-deepzoom_files的目录,其中包含所有磁贴。可以调整的参数有很多,请参考文档中的章节:

https://libvips.github.io/libvips/API/current/Making-image-pyramids.md.html

它速度非常快,甚至可以在普通的硬件上制作任何大小的金字塔。

您可以使用arrayjoin重新组合平铺以形成图像。您为它提供了一个以行为主的图像列表,并将across设置为每行的图像数量。例如:

代码语言:javascript
复制
import pyvips

tiles = [pyvips.Image.new_from_file(f"{x}_{y}.jpeg", access="sequential")
         for y in range(height) for x in range(width)] 
image = pyvips.Image.arrayjoin(tiles, across=width)
image.write_to_file("huge.tif", compression="jpeg", tile=True)

它非常快,可以连接非常大的图像数组。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65661572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档