Pure Python MRXS (3DHISTECH MIRAX) whole-slide image reader with OpenSlide-compatible API
Project description
MRXSSlide
纯 Python 实现的 MRXS(3DHISTECH MIRAX)数字病理切片读取库,提供与 OpenSlide 完全兼容的 API
✨ 特性 • 📦 安装 • 🚀 快速开始 • 📖 API • ⚡ 性能
✨ 特性
- 🐍 纯 Python 实现 — 仅依赖 Pillow,零原生依赖,跨平台开箱即用
- 🔄 OpenSlide 兼容 API — 可直接替换
openslide-python,无需修改业务代码 - ⚡ 并行解码 + LRU 帧缓存 — 多线程解码 JPEG/PNG 帧,重复读取显著加速
- 📁 支持直接传数据目录 —
.mrxs主文件缺失时可直接打开同名数据目录 - 🔺 金字塔多层级读取 — 自动解析 MRXS 全部缩放层级(含由底层帧派生的高层级)
- 🖼️ 关联图像读取 — 支持 macro、label、thumbnail
- 📊 完整元数据支持 — MPP、扫描倍率、背景色及全部 INI 键(
mirax.GROUP.KEY) - 🧪 实验性 JPEG-XR 支持 —
pip install mrxsslide[jxr](基于 imagecodecs)
📦 安装
使用 uv(推荐)
uv pip install mrxsslide
使用 pip
pip install mrxsslide
仅依赖 Pillow,任何平台都能直接安装。
JPEG-XR 支持(实验性)
MRXS 切片也可能使用 JPEG-XR 压缩,需安装可选依赖:
pip install mrxsslide[jxr]
开发环境
uv sync --extra dev --extra batch
dev 含测试/ lint 依赖及 openslide 对比测试所需的 openslide-python +
openslide-bin(C 库);batch 含 read_regions_batch 与
tests/test_batch.py 所需的 numpy。缺 batch 时批量测试会在收集期
ImportError,缺 openslide-bin 时 17 个 openslide 对比测试会被静默 skip。
🚀 快速开始
作为 OpenSlide 的 drop-in 替代品
import mrxsslide as openslide
slide = openslide.OpenSlide("path/to/sample.mrxs")
print(f"层级数: {slide.level_count}")
print(f"Level 0 尺寸: {slide.dimensions}")
for i in range(slide.level_count):
print(f" Level {i}: {slide.level_dimensions[i]} "
f"downsample={slide.level_downsamples[i]}")
# 读取区域(location 为 level 0 坐标,返回 RGBA)
img = slide.read_region((100000, 100000), 0, (512, 512))
img.save("region.png")
# 缩略图
thumb = slide.get_thumbnail((512, 512))
thumb.save("thumbnail.png")
# 关联图像
macro = slide.associated_images["macro"]
macro.save("macro.png")
# 属性读取
vendor = slide.properties[openslide.PROPERTY_NAME_VENDOR]
mpp_x = slide.properties[openslide.PROPERTY_NAME_MPP_X]
slide.close()
上下文管理器
with openslide.OpenSlide("sample.mrxs") as slide:
img = slide.read_region((0, 0), 0, (256, 256))
# 自动 close
批量读取
ML pipeline 按批量读 patch 时,read_regions_batch 把所有坐标命中的
缺失帧合并为一次并行解码,并直接返回 numpy ndarray。适用场景:解码/磁盘
开销占主导(冷页缓存、大帧、JPEG-XR)或下游需要 ndarray 形态;小帧 +
热页缓存场景下不优于逐次 read_region。
结果第 i 项与 read_region(locs[i], level, size) 逐像素一致。
需要可选依赖 numpy:pip install mrxsslide[batch]。
locs = [(50000, 90000), (20000, 3000), (500, 60000)]
batch = slide.read_regions_batch(locs, 0, (512, 512))
print(batch.shape, batch.dtype) # (3, 512, 512, 4) uint8
# mode="RGB":透明区合成到 openslide.background-color 背景色上
rgb = slide.read_regions_batch(locs, 0, (512, 512), mode="RGB")
print(rgb.shape) # (3, 512, 512, 3)
直接打开数据目录
.mrxs 主文件丢失或仅拷贝了数据目录时,可直接传入目录路径:
slide = openslide.OpenSlide("path/to/sample") # 与 sample.mrxs 同名的数据目录
命令行示例
python examples/read_region.py sample.mrxs 100000 100000 0 512 512
📖 API 参考
OpenSlide(filename, max_workers=0)
打开一个 MRXS 切片(.mrxs 文件或同名数据目录)。
max_workers=0 表示自动选择解码线程数(最多 16)。
类方法
| 方法 | 说明 |
|---|---|
OpenSlide.detect_format(filename) |
检测文件格式,返回 "mirax" 或 None |
属性
| 属性 | 类型 | 说明 |
|---|---|---|
level_count |
int |
金字塔层级数 |
dimensions |
(int, int) |
Level 0 尺寸(最高分辨率) |
level_dimensions |
Tuple[(w, h), ...] |
每层尺寸 |
level_downsamples |
Tuple[float, ...] |
每层下采样倍数 |
properties |
Mapping[str, str] |
元数据属性(只读映射) |
associated_images |
Mapping[str, PIL.Image] |
关联图像:macro、label、thumbnail |
color_profile |
object | None |
ICC 颜色配置文件(当前返回 None) |
方法
| 方法 | 说明 |
|---|---|
read_region(location, level, size) |
读取指定区域,返回 RGBA 图像 |
read_regions_batch(locations, level, size, mode="RGBA") |
批量读取,返回 numpy (N, h, w, C) uint8(需 mrxsslide[batch]) |
get_best_level_for_downsample(downsample) |
根据下采样倍数选择最佳层级 |
get_thumbnail(size) |
生成缩略图(RGB,LANCZOS 重采样) |
set_cache(cache) |
API 兼容方法(当前为 no-op) |
close() |
关闭并释放资源 |
属性常量
from mrxsslide import (
PROPERTY_NAME_VENDOR, # "openslide.vendor"
PROPERTY_NAME_MPP_X, # "openslide.mpp-x"
PROPERTY_NAME_MPP_Y, # "openslide.mpp-y"
PROPERTY_NAME_OBJECTIVE_POWER, # "openslide.objective-power"
PROPERTY_NAME_BACKGROUND_COLOR, # "openslide.background-color"
PROPERTY_NAME_BOUNDS_X, # "openslide.bounds-x"
PROPERTY_NAME_BOUNDS_Y, # "openslide.bounds-y"
PROPERTY_NAME_BOUNDS_WIDTH, # "openslide.bounds-width"
PROPERTY_NAME_BOUNDS_HEIGHT, # "openslide.bounds-height"
PROPERTY_NAME_QUICKHASH1, # "openslide.quickhash-1"
)
异常
OpenSlideError、OpenSlideUnsupportedFormatError(与 openslide-python 同名),
以及对应别名 MrxsError、MrxsOpenError、MrxsUnsupportedFormatError。
⚡ 性能
与 OpenSlide(C 实现)读取同一 MRXS 文件对比(测试脚本见
benchmarks/compare_mrxs_openslide.py):
| 场景 | mrxsslide | OpenSlide | 加速比 |
|---|---|---|---|
| 随机读取 50 × 512×512(level 0) | 0.02 s | 0.10 s | 6.2× |
| 同 50 区域第二遍(LRU 帧缓存热) | 0.02 s | 0.12 s | 6.6× |
| 重复读取同一区域 ×50(LRU 缓存) | 0.01 s | 0.03 s | 2.2× |
| 顺序扫描 400 × 256×256(level 4) | 1.5 s | 1.6 s | 1.2× |
测试文件:
1053891-15 pou2F3.mrxs(83,379 × 185,672,9 层,JPEG 压缩)。
环境:Intel Xeon E5-2678 v3 / Python 3.11 / Pillow 12.3.0 / openslide-python 1.4.6(OpenSlide 4.0.1),测试时机器负载较高。
方法:每个场景 mrxsslide 与 OpenSlide 交替运行 3 次取中位数,共 4 轮取代表值,保证两者面对相同的页缓存热度;该口径下页缓存已被预热,不反映页缓存完全冷的首次读取。
说明:随机与重复读取场景 mrxsslide 明显更快(并行解码 + LRU 帧缓存);顺序扫描场景基本持平(4 轮加速比 0.95–1.21×)。不同样本、压缩格式与硬件会导致差异。
🏗️ 架构
MRXSSlide 完全基于纯 Python 实现,通过直接解析 MRXS 格式完成图像读取:
- 无需任何 C/C++ 扩展或系统动态库
- 不依赖 OpenSlide、libjpeg、openjpeg 等外部库
read_region三阶段流水线:收集命中 tile → 线程池并行解码帧 → 仿射对齐 + alpha 合成- 每个数据文件共享只读 fd +
os.pread,无线程锁 - 适合服务器、容器等不便安装原生依赖的场景
📁 项目结构
mrxsslide/
├── src/mrxsslide/
│ ├── __init__.py # 包入口,导出 OpenSlide API
│ ├── _slide.py # OpenSlide 主类(三阶段 read_region)
│ ├── _mrxsformat.py # MRXS / Slidedat / 索引页解析
│ ├── _codecs.py # JPEG / PNG / JPEG-XR 解码
│ ├── _cache.py # LRU 帧缓存
│ └── _exceptions.py # OpenSlideError / 兼容异常
├── tests/ # 测试(含 sample.mrxs 软链)
├── examples/ # 示例脚本
├── benchmarks/ # 与 OpenSlide 的对比基准
├── scripts/ # 冒烟工具
├── README.md
├── LICENSE
└── pyproject.toml
⚠️ 已知限制
- 只读:目前不支持写入 MRXS 文件。
- JPEG-XR 为实验性:代码路径就绪但缺少真实样本验证。
- 首次冷读未覆盖:基准为页缓存预热后的交替 median-of-3 口径,该口径下 mrxsslide 各场景均不慢于 OpenSlide;页缓存完全冷的首次读取对比暂无数据(详见性能)。
📄 License
Copyright (c) 2026 Yifan Feng
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mrxsslide-0.1.0.tar.gz.
File metadata
- Download URL: mrxsslide-0.1.0.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08a9dd7ca2a9b8fc984d1980fa822f014ef9d5990aafe80908086698ed4cb6b1
|
|
| MD5 |
7ab5b15b697389cd52989281a6a94c5c
|
|
| BLAKE2b-256 |
1a8d0b382ec861f44cb21b106a8c825c32bdade2aab7035b82a62a73ad0cc917
|
Provenance
The following attestation bundles were made for mrxsslide-0.1.0.tar.gz:
Publisher:
publish.yml on yifanfeng97/mrxsslide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mrxsslide-0.1.0.tar.gz -
Subject digest:
08a9dd7ca2a9b8fc984d1980fa822f014ef9d5990aafe80908086698ed4cb6b1 - Sigstore transparency entry: 2256089601
- Sigstore integration time:
-
Permalink:
yifanfeng97/mrxsslide@7cbb8d5170eec70e62567cf885775fecf0efafae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/yifanfeng97
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7cbb8d5170eec70e62567cf885775fecf0efafae -
Trigger Event:
release
-
Statement type:
File details
Details for the file mrxsslide-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mrxsslide-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87d235a3f24078773d75e9d8de7207c5e96c6c523f3ed32210c67b26c174a7a4
|
|
| MD5 |
b2408eefcd4ce29b95a84cf7e4bce865
|
|
| BLAKE2b-256 |
37ea83c7d1e71f38bb3803b905278163af0d19f43b561804f9e58f14ec03ff90
|
Provenance
The following attestation bundles were made for mrxsslide-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on yifanfeng97/mrxsslide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mrxsslide-0.1.0-py3-none-any.whl -
Subject digest:
87d235a3f24078773d75e9d8de7207c5e96c6c523f3ed32210c67b26c174a7a4 - Sigstore transparency entry: 2256089605
- Sigstore integration time:
-
Permalink:
yifanfeng97/mrxsslide@7cbb8d5170eec70e62567cf885775fecf0efafae -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/yifanfeng97
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7cbb8d5170eec70e62567cf885775fecf0efafae -
Trigger Event:
release
-
Statement type: