正面胸部 X 線画像から 肺結節 を検出する教育用プロトタイプです。PyTorch + Ultralytics YOLO で学習・推論し、Streamlit で結果を表示します。検出ビューアは React + TypeScript の Streamlit カスタムコンポーネントで、画像上の bbox オーバーレイ・ズーム/パン・信頼度フィルタ・選択詳細パネルを提供します(推論ロジックは Python 側のまま)。
免責事項: 研究・教育目的のみです。臨床診断や患者ケアの判断には使用しないでください。
-
Python 3.11 以上
-
依存関係は
requirements.txtを参照 -
Streamlit ビューアの UI を変更する場合のみ Node.js 18+ と
npm(frontend/のビルド用。実行時はビルド済みbuild/を使用)
cxr-nodule-detector/
├── configs/
│ ├── train_node21.yaml # 学習ハイパーパラメータ
│ └── app.yaml # Streamlit / 推論のデフォルト
├── data/
│ ├── raw/ # 公開データセットを手動配置(自動ダウンロードなし)
│ └── processed/ # YOLO 用 images / labels / dataset.yaml
├── src/cxr_nodule/ # コアライブラリ
├── src/cxr_nodule/app/ # Streamlit アプリ
│ └── components/cxr_viewer/ # React + TS 検出ビューア(frontend/)
├── scripts/ # データセットレイアウト補助
└── tests/
cd cxr-nodule-detector
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements-cpu.txt
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"
NVIDIA GPU(CUDA 13.2)
pip install -r requirements-cuda132.txt
# または
bash scripts/install_cuda132.sh
公式 PyTorch ホイールは cu132 インデックス(同梱ランタイム CUDA 13.2)です。pip install -r requirements.txt のみだと PyTorch は入らないため、GPU 利用時は上記を使ってください。
cd cxr-nodule-detector
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements-cpu.txt
$env:PYTHONPATH = "$PWD\src"
NVIDIA GPU(CUDA 13.2)
pip install -r requirements-cuda132.txt
# または
.\scripts\install_cuda132.ps1
PowerShell で
Activate.ps1が拒否される場合:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
本リポジトリはデータセットを 自動ダウンロードしません。NODE21 など公開データセットを公式配布元から入手し、利用規約に同意したうえで配置してください。
-
生データ — 入手した配布形式に合わせて配置(例):
data/raw/node21/ -
YOLO 学習用レイアウト — 雛形を作成:
Linux / macOS
export PYTHONPATH="${PWD}/src:${PYTHONPATH}" python scripts/prepare_yolo_layout.py
Windows(PowerShell)
$env:PYTHONPATH = "$PWD\src" python scripts/prepare_yolo_layout.py
その後、例えば次のように配置:
data/processed/ ├── images/train/*.png ├── images/val/*.png ├── labels/train/*.txt # YOLO: class cx cy w h(正規化) ├── labels/val/*.txt └── dataset.yaml必要に応じて
data/processed/dataset.yaml.exampleをdataset.yamlにコピーするか、スクリプトが生成したファイルを使用します。 -
NODE21 → YOLO — preprocessed 画像(
.mha/.mhd/ PNG 等)とmetadata.csvを配置したうえで変換:-
.mha/.mhdは SimpleITK で読み込み、学習用に PNG へ変換 して保存 -
ラベル
.txtのファイル名は変換後 PNG の stem に合わせる(例:case001.mha→case001.png/case001.txt) -
bbox は
metadata.csvのx,y,width,heightから YOLO 正規化座標へ変換
Linux / macOS
export PYTHONPATH="${PWD}/src:${PYTHONPATH}" python -m cxr_nodule.yolo_format \ --images_dir data/raw/node21/images \ --metadata_csv data/raw/node21/metadata.csv \ --out_dir datasets/node21_yolo \ --seed 42
Windows(PowerShell)
$env:PYTHONPATH = "$PWD\src" python -m cxr_nodule.yolo_format ` --images_dir "data\raw\node21\images" ` --metadata_csv "data\raw\node21\metadata.csv" ` --out_dir "datasets\node21_yolo" ` --seed 42
出力例:
datasets/node21_yolo/ ├── images/{train,val,test}/ ├── labels/{train,val,test}/ # 陰性例は空の .txt └── node21.yamlオプション:
--train_ratio,--val_ratio,--test_ratio,--symlink(コピーの代わりにシンボリックリンク。.mhaは常に PNG 変換) -
-
DICOM — 学習用に PNG へ変換するか、
dicom_utils.load_dicom_as_uint8でパイプラインに組み込んでからエクスポートしてください。
configs/train_node21.yaml が datasets/node21_yolo/node21.yaml(または独自の dataset.yaml)を指し、train / val 画像が存在することを確認してください。
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"
python -m cxr_nodule.train --config configs/train_node21.yaml
$env:PYTHONPATH = "$PWD\src"
python -m cxr_nodule.train --config configs/train_node21.yaml
デフォルトモデルは YOLO11n(yolo11n.pt)です。パラメータは runs/detect/cxr_nodules/train_params.yaml に記録され、最良モデルのパスは best_model_path.txt に保存されます。
GPU: configs/train_node21.yaml と configs/app.yaml の device はデフォルトで auto です。CUDA が利用可能なら GPU(0)、なければ cpu を自動選択します。CUDA 13.2 では pip install -r requirements-cuda132.txt で GPU 版 PyTorch を入れてください。常に CPU のみ使う場合は device: cpu にしてください。
from pathlib import Path
from cxr_nodule.infer import load_image_for_infer, run_inference
from cxr_nodule.visualization import visualize_detections
image = load_image_for_infer(Path("path/to/cxr.dcm")) # .png / .jpg も可
result = run_inference("runs/detect/cxr_nodules/weights/best.pt", image, conf=0.25)
vis = visualize_detections(image, result.detections)
# vis.original は変更されない。vis.overlay に枠と信頼度が描画されるDICOM 入力では必要に応じて MONOCHROME1 反転を行い、8 ビットグレースケールに正規化したうえで YOLO 用に RGB へ変換します。
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"
streamlit run src/cxr_nodule/app/streamlit_app.py
$env:PYTHONPATH = "$PWD\src"
streamlit run src/cxr_nodule/app/streamlit_app.py
ブラウザで表示される URL(通常 http://localhost:8501)を開きます。
正面胸部 X 線(PNG / JPEG / DICOM)をアップロードし、サイドバーで 推論用の信頼度しきい値 を調整して 推論を実行 をクリックします。原画像のほか、React 検出ビューア(インタラクティブな bbox 表示)と検出一覧表が表示されます。研究用途のみである旨の警告が常に表示されます。
推論後、cxr_viewer カスタムコンポーネントが原画像と検出結果を表示します(infer.py の推論処理は変更しません)。
| 機能 | 説明 |
|---|---|
| bbox オーバーレイ | 正規化座標 [x1, y1, x2, y2] で矩形を重ね表示 |
| 表示用しきい値 | ビューア内スライダーで表示をリアルタイムフィルタ(再推論不要) |
| 検出一覧パネル | 右ペインで一覧表示・クリック選択 |
| 選択パネル | 信頼度・正規化/ピクセル座標を表示 |
| ズーム/パン | ホイールでズーム、ドラッグでパン |
Python からは base64 画像(または URL)と result.to_records()(ピクセル xyxy)を渡し、ラッパーがコンポーネント用 JSON に変換します。
フロントエンドを編集した場合(Linux / macOS):
cd src/cxr_nodule/app/components/cxr_viewer/frontend
npm install
npm run buildWindows(PowerShell):
cd src\cxr_nodule\app\components\cxr_viewer\frontend
npm install
npm run buildビルド成果物は frontend/build/ に出力されます。Python API から静的オーバーレイ画像が必要な場合は、引き続き visualize_detections() を利用できます。
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"
pytest
$env:PYTHONPATH = "$PWD\src"
pytest
| ファイル | 用途 |
|----------|------|
| configs/train_node21.yaml | YOLO 学習(モデル、エポック、バッチ、パス) |
| configs/app.yaml | デフォルトのモデルパス、しきい値、クラス名 |
本リポジトリのコードは最小限の研究用骨組みです。データセットのライセンスは別途 — NODE21 等の利用条件を遵守し、患者データや制限付きファイルをコミットしないでください。
論文等で NODE21 を使用する場合は、公式ドキュメントに従い元データセット・チャレンジ論文を引用してください。