Modular online patch streaming from whole-slide images for computational pathology.
Stream patches directly from WSIs during training — no disk pre-extraction, no storage overhead. Every component is pluggable: backends, tissue detectors, samplers, filters, transforms, views, dataset adapters.
Install
pip install "wsistream[openslide]" # with OpenSlide
pip install "wsistream[tiffslide]" # with TiffSlide (pure Python)
pip install "wsistream[torch]" # add PyTorch integration (WsiStreamDataset, DDP)
pip install "wsistream[all]" # everything (OpenSlide + TiffSlide + PyTorch + albumentations + matplotlib)
For development:
git clone https://github.com/RamonKaspar/wsistream.git
cd wsistream
pip install -e ".[dev]"
Documentation
Full documentation: ramonkaspar.github.io/wsistream
To build locally:
pip install mkdocs-material
mkdocs serve # local preview at http://127.0.0.1:8000
How it works
Each slide goes through a fixed pipeline:
- Open slide: via an explicit backend (
OpenSlideBackendorTiffSlideBackend) - Detect tissue: run a
TissueDetectoron a low-res thumbnail to get a binary mask - Sample coordinates: a
PatchSamplerproposes (x, y) locations within tissue regions - Extract patch: read the pixel data from the slide at each coordinate
- Filter patch: a
PatchFilteraccepts or rejects the tile based on its pixels - Transform patch: apply augmentations (
HEDColorAugmentation,RandomFlipRotate, etc.) or produce named multi-view outputs - Yield result:
PatchResultwith image (single-view) or named views (multi-view), coordinates, tissue fraction, and metadata
Quick start
from wsistream.pipeline import PatchPipeline
from wsistream.backends import OpenSlideBackend
from wsistream.tissue import CLAMTissueDetector
from wsistream.sampling import RandomSampler
from wsistream.filters import HSVPatchFilter
from wsistream.transforms import ComposeTransforms, HEDColorAugmentation, RandomFlipRotate, ResizeTransform
from wsistream.datasets import TCGAAdapter
pipeline = PatchPipeline(
slide_paths="/data/tcga", # directory or list of files
backend=OpenSlideBackend(),
tissue_detector=CLAMTissueDetector(),
sampler=RandomSampler(patch_size=256, num_patches=-1, target_mpp=0.5),
patch_filter=HSVPatchFilter(min_pixel_fraction=0.6),
transforms=ComposeTransforms(transforms=[
HEDColorAugmentation(sigma=0.05),
RandomFlipRotate(),
ResizeTransform(target_size=224),
]),
dataset_adapter=TCGAAdapter(),
pool_size=8,
patches_per_slide=100,
cycle=True,
)
for result in pipeline:
print(result.image.shape) # (224, 224, 3) uint8
print(result.coordinate.mpp) # ~0.5
print(result.tissue_fraction) # 0.87
print(result.slide_metadata.patient_id) # TCGA-3L-AA1B
Pool-based slide interleaving
The pipeline keeps pool_size slides open simultaneously and takes patches_per_slide patches from each before closing it and opening the next. With cycle=True, slides are re-queued for infinite streaming. Set patches_per_visit (default 1) to read multiple patches from the same slide before round-robining, which can significantly improve I/O throughput on network filesystems.
PyTorch integration
wsistream.torch provides WsiStreamDataset (an IterableDataset), MonitoredLoader for throughput tracking, and partition_slides_by_rank for DDP. Worker-level slide partitioning is handled automatically.
from torch.utils.data import DataLoader
from wsistream.backends import OpenSlideBackend
from wsistream.sampling import RandomSampler
from wsistream.tissue import OtsuTissueDetector
from wsistream.torch import WsiStreamDataset, partition_slides_by_rank
my_slides = partition_slides_by_rank("/data/tcga", rank=rank, world_size=world_size)
dataset = WsiStreamDataset(
slide_paths=my_slides,
backend=OpenSlideBackend(),
tissue_detector=OtsuTissueDetector(),
sampler=RandomSampler(patch_size=256, num_patches=-1, target_mpp=0.5),
)
loader = DataLoader(dataset, batch_size=64, num_workers=4, pin_memory=True)
loader_iter = iter(loader)
for step in range(total_steps):
batch = next(loader_iter)
images = batch["image"].to(device, non_blocking=True) # (B, 3, H, W) float32
Metadata
Release files for wsistream 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wsistream-0.1.6.tar.gz | 10.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wsistream-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.0 MB
Release files / wsistream-0.1.6.tar.gz
| Download URL | wsistream-0.1.6.tar.gz |
|---|---|
| Size | 10.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
58be1370354774045f2b3be608499436e19b313ad6836ca92966d6d7a155aa29
|
|
BLAKE2b-256 checksum How to use checksums |
783cc4f947667c52c0f400b7ac068f24dc73fa0db5afee3b2fda2c8cadf00221
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / wsistream-0.1.6-py3-none-any.whl
| Download URL | wsistream-0.1.6-py3-none-any.whl |
|---|---|
| Size | 75.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
657e9613ce891fb6a9e5052a6149f7013bc7b638296457df865ac192617880c5
|
|
BLAKE2b-256 checksum How to use checksums |
cc2277f642ecc2160f24d2ead94fc624b9e89945673cd81f7b1c71a70ecc07db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|