AIと機械学習は医療イメージを変えるが、これらのモデルのトレーニングには、大規模で適切に匿名化されたデータセットが必要だ。このガイドでは、完全なワークフローを使用してAI研究のためのDICOMデータセットを準備する方法を学びます。

テーブルコンテンツ

なぜAI研究は匿名化されたDICOMデータを必要とするのか。

診断、分割、検出のための医療イメージのAIモデルには、本質的なトレーニングデータが必要です. このデータは、HIPAA、GDPR、および機関ポリシーに合致するために適切に匿名化されなければなりません. さらに、研究協力は多くの機関を拡張し、標準化されたデ・識別が不可欠になります。

適切なデータセットの準備は、単なる患者名の削除以上に含まれます. すべての識別情報をシステム的に処理し、何千ものファイルを通じて匿名化規則の一貫した適用、およびデータをMLフレームワークにアクセスできるフォーマット変換を必要とします。

不適切なデータセットの準備のリスク

部分的に匿名化または不適切に構造化されたデータセットを使用すると、重大な問題が生じます。不完全な無知化は、規制違反および倫理的侵害につながる患者の情報を暴露することができます. データセットを通じて不一貫した無意識化が、異常やデータの質の問題を引き起こす可能性があります. 不構成されたメタデータでは、モデルトレーニングのためのフィルター、リクエスト、事前処理データを困難にします。

これらのリスクは、自動化され、一貫した匿名化パイプを使用し、機械に優しいフォーマットにデータを変換することによって軽減されます。

