You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:06:03