pydicom について
pydicomは、Pythonでpydicomを使ってDICOMデータを読み取り、確認、処理するためのスキルです。医用画像を扱う開発者や研究者向けに、PHI保護、ピクセル処理の制限、レビュー済みの匿名化手順を案内します。
主な機能
- 01DICOMデータセットとメタデータの読み取り
- 02ピクセル・マルチフレーム処理の案内
- 03転送構文とコーデックの確認
- 04メタデータ集計・技術インベントリCLI
- 05匿名化監査ワークフローの案内
活用シーン
- 01許可されたローカルDICOMファイルの確認
- 02マルチフレーム処理のリソース計画
- 03転送構文とコーデック機能の確認
- 04匿名化派生データの作成と監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill pydicomインストール後、Claude Code で/pydicomを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/common_tags.mdtransfer_syntaxes.mdscripts/__init__.py_common.pyanonymize_dicom.pydeidentification_audit.pydicom_inventory.pydicom_to_image.pyextract_metadata.pypixel_frame_planner.pytransfer_syntax_inspector.pyuid_mapping_validator.py詳細
pydicom
DICOM データセットの入出力とピクセル処理には pydicom を使用します。ここで確認した現行の安定版は Version 3.0.2 です。細工された DICOMDIR によるパストラバーサルの問題である CVE-2026-32711 が修正されています。pydicom 3.0.2 の宣言上の Python 要件は >=3.10 です。内蔵の DICOM ディクショナリは 2024c ですが、最新の DICOM Standard はそれより新しい場合があります。
必須の安全境界
- ユーザーがアクセスを許可されているローカルデータのみを扱ってください。
- DICOM メタデータ、ファイル名、プライベート要素、オーバーレイ、構造化コンテンツ、ピクセルには、保護対象保健情報(PHI)が含まれている可能性があります。
- デフォルトでは、
Datasetの内容を出力したり、メタデータ全体/JSON をエクスポートしたり、要素の値をログに記録したりしないでください。文書化された許可リストを使用し、集計結果を出力してください。 - pydicom は汎用の DICOM フレームワークであり、診断用ビューアーではありません。ピクセル出力、検証、変換、プラグインの利用可否は、診断上の主張ではありません。
- 非識別化は、プロファイル、目的、受領者、管轄区域、脅威の状況に固有の処理です。プライバシー/DICOM の専門家による検証が必要です。
- タグ削除スクリプトが DICOM PS3.15、HIPAA、GDPR、またはその他の規制への準拠を実現すると主張しないでください。原本を保持し、派生出力を監査してください。
- 決定論的な仮名化キーと UID マップは、再識別につながる機密情報として扱ってください。最小権限を適用し、暗号化された/管理対象のシークレットストレージを使用してください。派生データと一緒にコミット、同期、ログ記録、共有しないでください。また、バックアップ、ローテーション、失効、破棄の手順を定めてください。キーが漏えいすると、意図した分離が無効になります。ローテーションによって決定論的なマッピングも変わります。
- 信頼できないデータセットや通常より大きなデータセットを解析する前に、入力ファイル数、ファイル件数、フレーム数、デコード後のバイト数、出力に明示的な上限を設定してください。
インストール
分離された環境を作成または有効化してから、確認済みの正確なリリースをインストールします。
uv pip install "pydicom==3.0.2"
非圧縮ピクセル配列と画像のレンダリング:
uv pip install "pydicom==3.0.2" "numpy==2.5.1" "Pillow==12.3.0"
デプロイ環境で必要な転送構文プラグインのみをインストールします。
# JPEG/JPEG-LS, JPEG 2000/HTJ2K, and faster RLE through pylibjpeg
uv pip install "numpy==2.5.1" "pylibjpeg==2.1.0" \
"pylibjpeg-libjpeg==2.4.0" "pylibjpeg-openjpeg==2.5.0" \
"pylibjpeg-rle==2.2.0"
# JPEG-LS encoder/decoder
uv pip install "numpy==2.5.1" "pyjpegls==1.5.1"
# Alternative decoder with platform-specific wheels
uv pip install "python-gdcm==3.2.6"
プラグインのライセンスとホイールはパッケージ/プラットフォームによって異なるため、デプロイ前に確認してください。Pillow には文書化されたデコード上の制限があり、pydicom はプラグインの出力を独立して確認するよう注意を促しています。
ネイティブコードのコーデック用ホイールを導入すると、サプライチェーンとメモリ安全性の境界が広がります。管理された環境にデプロイする場合は、信頼できるビルドホストでこれらの正確なピンを解決し、ホイールのハッシュと来歴をロックして検証し、承認済みのアーティファクトを社内にミラーリングしてスキャンしてください。また、実行時に公開インデックスから解決するのではなく、ハッシュ検証を有効にしてインストールしてください。
ワークフローを選択する
- 集計概要が必要な場合:
scripts/extract_metadata.pyを実行します。 - 範囲を限定した技術的な確認が必要な場合:
scripts/dicom_inventory.pyを実行します。 - コーデックのデプロイ前確認が必要な場合:
scripts/transfer_syntax_inspector.pyを実行します。 - フレーム/メモリの計画が必要な場合:
scripts/pixel_frame_planner.pyを実行します。 - 診断目的ではないフレームを 1 つレンダリングする場合:
scripts/dicom_to_image.pyを実行します。 - 仮名化された派生データが必要な場合:非識別化のセクションを読み、施設で確認済みのアクションプロファイルを作成してから、
scripts/anonymize_dicom.pyとscripts/deidentification_audit.pyを実行します。 - 機密性の高い UID マップを確認する場合:
scripts/uid_mapping_validator.pyを実行します。
データセットを安全に読み込む
dcmread() は FileDataset を返します。これは Dataset のサブクラスで、file_meta、プリアンブル、元のエンコーディングなどの File Format 状態を保持します。
from pathlib import Path
import pydicom
path = Path("authorized/input.dcm")
ds = pydicom.dcmread(
path,
stop_before_pixels=True,
specific_tags=[
"SOPClassUID",
"Modality",
"Rows",
"Columns",
"NumberOfFrames",
],
)
technical = {
"sop_class": ds.get("SOPClassUID"),
"modality": ds.get("Modality"),
"rows": ds.get("Rows"),
"columns": ds.get("Columns"),
}
次のように使用します。
- メタデータのみを扱う場合は
stop_before_pixels=Trueを使用します。 - 最小限の許可リストを指定するには
specific_tags=[...]を使用します。 - 後で書き込みを行い、大きな値を保持する必要がある場合は
defer_size="1 MiB"を使用します。 force=False(デフォルト)を使用します。force=Trueは File Format ヘッダーの確認を回避するだけであり、バイト列が有効な DICOM であることを証明するものではありません。
臨床データに対して print(ds)、repr(ds) を呼び出したり、値を反復処理してログに記録したりしないでください。
Dataset、DataElement、Sequence
キーワードで標準要素にアクセスし、存在しない場合に備えて確認します。
modality = ds.get("Modality", "UNSPECIFIED")
if "ReferencedImageSequence" in ds:
for item in ds.ReferencedImageSequence:
referenced_class = item.get("ReferencedSOPClassUID")
ds[0x0010, 0x0010] のようにタグでアクセスすると、DataElement が返されます。その .value は別個の値です。Sequence は、ネストされた Dataset 項目のリストとして動作します。プライバシー保護の処理では、最上位だけでなく、すべてのシーケンス項目を再帰的に処理する必要があります。
ファイルを作成するときは、グループ 0002 に FileMetaDataset を使用し、データセットとファイルメタの SOP UID を一致させ、Transfer Syntax UID を設定したうえで、強制された File Format で書き込みます。
from pydicom import dcmwrite
from pydicom.dataset import FileDataset, FileMetaDataset
from pydicom.uid import CTImageStorage, ExplicitVRLittleEndian, generate_uid
meta = FileMetaDataset()
meta.MediaStorageSOPClassUID = CTImageStorage
meta.MediaStorageSOPInstanceUID = generate_uid()
meta.TransferSyntaxUID = ExplicitVRLittleEndian
ds = FileDataset(None, {}, file_meta=meta, preamble=b"\0" * 128)
ds.SOPClassUID = meta.MediaStorageSOPClassUID
ds.SOPInstanceUID = meta.MediaStorageSOPInstanceUID
# Add all attributes required by the selected IOD before writing.
dcmwrite("new.dcm", ds, enforce_file_format=True, overwrite=False)
write_like_original は pydicom 3.0 で非推奨になりました。enforce_file_format を使用してください。書き込みに成功しても、PS3.3 IOD に完全準拠しているとは限りません。
UID と転送構文
File Meta Information の Transfer Syntax UID によって、データセットのエンコーディングとピクセル圧縮が制御されます。
ts = ds.file_meta.TransferSyntaxUID
summary = {
"uid": str(ts),
"name": ts.name,
"compressed": ts.is_compressed,
"implicit_vr": ts.is_implicit_VR,
"little_endian": ts.is_little_endian,
}
pydicom 3.0 では、書き込みエンコーディングは従来のデータセットフラグよりも先に Transfer Syntax UID から決定されます。匿名化の際に、構造を定義する UID(Transfer Syntax、SOP Class、コーディングスキームの UID)を置き換えないでください。インスタンス/参照 UID の置換は、宣言された対象範囲全体にわたって一対一で対応し、一貫性を保つ必要があります。
圧縮、展開、またはカプセル化を行う前に、references/transfer_syntaxes.md をお読みください。
ピクセルデータとフレーム
安定版の pydicom.pixels API は、パスベースのフレーム単位のデコードに対応しています。
from pydicom.pixels import pixel_array
# Reads only the selected frame where the source permits it.
frame = pixel_array("authorized/image.dcm", index=0, raw=False)
形状の意味は次のとおりです。
- グレースケールの単一フレーム:
(rows, columns) - グレースケールの複数フレーム:
(frames, rows, columns) - カラーの単一フレーム:
(rows, columns, samples) - カラーの複数フレーム:
(frames, rows, columns, samples)
raw=False は、可能な場合に YCbCr ピクセルデータを RGB に変換します。raw=True は、必須の最小限の処理を適用した後のデコード済み色空間を維持します。複数フレームを上限付きで反復処理するには、iter_pixels(path, indices=[...]) を使用してください。
グレースケール表示では、次の順序で変換を適用してください。
from pydicom.pixels import apply_modality_lut, apply_voi_lut
modality_values = apply_modality_lut(frame, ds)
display_values = apply_voi_lut(modality_values, ds, index=0)
Modality LUT/再スケーリングと VOI/ウィンドウ処理は、表示や値の意味を変えます。MONOCHROME1 では、表示用の反転が必要な場合があります。Palette Color には apply_color_lut() が必要です。プレゼンテーション状態や ICC の動作には、検証済みのビューアーが必要となる場合があります。定量分析では、フレームごとの最小値/最大値による正規化を決して使用しないでください。
圧縮、展開、カプセル化
pixel_arrayにアクセスすると必要に応じてデコードされますが、データセットは変更されません。Dataset.decompress()は Pixel Data をインプレースで変更し、Explicit VR Little Endian を設定して画像メタデータを更新します。また、デフォルトで新しい SOP Instance UID を生成します。Dataset.compress(uid)は Pixel Data と Transfer Syntax をインプレースで変更し、デフォルトで新しい SOP Instance UID を生成します。- pydicom 3.0 に組み込まれているエンコーダーと検出されたエンコーダーは、安定版プラグインの対応表に記載された RLE Lossless、JPEG-LS、JPEG 2000 の組み合わせに対応しています。
- 圧縮された各フレームは個別にエンコードされ、その後カプセル化されます。外部でエンコードされたフレームには、
encapsulate()またはencapsulate_extended()を使用してください。 - 現行の
pydicom.encaps.generate_frames()またはget_frame()でフレームを読み取ってください。従来のカプセル化ジェネレーター名は pydicom 4 で非推奨になります。
常に最初に機能を確認し、デコードするバイト数やフレーム数を制限して、ピクセルの正しさを個別に検証してください。非可逆圧縮の許容性は、pydicom および DICOM エンコーディング仕様の対象外です。
DICOM JSON とプライベート要素
Dataset.to_json()、to_json_dict()、Dataset.from_json() は DICOM JSON Model を実装していますが、pydicom のドキュメントでは JSON サポートはベータ版とされています。完全な JSON ではバイナリデータがインライン化され、あらゆる識別子やピクセルペイロードが公開される可能性があります。メタデータレポートとして出力しないでください。BulkDataURI ハンドラーを導入すると、別途、ストレージ、認可、取得に関する責務が生じます。
プライベート要素は標準化されておらず、PHI を含む場合があります。
# Recursive removal, but not sufficient de-identification by itself.
ds.remove_private_tags()
レビュー済みの安全なプライベート要素に関するポリシーで明示的に許可されている場合に限り、プライベート要素を保持してください。タグへのアクセス、プライバシークラス、標準仕様への参照については、references/common_tags.md をお読みください。
匿名化ワークフロー
DICOM PS3.15 Annex E では、機密性プロファイルによってすべての識別情報が削除されることが保証されるわけではなく、完全な匿名化プロセスに代わるものでもないことが明記されています。
- 目的、受領者、連結の必要性、規制、脅威モデル、および許容可能な再識別リスクを定義します。
- Basic Application Level Confidentiality Profile と、必要なオプション(ピクセル、視覚的に認識可能な特徴、グラフィック、構造化コンテンツ、記述子、時間情報、患者特性、デバイス、施設、UID、および安全なプライベートデータ)を選択します。
- ソースオブジェクトは管理されたストレージに変更せずに保管します。
- ネストされたシーケンスを含め、すべてのアクションを再帰的に適用します。
- インスタンス/参照 UID を対象範囲全体で一貫して置き換え、構造を表す UID は保持します。
- 日付/時刻の処理方法を明示的に決定します。固定シフトは間隔を保持できますが、一部のみの日付、タイムゾーン、単独の時刻、うるう日、縦断的な連結、および外部イベントには、レビュー済みの方針が必要です。
- ピクセル、オーバーレイ、グラフィック、構造化コンテンツ、および視覚的に認識可能な特徴を検査します。メタデータがないことからピクセルがクリーンだと推測したり、検証せずに
BurnedInAnnotation=NOを設定したりしないでください。 - 情報漏えいを防ぐため、File Meta Information とプリアンブルを再構築します。
- 技術的な検証と匿名化監査を実施し、その後、専門家による検証と文書化されたリスクレビューを行います。
同梱のスクリプトは、匿名化の成功を確認できないため、意図的に PatientIdentityRemoved を NO に設定します。
ヘルパー CLI
すべての --help の実行には依存関係がありません。ツールはネットワークにアクセスせず、限定された技術情報の許可リストを超える DICOM 値を出力しません。
同梱コンテンツは、リンクされた 2 つの参考資料、説明文書付きのヘルパースクリプト、および合成テストで構成されます。pydicom の実行時依存関係は、固定された PyPI リリースからインストールされます。
# Redacted aggregate metadata
python scripts/extract_metadata.py authorized/ --recursive
# Metadata-only technical inventory
python scripts/dicom_inventory.py authorized/ --recursive
# Installed codec/plugin capabilities
python scripts/transfer_syntax_inspector.py --input authorized/image.dcm
# Frame shape, byte, and transform plan
python scripts/pixel_frame_planner.py authorized/image.dcm --frames 0,2-4
# One non-diagnostic frame
python scripts/dicom_to_image.py authorized/image.dcm frame.png \
--acknowledge-pixel-phi
# Create a secret key, then a scoped pseudonymized derivative plus audit
python scripts/anonymize_dicom.py --generate-uid-key project.key
python scripts/anonymize_dicom.py authorized/in.dcm derived/out.dcm \
--uid-key-file project.key --uid-scope export-v1 \
--audit-report derived/out.audit.json
# Audit candidate metadata; no pixel decompression
python scripts/deidentification_audit.py derived/out.dcm
# Validate an explicitly requested sensitive UID mapping
python scripts/uid_mapping_validator.py derived/uid-map.json \
--uid-key-file project.key --uid-scope export-v1
生成される raw key ファイルは、管理されたローカル環境での利便性を目的としており、所有者のみがアクセスできる権限で作成されます。本番環境では、承認済みのシークレットマネージャーからキーのバイト列をロックされた一時ファイルに書き込み、匿名化サービスのみにアクセスを制限し、使用後は安全に削除してください。任意の UID マップを保存する場合は、派生データとは分けて保管してください。このマップは元の識別子と置換後の識別子を直接結び付けます。
pydicom 3.0 への移行に関する注意事項
read_file()とwrite_file()は削除されました。代わりにdcmread()とdcmwrite()を使用してください。write_like_originalは非推奨です。代わりにenforce_file_formatを使用してください。pydicom.pixel_data_handlersは v4 で削除予定の非推奨機能です。代わりにpydicom.pixelsを使用してください。Dataset.pixel_arrayはデフォルトで新しいピクセルバックエンドを使用し、可能な場合は YCbCr を RGB に変換します。JPEGLosslessは UID1.2.840.10008.1.2.4.57を指すようになりました。JPEGLosslessSV1は.70です。Dataset.is_little_endianとis_implicit_VRは v4 で非推奨になります。
ソース(2026-07-23に確認済み)
- PyPI の pydicom 3.0.2 — リリース日:
2026-03-19;Python
>=3.10。 - pydicom のリリース — 3.0.2 および CVE-2026-32711 の詳細。
- 安定版リリースノート
- 安定版インストールガイド
- データセットの基本
- 安定版ピクセルチュートリアル
- 安定版ピクセルプラグイン
- 安定版圧縮チュートリアル
- 安定版 DICOM JSON チュートリアル
- 安定版プライベート要素ガイド
- 現行の DICOM 規格
- DICOM PS3.3、 PS3.5、 PS3.6、 および PS3.15
エージェントの運用手順
- 環境を確認します。 データへのアクセス権限、匿名化の状態、および適用される規制やプロトコルを確認します。
- 入力を明確にします。 データまたはユーザーから、形式、識別子、パラメーターを確認します。結果に影響する値は推測せず、質問してください。
- まず小規模なバージョンを実行します。 最初に匿名化済みのサンプルまたは合成データで作業します。
- 上記の手順と参考資料を使用して、タスク全体を実行します。
- 結果を検証します。 出力を臨床ガイドラインおよび報告基準と照合し、臨床内容は資格を有する人間に確認してもらいます。
- 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未確定の事項を明記します。
| このような場合 | 対応 |
|---|---|
| データに患者を特定できる情報が含まれているように見える | 処理を中止し、続行する前にユーザーに確認します。 |
| この手順に記載された関数、フラグ、エンドポイントがインストール済みバージョンにない | インストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認し、適宜対応してユーザーに伝えます。API を決して捏造しないでください。 |
| 必須の入力、識別子、パラメーターが曖昧である | ユーザーに確認するか、実行前に仮定を明示します。 |
完全性に関するルール
- 結果、パラメーター、識別子、引用、統計を決して捏造しないでください。実行または検証できない場合は、その旨を明確に伝えてください。
- 出力は資格を有する専門家向けの意思決定支援であり、医療上の助言ではありません。診断や指示として提示しないでください。
- ここに記載されたバージョン固有の情報は古くなっている可能性があります。インストール済みバージョンの公式ドキュメントと照合してください。
- 費用が発生する、共有 GPU やクラウドクォータを消費する、個人データや患者データを扱う、または取り消せない操作を行う前に、必ず確認してください。