完全な準備作業流(#complete-preparation-workflow)

完全なワークフローは4段階で構成されます. まず、バッチは一貫したプロファイルを使用してDICOMの研究を匿名化します. 第二に、パイプライン入力のためにJSONに匿名的メタデータを変換します。

各段階をコードの例で実施します。

バッチ・アニメ化(Batch Anonymization)

DICOMコレクションを一貫したプロフィールで匿名化することから始まります。

using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;

public class DicomDatasetPreparation
{
    private readonly string _inputFolder;
    private readonly string _outputFolder;
    private readonly string _mappingFile;
    private readonly Anonymizer _anonymizer;
    private readonly List<string> _mappings = new();

    public DicomDatasetPreparation(string inputFolder, string outputFolder)
    {
        _inputFolder = inputFolder;
        _outputFolder = outputFolder;
        _mappingFile = Path.Combine(outputFolder, "id_mapping.csv");

        Directory.CreateDirectory(outputFolder);

        // Create anonymizer with research-appropriate profile
        ConfidentialityProfile profile = ConfidentialityProfile.CreateDefault(
            ConfidentialityProfileOptions.BasicProfile |
            ConfidentialityProfileOptions.RetainPatientChars
        );
        _anonymizer = new Anonymizer(profile);

        _mappings.Add("OriginalFile,AnonymizedFile,Timestamp");
    }

    public async Task ProcessDatasetAsync()
    {
        string[] dicomFiles = Directory.GetFiles(_inputFolder, "*.dcm", SearchOption.AllDirectories);
        Console.WriteLine($"Found {dicomFiles.Length} DICOM files to process.");

        int processed = 0;
        int failed = 0;

        foreach (string filePath in dicomFiles)
        {
            try
            {
                string relativePath = Path.GetRelativePath(_inputFolder, filePath);
                string outputPath = Path.Combine(_outputFolder, "images", relativePath);

                Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);

                DicomFile dcm = DicomFile.Open(filePath);
                DicomFile anonymizedDcm = _anonymizer.Anonymize(dcm);
                anonymizedDcm.Save(outputPath);

                // Record mapping for audit trail
                _mappings.Add($"\"{relativePath}\",\"{outputPath}\",\"{DateTime.UtcNow:O}\"");

                processed++;
                if (processed % 100 == 0)
                {
                    Console.WriteLine($"Progress: {processed}/{dicomFiles.Length}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error processing {filePath}: {ex.Message}");
                failed++;
            }
        }

        // Save mapping file
        await File.WriteAllLinesAsync(_mappingFile, _mappings);

        Console.WriteLine($"\nAnonymization complete:");
        Console.WriteLine($"  Processed: {processed}");
        Console.WriteLine($"  Failed: {failed}");
        Console.WriteLine($"  Mapping file: {_mappingFile}");
    }
}

メタデータをJSONに変換する

匿名化後、ML パイプライン入力のための JSON にメタデータを変換する:

using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Serialization;

public class MetadataExporter
{
    public async Task ExportMetadataToJsonAsync(string dicomFolder, string jsonOutputPath)
    {
        string[] dicomFiles = Directory.GetFiles(dicomFolder, "*.dcm", SearchOption.AllDirectories);
        List<Dataset> datasets = new();

        Console.WriteLine($"Extracting metadata from {dicomFiles.Length} files...");

        foreach (string filePath in dicomFiles)
        {
            try
            {
                DicomFile dcm = DicomFile.Open(filePath);
                datasets.Add(dcm.Dataset);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Skipping {filePath}: {ex.Message}");
            }
        }

        // Serialize all datasets to JSON array
        string jsonArray = DicomJsonSerializer.Serialize(datasets.ToArray(), writeIndented: true);
        await File.WriteAllTextAsync(jsonOutputPath, jsonArray);

        Console.WriteLine($"Exported {datasets.Count} datasets to {jsonOutputPath}");
    }

    public async Task ExportMetadataPerFileAsync(string dicomFolder, string jsonOutputFolder)
    {
        Directory.CreateDirectory(jsonOutputFolder);
        string[] dicomFiles = Directory.GetFiles(dicomFolder, "*.dcm", SearchOption.AllDirectories);

        foreach (string filePath in dicomFiles)
        {
            try
            {
                DicomFile dcm = DicomFile.Open(filePath);
                string json = DicomJsonSerializer.Serialize(dcm, writeIndented: true);

                string jsonFileName = Path.GetFileNameWithoutExtension(filePath) + ".json";
                string jsonPath = Path.Combine(jsonOutputFolder, jsonFileName);
                await File.WriteAllTextAsync(jsonPath, json);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error exporting {filePath}: {ex.Message}");
            }
        }

        Console.WriteLine($"Individual JSON files saved to {jsonOutputFolder}");
    }
}

ML パイプラインと統合

輸出されたJSONは、さまざまなMLフレームワークやツールに充電することができます。

パンダでPythonにアップロード

import json
import pandas as pd

# Load the JSON array
with open('dicom_metadata.json', 'r') as f:
    dicom_data = json.load(f)

# Flatten nested structure for analysis
def extract_values(record):
    result = {}
    for tag, data in record.items():
        if 'Value' in data and data['Value']:
            value = data['Value'][0]
            if isinstance(value, dict) and 'Alphabetic' in value:
                result[tag] = value['Alphabetic']
            else:
                result[tag] = value
    return result

flat_data = [extract_values(record) for record in dicom_data]
df = pd.DataFrame(flat_data)

print(df.head())
print(f"Dataset shape: {df.shape}")

エラスティックサークルにおけるインデックス

from elasticsearch import Elasticsearch, helpers

es = Elasticsearch(['http://localhost:9200'])

with open('dicom_metadata.json', 'r') as f:
    dicom_data = json.load(f)

def generate_actions(data):
    for i, record in enumerate(data):
        yield {
            '_index': 'dicom_studies',
            '_id': i,
            '_source': record
        }

helpers.bulk(es, generate_actions(dicom_data))
print(f"Indexed {len(dicom_data)} records to Elasticsearch")

完全パイプラインスクリプト

以下は、準備作業の全流を実行する完全なC#スクリプトです。

using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;
using Aspose.Medical.Dicom.Serialization;

class Program
{
    static async Task Main(string[] args)
    {
        string inputFolder = args.Length > 0 ? args[0] : @"C:\DicomSource";
        string outputFolder = args.Length > 1 ? args[1] : @"C:\DicomPrepared";

        Console.WriteLine("=== DICOM Dataset Preparation for AI ===\n");

        // Step 1: Anonymize
        Console.WriteLine("Step 1: Anonymizing DICOM files...");
        var prep = new DicomDatasetPreparation(inputFolder, outputFolder);
        await prep.ProcessDatasetAsync();

        // Step 2: Export metadata to JSON
        Console.WriteLine("\nStep 2: Exporting metadata to JSON...");
        var exporter = new MetadataExporter();
        string anonymizedFolder = Path.Combine(outputFolder, "images");
        string jsonOutput = Path.Combine(outputFolder, "metadata.json");
        await exporter.ExportMetadataToJsonAsync(anonymizedFolder, jsonOutput);

        Console.WriteLine("\n=== Dataset Preparation Complete ===");
        Console.WriteLine($"Anonymized images: {Path.Combine(outputFolder, "images")}");
        Console.WriteLine($"Metadata JSON: {jsonOutput}");
        Console.WriteLine($"ID Mapping: {Path.Combine(outputFolder, "id_mapping.csv")}");
    }
}

最良の実践(ベスト・プラクティス)

セキュアIDマッピングストレージは不可欠です 匿名およびオリジナルの識別子の間のマッチングは、匿名的データから別々に安全でアクセスコントロールされた場所に保管されなければなりません。

すべての操作を記録する 再生可能性のために. どのファイルが処理されたか、いつ、どのプロフィールで、どのようなエラーが発生したかを記載します. この文書化は、研究回復性および監査の要件に重要です。

プロフィールが予想通り動作し、画像の品質が保存されていることを確認するために、完全なデータセットを処理する前にサンプル出力を確認します。

**大規模なデータセットのデータ分割を考慮してください. 異なるトレーニングタスクのためのサブセット選択を容易にするために、研究タイプ、モダリティ、またはその他の関連する基準に基づいて出力を組織します。

結論( )

人工知能と機械学習のためのDICOMデータセットの準備には、プライバシー、一貫性、およびフォーマット互換性に注意を払う必要があります. .NET のための Aspose.Medical を使用すると、一致したプロファイルで研究を匿名化し、ML フレームワークの入力のために JSON にメタデータをエクスポートする自動パイプを構築することができます。

このワークフローは、あなたの研究データが適切に識別され、構造化されており、次の世代の医療イメージAIの準備ができていることを保証します。

詳しい情報や例はこちらをご覧ください。 メディカル・ドキュメンタリー完全な API 能力を試すには、 無料の暫定ライセンスを取得.

More in this category