人工智能和机器学习正在转化医学图像,但这些模型的训练需要大,正确匿名数据集. 在本指南中,您将学习如何使用一个完整的工作流,将包匿与JSON金属数据出口结合到ML管道的无缝整合。
内容表
為什麼 AI 研究需要匿名 DICOM 資料
医学图像人工智能模型用于诊断、分类和检测需要有意义的培训数据. 这些数据必须适当匿名化,以符合HIPAA、GDPR和机构政策。 此外,研究合作往往包括多个机构,使标准化识别至关重要。
正确的数据集编制涉及更多,而不仅仅是删除患者名称,需要系统处理所有识别信息,在成千上万的文件中连续应用匿名化规则,以及格式转换,使数据可访问ML框架。
不适当数据组准备的风险
使用部分匿名或不正确结构化的数据集会产生重大问题. 不完整的匿名的可能暴露病人信息,导致监管违规和道德违法行为. 在数据组中不一致的 anonymization 可能会引入错误或数据质量问题。 不结构化的metadata使难过滤、查询和预处理模型培训数据。
这些风险通过使用自动、一致的匿名化管道和将数据转换为机器友好的格式来减轻。
完整准备工作流(#complete preparation-workflow)
整個工作流由四個階段組成. 第一,包匿名化DICOM研究使用一致的檔案. 第二,轉換匿名的數據到JSON管道插入. 三,儲存圖像和數字為ML框架接入。
让我们用代码的例子来实现每个阶段。
Batch 匿名化
首先,将您的 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上加载Pandas
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}")
在Elasticsearch中编辑
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数据集需要仔细关注隐私、一致性和格式兼容性. 使用Aspose.Medical for .NET,您可以创建自动管道,以一致的个人资料进行匿名化研究,向ML框架输入的JSON出口金属数据,并保持可再生性的审计轨道。
此工作流确保您的研究数据是正确的识别,结构良好,并为下一代医学图像人工智能做好准备。
更多信息和示例,请参观 ASPOSE.医学文档要尝试完整的 API 能力, 获得免费的临时许可证.