histolab-wsi-processing について
histolab-wsi-processingは、計算病理研究者向けのPython製全スライド画像処理ライブラリです。組織検出、タイル抽出、前処理に加え、タイルの品質スコアリングにも対応します。
主な機能
- 01組織領域の検出とマスク処理
- 02ランダム・グリッド・スコア式タイル抽出
- 03組み合わせ可能な画像・形態学フィルター
- 04核密度や細胞性によるタイル評価
- 05スライド・マスク・タイルの可視化
活用シーン
- 01モデル学習用タイルデータセットの作成
- 02スライド確認用の組織領域サンプリング
- 03スライドの背景やアーティファクトの除去
- 04複数スライド間でのタイル品質比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill histolab-wsi-processingインストール後、Claude Code で/histolab-wsi-processingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/filters_preprocessing.mdtile_extraction.mdvisualization_slides.md詳細
Histolab による WSI 処理
概要
Histolab は、デジタル病理学における全スライド画像(WSI)を処理するための Python ライブラリです。組織検出を自動化し、複数の方法でギガピクセル画像から有用なタイルを抽出できるほか、前処理用に組み合わせ可能なフィルターパイプラインを提供します。OpenSlide を介して、SVS、TIFF、NDPI などの WSI 形式を処理します。
使用する場面
- 深層学習モデルのトレーニング用に、全スライド画像からタイルを抽出する
- 組織領域を検出し、組織病理スライドの背景やアーティファクトを除去する
- H&E または IHC 染色組織切片の前処理パイプラインを構築する
- 核密度や細胞密度に基づいて順位付けした、品質重視のタイルデータセットを作成する
- 一貫したパラメーターでスライドのコレクション全体からタイルを一括抽出する
- 計算病理学のワークフローに先立って、スライドの品質と組織の被覆率を評価する
- タイル抽出を行わずにスライドへ直接アクセスする場合は、
openslide-pythonを直接使用してください - 複雑な多重化イメージングや空間プロテオミクスのパイプラインには、代わりに
pathmlを使用してください
前提条件
- Python パッケージ:
histolab(OpenSlide の Python バインディングを含む) - システム依存関係:OpenSlide C ライブラリを別途インストールする必要があります
- 対応形式:SVS、TIFF、NDPI、VMS、SCN、MRXS(OpenSlide 経由)
# macOS
brew install openslide
pip install histolab
# Ubuntu/Debian
sudo apt-get install openslide-tools
pip install histolab
クイックスタート
from histolab.slide import Slide
from histolab.tiler import RandomTiler
# Load slide
slide = Slide("slide.svs", processed_path="output/")
print(f"Dimensions: {slide.dimensions}, Levels: {slide.levels}")
# Configure tiler
tiler = RandomTiler(
tile_size=(512, 512), n_tiles=100, level=0, seed=42,
check_tissue=True, tissue_percent=80.0
)
# Preview and extract
tiler.locate_tiles(slide, n_tiles=20)
tiler.extract(slide)
コア API
モジュール 1:スライド管理
Slide クラスは、WSI ファイルの読み込みと検査に使用する主要なインターフェースです。
from histolab.slide import Slide
from histolab.data import prostate_tissue
# Load from built-in sample data (prostate, ovarian, breast, heart, kidney)
prostate_svs, prostate_path = prostate_tissue()
slide = Slide(prostate_path, processed_path="output/")
# Inspect properties
print(f"Dimensions: {slide.dimensions}") # (width, height) at level 0
print(f"Levels: {slide.levels}") # Number of pyramid levels
print(f"Level dims: {slide.level_dimensions}") # Dimensions per level
print(f"Magnification: {slide.properties.get('openslide.objective-power', 'N/A')}")
print(f"MPP-X: {slide.properties.get('openslide.mpp-x', 'N/A')}")
# Thumbnail and scaled image
slide.save_thumbnail() # Saves to processed_path
scaled = slide.scaled_image(scale_factor=32)
# Extract region at specific coordinates
region = slide.extract_region(location=(1000, 2000), size=(512, 512), level=0)
モジュール 2:組織検出
マスククラスは組織領域を特定し、タイル抽出時に背景を除外します。
from histolab.masks import TissueMask, BiggestTissueBoxMask, BinaryMask
import numpy as np
# TissueMask: segments ALL tissue regions (multiple sections)
tissue_mask = TissueMask()
mask_array = tissue_mask(slide) # Binary NumPy array: True=tissue, False=background
print(f"Tissue coverage: {mask_array.sum() / mask_array.size * 100:.1f}%")
# BiggestTissueBoxMask: bounding box of largest tissue region (default)
biggest_mask = BiggestTissueBoxMask()
# Visualize mask on slide thumbnail
slide.locate_mask(tissue_mask)
# Custom mask via BinaryMask subclass
class RectangularROI(BinaryMask):
def __init__(self, x, y, w, h):
self.x, self.y, self.w, self.h = x, y, w, h
def _mask(self, slide):
thumb = slide.thumbnail
mask = np.zeros(thumb.shape[:2], dtype=bool)
mask[self.y:self.y+self.h, self.x:self.x+self.w] = True
return mask
モジュール 3:タイル抽出
タイルを抽出する 3 つの方法として、ランダムサンプリング、グリッドによる網羅、スコアに基づく選択があります。
from histolab.tiler import RandomTiler, GridTiler, ScoreTiler
from histolab.scorer import NucleiScorer
from histolab.masks import TissueMask
# RandomTiler: fixed number of randomly positioned tiles
random_tiler = RandomTiler(
tile_size=(512, 512), n_tiles=100, level=0,
seed=42, check_tissue=True, tissue_percent=80.0
)
random_tiler.locate_tiles(slide, n_tiles=20) # Preview first
random_tiler.extract(slide)
# GridTiler: systematic grid coverage
grid_tiler = GridTiler(
tile_size=(512, 512), level=0,
pixel_overlap=0, check_tissue=True, tissue_percent=70.0
)
grid_tiler.extract(slide, extraction_mask=TissueMask())
# ScoreTiler: top-ranked tiles by scoring function
score_tiler = ScoreTiler(
tile_size=(512, 512), n_tiles=50, level=0,
scorer=NucleiScorer(), check_tissue=True
)
score_tiler.extract(slide, report_path="tiles_report.csv")
# Report CSV: tile_name, x_coord, y_coord, level, score, tissue_percent
モジュール 4:フィルターと前処理
組織検出と前処理に使用できる、組み合わせ可能な画像フィルターと形態学的フィルターです。
from histolab.filters.image_filters import (
RgbToGrayscale, RgbToHsv, RgbToHed,
OtsuThreshold, AdaptiveThreshold,
StretchContrast, HistogramEqualization, Invert
)
from histolab.filters.morphological_filters import (
BinaryDilation, BinaryErosion, BinaryOpening, BinaryClosing,
RemoveSmallObjects, RemoveSmallHoles
)
from histolab.filters.compositions import Compose
# Standard tissue detection pipeline
tissue_pipeline = Compose([
RgbToGrayscale(),
OtsuThreshold(),
BinaryDilation(disk_size=5),
RemoveSmallHoles(area_threshold=1000),
RemoveSmallObjects(area_threshold=500)
])
# Use custom pipeline with TissueMask
from histolab.masks import TissueMask
custom_mask = TissueMask(filters=tissue_pipeline)
# Stain deconvolution (H&E)
hed_filter = RgbToHed() # Hematoxylin-Eosin-DAB separation
# Apply filters to individual tiles
from histolab.tile import Tile
filter_chain = Compose([RgbToGrayscale(), StretchContrast()])
filtered_tile = tile.apply_filters(filter_chain)
# Lambda for custom inline filters
from histolab.filters.image_filters import Lambda
import numpy as np
brightness = Lambda(lambda img: np.clip(img * 1.2, 0, 255).astype(np.uint8))
red_channel = Lambda(lambda img: img[:, :, 0])
モジュール 5:スコアリング
スコアラーはタイルの組織内容の品質を評価し、ScoreTiler で使用するために順位付けします。
from histolab.scorer import NucleiScorer, CellularityScorer, Scorer
import numpy as np
# Built-in scorers
nuclei = NucleiScorer() # Scores by nuclei density (grayscale threshold + count)
cellularity = CellularityScorer() # Scores by overall cellular content
# Custom scorer
class ColorVarianceScorer(Scorer):
def __call__(self, tile):
"""Score tiles by color variance (higher = more informative)."""
tile_array = np.array(tile.image)
return np.var(tile_array, axis=(0, 1)).sum()
score_tiler = ScoreTiler(
tile_size=(512, 512), n_tiles=30,
scorer=ColorVarianceScorer()
)
モジュール 6:可視化
スライド、マスク、タイルの確認に使用できる組み込みメソッドと matplotlib のパターンです。
import matplotlib.pyplot as plt
from histolab.masks import TissueMask
# Built-in: mask overlay on slide thumbnail
slide.locate_mask(TissueMask())
# Built-in: tile location preview
tiler.locate_tiles(slide, n_tiles=20)
# Manual side-by-side: slide vs mask
mask = TissueMask()
mask_array = mask(slide)
fig, axes = plt.subplots(1, 2, figsize=(15, 7))
axes[0].imshow(slide.thumbnail); axes[0].set_title("Slide"); axes[0].axis('off')
axes[1].imshow(mask_array, cmap='gray'); axes[1].set_title("Mask"); axes[1].axis('off')
plt.tight_layout()
plt.show()
# Display extracted tiles in grid
from pathlib import Path
from PIL import Image
tile_paths = list(Path("output/tiles/").glob("*.png"))[:16]
fig, axes = plt.subplots(4, 4, figsize=(12, 12))
for idx, tp in enumerate(axes.ravel()):
if idx < len(tile_paths):
tp.imshow(Image.open(tile_paths[idx]))
tp.set_title(tile_paths[idx].stem, fontsize=8)
tp.axis('off')
plt.tight_layout()
plt.show()
主な概念
WSI のピラミッドレベル
全スライド画像は、複数の解像度レベルからなるピラミッド構造を使用します。レベル 0 は最高解像度(ネイティブスキャン)です。レベルが上がるごとに解像度は段階的に低くなり、より高速にアクセスできます。
for level in range(slide.levels):
dims = slide.level_dimensions[level]
downsample = slide.level_downsamples[level]
print(f"Level {level}: {dims}, downsample: {downsample:.0f}x")
# Level 0: (98304, 221184), downsample: 1x
# Level 1: (24576, 55296), downsample: 4x
フィルターを組み合わせるパターン
フィルターは Compose を使って連結するよう設計されています。あるフィルターの出力が、次のフィルターの入力になります。画像フィルターは RGB/グレースケール配列を処理し、形態学的フィルターは二値配列を処理します。順序が重要です。後続のフィルターを適用する前に、必ず想定される入力型へ変換してください。
マスクとタイラーの連携
すべてのタイラーは extraction_mask パラメーターを受け取ります。デフォルトは BiggestTissueBoxMask() です。複数の切片があるスライドでは TissueMask() に、ROI 固有の抽出ではカスタムの BinaryMask サブクラスに置き換えてください。
一般的なワークフロー
ワークフロー 1:スライドの探索的分析
目標:スライドをすばやく確認して組織を検出し、レビュー用に多様な領域をサンプリングします。
from histolab.slide import Slide
from histolab.tiler import RandomTiler
from histolab.masks import TissueMask
import matplotlib.pyplot as plt
import logging
logging.basicConfig(level=logging.INFO)
slide = Slide("slide.svs", processed_path="output/exploratory/")
print(f"Dimensions: {slide.dimensions}, Levels: {slide.levels}")
slide.save_thumbnail()
# Visualize tissue detection
tissue_mask = TissueMask()
slide.locate_mask(tissue_mask)
mask_arr = tissue_mask(slide)
print(f"Tissue coverage: {mask_arr.sum() / mask_arr.size * 100:.1f}%")
# Sample tiles
tiler = RandomTiler(
tile_size=(512, 512), n_tiles=50, level=0,
seed=42, check_tissue=True, tissue_percent=80.0
)
tiler.locate_tiles(slide, n_tiles=20)
tiler.extract(slide)
ワークフロー 2:深層学習データセットの準備
目標:モデルのトレーニング用に、複数のスライドから品質管理されたタイルデータセットを構築します。
from pathlib import Path
from histolab.slide import Slide
from histolab.tiler import ScoreTiler
from histolab.scorer import NucleiScorer
import pandas as pd
import logging
logging.basicConfig(level=logging.INFO)
slide_dir = Path("slides/")
output_base = Path("output/dataset/")
all_reports = []
tiler = ScoreTiler(
tile_size=(512, 512), n_tiles=100, level=0,
scorer=NucleiScorer(), check_tissue=True, tissue_percent=80.0
)
for slide_path in sorted(slide_dir.glob("*.svs")):
out_dir = output_base / slide_path.stem
out_dir.mkdir(parents=True, exist_ok=True)
slide = Slide(str(slide_path), processed_path=str(out_dir))
slide.save_thumbnail()
report_path = str(out_dir / "report.csv")
tiler.extract(slide, report_path=report_path)
df = pd.read_csv(report_path)
df["slide"] = slide_path.stem
all_reports.append(df)
print(f"{slide_path.stem}: {len(df)} tiles, mean score {df['score'].mean():.3f}")
combined = pd.concat(all_reports, ignore_index=True)
combined.to_csv(output_base / "dataset_manifest.csv", index=False)
print(f"Total: {len(combined)} tiles from {len(all_reports)} slides")
ワークフロー 3:アーティファクト除去を伴うカスタム組織検出
目標:カスタムのフィルターパイプラインを使用して、ペンによる注釈や通常とは異なる染色のあるスライドを処理します。
from histolab.slide import Slide
from histolab.masks import TissueMask
from histolab.tiler import GridTiler
from histolab.filters.compositions import Compose
from histolab.filters.image_filters import RgbToGrayscale, OtsuThreshold
from histolab.filters.morphological_filters import (
BinaryDilation, RemoveSmallObjects, RemoveSmallHoles
)
# Aggressive artifact removal pipeline
aggressive_filters = Compose([
RgbToGrayscale(),
OtsuThreshold(),
BinaryDilation(disk_size=10),
RemoveSmallHoles(area_threshold=5000),
RemoveSmallObjects(area_threshold=3000)
])
custom_mask = TissueMask(filters=aggressive_filters)
slide = Slide("artifact_slide.svs", processed_path="output/clean/")
# Compare default vs custom mask
slide.locate_mask(TissueMask()) # Default
slide.locate_mask(custom_mask) # Custom (tighter)
# Extract with custom mask
grid_tiler = GridTiler(
tile_size=(512, 512), level=1,
check_tissue=True, tissue_percent=70.0
)
grid_tiler.extract(slide, extraction_mask=custom_mask)
主なパラメーター
| パラメーター | モジュール | デフォルト | 範囲/オプション | 効果 |
|---|---|---|---|---|
tile_size | すべてのTiler | (512, 512) | 任意の (w, h) タプル | タイルのピクセル単位の寸法 |
level | すべてのTiler | 0 | 0 から slide.levels-1 | ピラミッドレベル(0=最高解像度) |
check_tissue | すべてのTiler | True | True/False | 組織の含有量に基づいてタイルをフィルタリング |
tissue_percent | すべてのTiler | 80.0 | 0.0~100.0 | 組織被覆率の最小しきい値 |
n_tiles | Random/ScoreTiler | 変動 | 任意の正の整数 | 抽出するタイル数 |
seed | RandomTiler | None | 任意の整数 | 再現性を確保するための乱数シード |
pixel_overlap | GridTiler | 0 | 0以上 | 隣接するタイル間のピクセル単位の重なり |
scorer | ScoreTiler | 必須 | NucleiScorer()、CellularityScorer()、カスタム | タイルの順位付けに使用するスコアリング関数 |
extraction_mask | すべてのTiler | BiggestTissueBoxMask() | 任意の BinaryMask | 有効な抽出領域を定義するマスク |
disk_size | 形態学的フィルター | 5 | 1~20 | 構造要素のサイズ |
area_threshold | RemoveSmall* | 500/1000 | 0以上 | オブジェクト/穴のピクセル単位の最小面積 |
ベストプラクティス
-
抽出前に必ずプレビューする:本格的な抽出を開始する前に、
locate_tiles()とlocate_mask()を呼び出して設定を検証してください。大規模なスライドコレクションでは、これにより何時間もの時間を節約できます。 -
レベルを解析解像度に合わせる:レベル0では最大限の詳細を得られますが、処理は低速です。初期解析には通常、レベル1~2で十分です。細胞レベルの詳細が必要なタスクに限り、レベル0を使用してください。
-
適切なタイル化戦略を選ぶ:
RandomTilerは探索的解析や多様なサンプリングに使用しますGridTilerは全体をカバーする場合や空間解析に使用しますScoreTilerは品質を重視したデータセットのキュレーションに使用します
-
再現性のためにシードを使用する:実行間で一貫したタイル選択を行うため、
RandomTilerでは必ずseedを設定してください。 -
特定の染色に合わせてマスクをカスタマイズする:H&E染色とIHC染色では色のプロファイルが異なります。標準以外の染色では、フィルターパラメーターを調整するか、カスタムの
Composeパイプラインを構築してください。 -
アンチパターン —
BiggestTissueBoxMaskで十分な場合にTissueMaskを使わない:TissueMaskは計算コストが高くなります。スライドに複数の組織切片がある場合に限り使用してください。 -
バッチ処理ではロギングを有効にする:
logging.basicConfig(level=logging.INFO)を設定すると、抽出中の進捗を確認できます。 -
ScoreTilerでCSVレポートを生成する:
extract()でreport_pathを使用すると、後続のMLパイプライン向けのメタデータマニフェストを作成できます。 -
アンチパターン — 初期の探索でレベル0から抽出しない:素早く反復するにはレベル1または2を使用し、その後、最終的なデータセットを生成する際にレベル0に切り替えてください。
よく使うレシピ
レシピ:核の強調パイプライン
使用場面:解析用に、H&E染色切片から核シグナルを分離して強調します。
from histolab.filters.image_filters import RgbToHed, HistogramEqualization, Lambda
from histolab.filters.compositions import Compose
nuclei_pipeline = Compose([
RgbToHed(),
Lambda(lambda hed: hed[:, :, 0]), # Extract hematoxylin channel
HistogramEqualization()
])
# Apply to slide thumbnail for visualization
enhanced = nuclei_pipeline(slide.thumbnail)
レシピ:スコア分布の解析
使用場面:タイルの品質分布を評価し、最適なスコアしきい値を特定します。
import pandas as pd
import matplotlib.pyplot as plt
report = pd.read_csv("tiles_report.csv")
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].hist(report['score'], bins=30, edgecolor='black', alpha=0.7)
axes[0].set_xlabel('Tile Score'); axes[0].set_ylabel('Frequency')
axes[0].set_title('Score Distribution')
axes[1].scatter(report['tissue_percent'], report['score'], alpha=0.5)
axes[1].set_xlabel('Tissue %'); axes[1].set_ylabel('Score')
axes[1].set_title('Score vs Tissue Coverage')
plt.tight_layout()
plt.savefig("quality_analysis.png", dpi=150, bbox_inches='tight')
plt.show()
レシピ:マルチレベル階層抽出
使用場面:マルチスケール解析のため、同じ位置から複数の倍率レベルでタイルを抽出します。
from histolab.tiler import RandomTiler
for level in [0, 1, 2]:
tiler = RandomTiler(
tile_size=(512, 512), n_tiles=50,
level=level, seed=42, # Same seed = same locations
prefix=f"level{level}_"
)
tiler.extract(slide)
print(f"Extracted level {level} tiles")
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
OpenSlideError: Unsupported format | OpenSlide C ライブラリがインストールされていないか、スライド形式がサポートされていません | OpenSlide システムライブラリをインストールし、openslide-show-properties で形式を確認します |
| タイルが抽出されない | tissue_percent が高すぎるか、マスクが組織を捉えていません | tissue_percent を下げます(60~70% を試してください)。locate_mask() でマスクをプレビューします |
| 背景タイルが多い | check_tissue=False またはマスクの精度が低い | check_tissue=True を有効にし、tissue_percent を上げます。TissueMask() を使用します |
| 抽出が非常に遅い | 大きなスライドでレベル 0 を使用しているか、多数のセクションで TissueMask を使用しています | レベル 1~2 で抽出します。BiggestTissueBoxMask を使用し、n_tiles を減らします |
| タイルにペンの痕跡がある | デフォルトのマスクにペンの痕跡が含まれています | HSV ベースのペン検出を使ってカスタムフィルターを作成し、RemoveSmallObjects のしきい値を上げます |
抽出中に MemoryError が発生する | 非常に大きな WSI でレベル 0 のタイルにアクセスしています | より低いレベルで抽出し、バッチごとに処理するタイル数を減らします |
| 実行ごとに結果が一致しない | RandomTiler に seed が設定されていません | 常に seed パラメーターを設定します |
| タイルがモデルに対して小さすぎる/大きすぎる | tile_size がモデルの入力サイズと一致していません | モデルの要件に合わせて tile_size を調整します(一般的には 224、256、512) |
同梱リソース
references/filters_preprocessing.md
すべての画像フィルター(RgbToGrayscale、RgbToHsv、RgbToHed、OtsuThreshold、AdaptiveThreshold、Invert、StretchContrast、HistogramEqualization、Lambda)と形態学的フィルター(BinaryDilation、BinaryErosion、BinaryOpening、BinaryClosing、RemoveSmallObjects、RemoveSmallHoles)を網羅した包括的なフィルターリファレンスです。個別のコード例、ユースケースの説明、一般的な前処理パイプライン(組織検出、ペン痕の除去、核の強調、染色の正規化)が含まれています。
- 対象範囲:すべてのフィルタータイプの個別コードブロック、
Composeによる連結、品質管理フィルター、カスタムマスクの統合 - 本文に移動:標準的な組織検出パイプラインと Lambda フィルターの基本は、コア API モジュール 4 に移動しました
- 省略:フィルター効果の段階的な可視化手順(references/visualization_slides.md で説明)。ベストプラクティスのリストは一部をメインの「ベストプラクティス」セクションに統合しました
references/tile_extraction.md
3 つのタイル化戦略(RandomTiler、GridTiler、ScoreTiler)すべてを網羅した詳細なタイル抽出リファレンスです。全パラメーターの説明、組み込みスコアラー(NucleiScorer、CellularityScorer)の一覧、カスタムスコアラーの作成、ログ記録と CSV レポートを含む抽出ワークフロー、高度なパターン(マルチレベル、階層型、抽出後のぼかしフィルタリング)を説明しています。
- 対象範囲:各タイル化方式のパラメーターとユースケース、スコアラー API、タイルのプレビュー、レポート付き抽出、高度なパターン、パフォーマンス最適化
- 本文に移動:タイル化の基本的な使い方とスコアラーの作成は、コア API モジュール 3 および 5 に移動しました。一般的なパラメーターの表は「主要パラメーター」に移動しました
- 省略:ASCII のグリッドパターン図(簡単な視覚的補助のため)
references/visualization_slides.md
可視化、スライド管理、組織マスクに関するリファレンスを統合したものです。スライドの検査ワークフロー、マスク比較の可視化、タイルグリッド表示、品質評価(スコア分布、上位/下位タイルの比較)、複数スライドのコレクションサムネイル、組織のカバレッジ棒グラフ、フィルター効果の可視化パイプライン、PDF レポートの生成、インタラクティブな Jupyter ウィジェットを扱います。
- 出典: visualization.md(547 行)+ slide_management.md(172 行)を統合
- 対象: 元のすべての可視化パターン、スライド検査ワークフロー、サンプルデータセット、ピラミッドレベルの列挙、マスククラスとカスタマイズ、アノテーション除外パターン
- インラインの配置変更: スライドの基本プロパティとマスクの基本事項を Core API Modules 1-2 に移動、サムネイル表示と基本的な locate_mask/locate_tiles を Module 6 に移動
- 省略: スライド名/パスの単純なプロパティ(2 行)、手動で座標を計算するカスタムタイル位置の可視化(概念的な説明のみで、実用性がないため)
元のリファレンスファイルの扱い(5 ファイル):
- slide_management.md(172 行)――(b)統合:基本的な内容を Core API Module 1(Slide クラス、プロパティ、サンプルデータ、サムネイル、領域、ピラミッドレベル)に統合し、高度なスライド検査と複数スライドのワークフローを references/visualization_slides.md に統合
- tissue_masks.md(251 行)――(b)統合:マスクの基本クラスと使い方を Core API Module 2 に統合し、カスタムマスク(RectangularMask、AnnotationExclusionMask)とマスク比較を references/visualization_slides.md に統合
- tile_extraction.md(421 行)――(a)references/tile_extraction.md に移行し、内容を簡潔化
- filters_preprocessing.md(514 行)――(a)references/filters_preprocessing.md に移行し、内容を簡潔化
- visualization.md(547 行)――(a)references/visualization_slides.md に移行し、slide_management.md と tissue_masks.md の内容を統合
関連スキル
- pathml-spatial-omics(予定)――高度な多重イメージングと空間プロテオミクス
- matplotlib-scientific-plotting――histolab の出力から出版品質の図を生成
参考資料
- Histolab ドキュメント――公式の API リファレンスとチュートリアル
- Histolab GitHub リポジトリ――ソースコードとサンプル
- OpenSlide――WSI 形式をサポートする基盤の C ライブラリ
- TCGA サンプルデータ――組み込みサンプルデータセットの提供元