OME-Zarr 与 OME-TIFF 的荧光显微图像标注
在多通道 z-stack 和延时图像上为已分割的细胞分类、勾画区域,再把区域导出为 QuPath 可读的 GeoJSON。
v2.13.0 新增
microscopy 标注方案显示以 OME-Zarr 或 OME-TIFF 存储的多通道显微图像,并记录标注者在图像上标出的感兴趣区域(ROI)和赋予的细胞类别。标注者可以开关通道,设置每个通道的颜色和对比度上下限,逐层浏览 z 切片和时间点,并沿文件自带的分辨率金字塔缩放。细胞生物学研究者和成像核心平台用这个方案在已有的分割结果上做细胞分类,例如在免疫荧光面板中把每个细胞核判为标记物阳性或标记物阴性。筛选团队用同一个方案为高内涵筛选视野中的表型评分,组织项目则把受损区域和碎屑标为区域。多名标注者可以标注同一幅图像,导出时每位标注者的区域和类别分开保存。
OME-Zarr 是开放显微环境(Open Microscopy Environment)的分块、多尺度图像格式,也称 OME-NGFF;OME-TIFF 是一种 TIFF 文件,其 OME-XML 头部给出通道和维度的名称。标签图像(label image)是以整数存储的分割结果,每个细胞一个 id,背景为 0。Cellpose 和 StarDist 等分割工具会输出标签图像。Potato 读取在别处生成的标签图像,自己不运行任何分割模型。
- 格式: 通过 zarr-python 读取 OME-Zarr 0.4(Zarr v2)和 0.5(Zarr v3),包括按当前 NGFF 开发版规范把坐标轴列在
coordinateSystems下的多尺度图像。通过 tifffile 读取 OME-TIFF,金字塔以 SubIFD 形式存储时也能读取。 - 坐标轴:
t、c、z中的任意几个,加上y和x。含有其他坐标轴的文件会被拒绝,并给出提示信息。没有C轴的 RGB TIFF 会把 RGB 采样当作通道读取。 - 通道: 名称、颜色和显示窗口取自 OME-Zarr 的
omero块或 OME-XML 的Channel元素。没有显示窗口的文件以最粗金字塔层级的第 0.5 和第 99.8 百分位为初始值,滑块的上限是能容纳数据的最小位深(以 uint16 存储的 12 位数据为 4095)。没有颜色的通道依次取蓝、绿、红、品红、青、黄、白和橙。 - 标签图像: OME-Zarr 图像的
labels/组无需配置即可找到。OME-TIFF 没有存放标签图像的标准位置,因此 OME-TIFF 条目要另外指定一个整数标签 TIFF。 - 离线: 查看器不从 Potato 服务器以外加载任何内容。不支持通过 HTTP 或 S3 访问远程 OME-Zarr。
Potato 在服务器上根据可见通道及其对比度上下限合成每个瓦片,浏览器在 OpenSeadragon 中显示合成后的 JPEG 瓦片。服务器端合成不需要 WebGL,也不向浏览器发送原始通道数据,代价是每次更改通道或对比度设置时,可见瓦片都要往返一次。
读取器需要 microscopy 可选依赖:
pip install 'potato-annotation[microscopy]'这个可选依赖在 Python 3.11 及以上版本安装 zarr-python 3,在更早的 Python 上安装 zarr-python 2,同时安装 tifffile。zarr-python 2 无法读取 OME-Zarr 0.5,因此 OME-Zarr 0.5 存储需要 Python 3.11 或更高版本。
配置
下面的配置让三名标注者为每幅图像中的细胞分类,并勾画受损组织或碎屑。细胞来自图像的标签图像,区域由标注者手工绘制:
annotation_task_name: "Cell classification"
task_dir: .
media_directory: media
output_annotation_dir: annotation_output
data_files: [data/images.json]
item_properties: {id_key: id, text_key: note}
num_annotators_per_item: 3
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: microscopy
name: cells
description: "Classify the cells, and outline any region that looks damaged."
image_key: image # item field naming the OME-Zarr or OME-TIFF
labels_key: cells # item field naming a label TIFF (OME-TIFF items)
tools: [bbox, polygon, landmark]
labels: # classes for regions
- {name: damaged, color: "#e8590c"}
- {name: debris, color: "#868e96"}
cell_labels: # classes for cells
- {name: "marker positive", color: "#f03e3e"}
- {name: "marker negative", color: "#4dabf7"}
- {name: dividing, color: "#fab005"}
channels: # overrides of the file's own settings
- {name: DAPI, label: "DAPI (nuclei)"}
- {index: 2, contrast: [100, 3000]}
min_cells: 1
label_requirement: {required: true}labels 列出区域类别,cell_labels 列出细胞类别。没有 cell_labels 时,细胞使用区域类别。第一个 channels 项为文件中名为 DAPI 的通道重命名,第二项为第三个通道(从 0 开始计数)设置初始对比度窗口。min_cells 与 label_requirement 同时设置时,标注者至少为一个细胞分类之前,Next 一直不可用。Potato 在服务器启动时检查每个方案值,值有误时服务器停止运行,并给出指明该键的提示信息。
只标细胞的任务
筛选中的表型评分通常只需要细胞类别,不需要区域。下面这段部分配置替换上面配置中的 annotation_schemes:
annotation_schemes:
- annotation_type: microscopy
name: phenotype
description: "Give every cell in the field a phenotype."
tools: [] # no region tools
label_image: cells # entry of the OME-Zarr labels/ group
labels: [normal, enlarged, multinucleated, apoptotic]
channels:
- {index: 0, color: "#0000ff"}
- {index: 1, visible: false}
min_cells: 20
label_requirement: {required: true}设置 tools: [] 后,区域工具被隐藏,类别列表作用于细胞。OME-Zarr 的 labels/ 组中有多个分割结果(例如细胞核和整个细胞)时,label_image 键选择其中一项。第二个通道初始隐藏,标注者仍然可以把它打开。
数据格式
每个条目给出相对于 media_directory 的图像路径:
{"id": "well_A01", "image": "screen/A01.ome.zarr"}
{"id": "tissue_b", "image": "tissue_b.ome.tif", "cells": "tissue_b_cells.tif"}Potato 先在 media_directory 中查找该路径,再在 task_dir 中查找,并拒绝绝对路径、URL 以及任何解析后位于两者之外的路径。对于 HCS 板或 bioformats2raw 容器,请指定存储中的某一幅图像,例如 plate.ome.zarr/A/1/0。如果指定的是板的根目录,Potato 会显示一条错误,并建议使用内部路径。
标签 TIFF 包含整数,宽高与图像的全分辨率宽高相同,并且只使用图像本身具有的 T、Z、Y 和 X 轴。Potato 拒绝尺寸不同的标签 TIFF,因为从较小栅格画出的细胞轮廓会落在图像上错误的位置。TIFF 平面整体解码,超过 max_pixels 的平面会被拒绝。大图像应存为瓦片化的金字塔 OME-TIFF 或 OME-Zarr,这样读取器只获取某个瓦片覆盖的数据块。
选项
microscopy 选项 | 默认值 | 含义 |
|---|---|---|
labels | 必填 | 区域类别,写成名称或带 #rrggbb 颜色的 {name, color}。没有颜色的类别依次取 Potato 的八色调色板。没有 cell_labels 时,这个列表同时给出细胞类别 |
cell_labels | labels | 细胞类别,写法相同。类别在标签数组导出中的编号是它在列表中的位置,从 1 开始 |
image_key | image | 存放图像路径的条目字段。路径可以带 /media/ 前缀 |
labels_key | 无 | 存放单独整数标签 TIFF 的条目字段,用于 OME-TIFF 条目。此时标签图像的名称为 cells |
label_image | 第一项 | 要使用的 OME-Zarr labels/ 组中的项 |
tools | [bbox, polygon, landmark] | 区域工具(矩形、多边形和点)。[] 表示只标细胞的任务 |
channels | 取自文件 | 按通道覆盖设置,以 index(从 0 开始)或 name 匹配,可设 label(显示名称)、color、contrast: [low, high] 和 visible |
min_rois | 0 | 条目的区域数达到这个数量之前,Next 一直不可用,取值 0 到 10,000。仅在方案为必填时生效 |
min_cells | 0 | 有类别的细胞达到这个数量之前,Next 一直不可用,取值 0 到 100,000。仅在方案为必填时生效 |
label_requirement | 无 | {required: true} 把方案设为必填 |
height | 520 | 查看器的像素高度,取值 240 到 2000,最多为窗口高度的 70%,在手机上更低 |
tile_size | 254 | 瓦片的像素尺寸,取值 64 到 1024 |
max_pixels | 64000000 | 整体解码的最大 TIFF 平面,也是导出时读取的最大标签平面,取值 1,000,000 到 4,000,000,000 |
label_max_side | 2048 | 发送到浏览器的标签栅格每边最多这么多像素,取值 256 到 8192 |
instructions | 无 | 显示在描述下方的文本 |
浏览器根据标签栅格判断点击落在哪个细胞上,导出则从同一幅标签图像读取细胞 id,因此点击选中的 id 就是导出中写出的 id。大于 label_max_side 的标签图像,取其金字塔中能放得下的最精细层级来显示;没有合适的层级时,每隔几个像素采样一次,比采样步长还窄的细胞可能不会出现在栅格中。细胞数超过 50,000 的标签图像不能用于细胞列表,会被拒绝。
细胞分类与区域绘制
标注者拖动来平移,滚动或双指捏合来缩放。每个通道行有一个显示或隐藏该通道的复选框、一个颜色色块、Min 和 Max 对比度滑块,以及一个恢复文件或配置设置的 Reset 按钮。在同一个浏览器会话中,Potato 会在条目之间保留通道设置。图像含有多个 z 切片或多个时间点时,图像下方会出现相应的 z 切片或时间点滑块。
要为细胞分类,标注者选择 Pan / select cell(按键 V),然后点击一个细胞。选中的细胞以黄色勾边,按 1 到 9 中的某个键或点击类别按钮即可为它指定类别。已分类的细胞以类别颜色填充。也可以输入细胞的 id 来选中细胞。类别作用于该细胞 id,覆盖每个 z 切片和时间点,存储的 z 和 t 记录标注者在哪个平面上做出分类。
要绘制区域,标注者选择 Rectangle(R)、Polygon(P)或 Point(O),并在“Region class”下选择类别。矩形靠拖动绘制。多边形每个顶点点击一次,点击第一个顶点、双击、按 Enter 或点击“Finish polygon”按钮即可结束。Escape 取消正在绘制的多边形,Backspace 删除最后一个顶点。区域属于绘制时所在的 z 切片和时间点,也只在那里显示。在 Regions 列表中选中一个区域,查看器会移到该区域所在的平面;列表中的每一项都有类别菜单和删除按钮。
存储的答案
每个方案为每个条目存储一个 JSON 对象:
{"image": {"width": 256, "height": 256},
"rois": [{"type": "polygon", "label": "damaged", "color": "#e8590c",
"coordinates": [{"x": 0.58, "y": 0.08}, {"x": 0.86, "y": 0.12}, {"x": 0.78, "y": 0.35}],
"z": 1, "t": 0}],
"cells": [{"label_id": 1, "class": "marker positive", "z": 1, "t": 0}],
"label_image": "cells"}区域坐标是相对于全分辨率图像的比例值,形式与 image_annotation 方案相同。bbox 为 {x, y, width, height},polygon 是一组点,landmark 是一个点。
导出
microscopy 导出把每位标注者的答案分开写入下面命令之后列出的文件:
python -m potato.export --config config.yaml --format microscopy --output out/| 文件 | 内容 |
|---|---|
microscopy_rois.geojson | 一个 FeatureCollection,包含所有区域,使用全分辨率像素坐标(x 向右,y 向下,无地理参考)。矩形和多边形是闭合的 Polygon,点是 Point。每个要素都带有 QuPath 可读格式的 objectType: "annotation" 和 classification: {name, color: [r, g, b]},另有 item_id、user_id、schema、roi_type、z 和 t |
microscopy_cells.csv | 每个已分类细胞一行,列为 user_id, instance_id, schema, label_image, label_id, class, z, t |
ome_zarr/<item>.ome.zarr/labels/<schema>__<user>/ | 条目的标签图像,其中每个细胞 id 都替换为该细胞的类别编号(未分类细胞和背景为 0),以 OME-Zarr 标签图像形式存储,带 image-label 颜色和一个列出各类别名称的 properties 列表 |
要在 QuPath 中打开这些区域,先打开图像,再导入 microscopy_rois.geojson。GeoJSON 包含所有条目和标注者。多幅图像或多名标注者共用这个文件时,导入前先按 item_id 和 user_id 筛选要素。
源图像为 OME-Zarr 0.5 时,标签数组写为 OME-Zarr 0.5,否则写为 0.4。--option zarr_format=2 或 --option zarr_format=3 可以覆盖版本,--option label_arrays=false 跳过标签数组。每个标签数组存储只有一个 labels/ 组,大多数查看器无法单独打开它。请把 labels/<schema>__<user> 复制到源图像的 labels/ 目录中,并把这个名称加入源图像 labels/ 组的 labels 列表。标签数组需要 zarr-python,以及位于 media_directory 下的源图像。缺少 zarr-python 或源图像时,导出只写出 GeoJSON 和 CSV,并列出一条警告。
Potato 的一致性指标不覆盖 microscopy 方案。逐细胞的一致性可以在导出后从 microscopy_cells.csv 计算,做法是按 instance_id、label_image 和 label_id 匹配行,再对匹配上的类别计算 Fleiss' kappa 或 Cohen's kappa。
全切片病理图像
SVS、NDPI、MRXS 以及 openslide 可读的其他切片格式的明场全切片扫描,使用深度缩放查看器中的 image_annotation 方案,并需要 wsi 可选依赖。microscopy 方案不能打开 SVS、NDPI 或 MRXS 文件。从 Potato 2.13 起,全切片图像上的区域可以用 potato import -i case_01.geojson --image-dir /data/slides -o case-project 从 QuPath GeoJSON 或 ASAP XML 导入。导入器会自动检测格式,也可以用 -f qupath_geojson 或 -f asap_xml 显式指定。导入的区域成为预标注。标注者绘制的区域可以用 python -m potato.export -c config.yaml -f qupath_geojson -o out/qupath 以 0 级切片像素坐标导出回 QuPath GeoJSON,-f asap_xml 则改为写出 ASAP XML。
示例
python potato/flask_server.py start examples/image/multichannel-microscopy/config.yaml -p 8000这个示例有两幅合成图像。一幅是 OME-Zarr 0.5 存储,含三个通道、三个 z 切片和一个 labels/cells 组;另一幅是 OME-TIFF,含三个通道、三个时间点和一个单独的标签 TIFF。同一目录下的 generate_data.py 会生成这两幅图像。
用编程智能体搭建研究
potato-skill 1.2.0 面向 Potato 2.13.1,认得 microscopy 这个名称,并指导研究设计这一侧,例如向标注者问什么、每幅图像由几名标注者分类、培训和注意力检查,以及导出。这个技能目前还没有记录 OME-Zarr 和 OME-TIFF 数据格式、方案选项和 microscopy 可选依赖。安装 potato-skill,把研究描述给你的智能体,再让智能体参考本页的 Markdown 副本 https://www.potatoannotator.com/docs/annotation-types/microscopy.md,以了解格式和选项。
延伸阅读
- 图像标注 - 普通图像上的框、多边形和掩码
- 基于深度缩放的十亿像素图像标注 - 瓦片金字塔与全切片图像
- 导出格式 - Potato 的导出格式和导出命令
- 你需要多少位标注者? - 为每个条目选择标注者人数
- 生命科学 - 用 Potato 做生命科学与生物审编
有关实现细节,请参阅源文档。