如何将OpenSlide用read_region读取的Tiff局部区域转换为OpenSlide对象
你原有的写法无法生效的核心原因是:openslide.OpenSlide()仅支持接收本地文件路径作为入参,而read_region()返回的是PIL图像对象,本身不携带原WSI的元数据,也不符合OpenSlide的初始化要求。
解决方案1:自定义代理类模拟OpenSlide接口(推荐)
不需要生成临时文件,性能最优,直接继承原WSI的所有元数据参数,仅对区域坐标做映射即可。
示例代码:
import openslide from PIL import Image class PartialOpenSlide: def __init__(self, original_wsi: openslide.OpenSlide, region_x: int, region_y: int, level: int, region_w: int, region_h: int): # 继承原WSI的所有元数据参数 self.properties = original_wsi.properties self.level_downsamples = original_wsi.level_downsamples self.mpp_x = original_wsi.mpp_x self.mpp_y = original_wsi.mpp_y # 存储当前裁剪区域的基础信息 self.origin_x = region_x self.origin_y = region_y self.base_level = level # 计算各层级下当前区域的尺寸 self.level_dimensions = [] base_w = region_w base_h = region_h for downsample in self.level_downsamples: self.level_dimensions.append((int(base_w / downsample), int(base_h / downsample))) # 预读基础层级的区域 self.base_image = original_wsi.read_region((region_x, region_y), level, (region_w, region_h)).convert("RGB") def read_region(self, location: tuple[int, int], level: int, size: tuple[int, int]) -> Image.Image: # 坐标映射:将局部区域的坐标转换为原图像的坐标 offset_x = int(location[0] * self.level_downsamples[level]) offset_y = int(location[1] * self.level_downsamples[level]) # 从预存的基础区域缩放得到对应层级的区域 downsample = self.level_downsamples[level] / self.level_downsamples[self.base_level] crop_x = int(offset_x / downsample) crop_y = int(offset_y / downsample) crop_w = int(size[0] / downsample) crop_h = int(size[1] / downsample) crop_img = self.base_image.crop((crop_x, crop_y, crop_x + crop_w, crop_y + crop_h)) return crop_img.resize(size, Image.Resampling.LANCZOS) # 调用示例 original_wsi = openslide.OpenSlide("your_full_slide.tiff") partial_wsi = PartialOpenSlide(original_wsi, 0, 0, 0, 4000, 4000) # 后续可以像使用原生OpenSlide对象一样调用partial_wsi的参数和方法 print(partial_wsi.mpp_x) print(partial_wsi.level_dimensions) region = partial_wsi.read_region((100,100), 1, (500,500))
解决方案2:生成临时TIFF文件后读取
如果你的处理流程强依赖原生OpenSlide实例的特性,可以将裁剪后的区域保存为带元数据的临时TIFF,再用OpenSlide读取:
import openslide import tifffile import tempfile import os original_wsi = openslide.OpenSlide("your_full_slide.tiff") region = original_wsi.read_region((0,0), 0, (4000,4000)).convert("RGB") # 生成临时文件 temp_fd, temp_path = tempfile.mkstemp(suffix=".tiff") os.close(temp_fd) # 写入TIFF时附带原WSI的元数据 with tifffile.TiffWriter(temp_path) as tif: tif.write( region, metadata={ "MPP": original_wsi.mpp_x, "Properties": dict(original_wsi.properties) } ) # 读取临时文件得到OpenSlide实例 partial_wsi = openslide.OpenSlide(temp_path) # 使用完成后删除临时文件 os.unlink(temp_path)
该方案需要额外的磁盘IO开销,且元数据的兼容性取决于你写入TIFF的标签是否符合OpenSlide的识别规则。
内容的提问来源于stack exchange,提问作者SjAnupa
相关产品推荐
相关产品推荐

