DICOM 연구의 폴더를 익명화하는 방법
이 튜토리얼은 C#를 사용하여 폴더에서 여러 DICOM 파일을 익명화하는 방법을 보여줍니다.수백 또는 수천 개의 의료 이미지 파일과 함께 작업 할 때, 배치 처리 효율성과 일관성에 필수적입니다.
배치 익명화의 혜택
효율성:- 전체 연구 또는 아카이브를 하나의 작업으로 처리합니다.
일관성 일관성:- 모든 파일에 동일한 익명화 규칙을 적용합니다.
자동화:- 자동화된 작업 흐름과 파이프라인에 통합합니다.
원제 : Environment Preparation
- Visual Studio 또는 모든 호환되는 .NET IDE를 설정합니다.
- 새로운 .NET 8 콘솔 애플리케이션 프로젝트를 만드십시오.
- NuGet 패키지 관리자에서 Aspose.Medical을 설치합니다.
- DICOM 파일을 사용하여 입력 폴더를 준비하고 출력을 만듭니다.
단계별로 DICOM 파일을 익명화하기 위한 배치 가이드
단계 1 : Aspose.Medical 설치
NuGet을 사용하여 프로젝트에 Aspose.Medical 도서관을 추가합니다.
Install-Package Aspose.Medical단계 2 : 필요한 이름 공간을 포함
코드에 필요한 이름 공간에 참조를 추가합니다.
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;3단계: 디렉토리 경로 설정
입력 및 출력 디렉토리 경로를 설정합니다.
string inputDirectory = @"C:\DicomStudies\Input";
string outputDirectory = @"C:\DicomStudies\Anonymized";
// Ensure output directory exists
Directory.CreateDirectory(outputDirectory);단계 4 : DICOM 파일 목록
모든 DICOM 파일을 입력 디렉토리에서 얻으십시오.
string[] dicomFiles = Directory.GetFiles(
inputDirectory,
"*.dcm",
SearchOption.AllDirectories
);
Console.WriteLine($"Found {dicomFiles.Length} DICOM files to process.");5단계: 애니메이션 만들기
원하는 프로필과 함께 애니메이션을 만드십시오.
Anonymizer anonymizer = new();
// Or with a custom profile:
// ConfidentialityProfile profile = ConfidentialityProfile.CreateDefault(
// ConfidentialityProfileOptions.BasicProfile
// );
// Anonymizer anonymizer = new(profile);단계 6 : 각 파일을 처리
각 파일을 통과하고, 익명화하고 출력 디렉토리로 저장합니다.
int successCount = 0;
int failCount = 0;
foreach (string filePath in dicomFiles)
{
try
{
// Load DICOM file
DicomFile dcm = DicomFile.Open(filePath);
// Anonymize
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
// Preserve relative directory structure
string relativePath = Path.GetRelativePath(inputDirectory, filePath);
string outputPath = Path.Combine(outputDirectory, relativePath);
// Ensure subdirectory exists
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
// Save anonymized file
anonymizedDcm.Save(outputPath);
successCount++;
Console.WriteLine($"✓ Processed: {relativePath}");
}
catch (Exception ex)
{
failCount++;
Console.WriteLine($"✗ Failed: {filePath} - {ex.Message}");
}
}
Console.WriteLine($"\nCompleted: {successCount} succeeded, {failCount} failed.");배치 익명화에 대한 전체 코드 예제
다음은 진보 보고서와 함께 배치 익명을 보여주는 완전한 예입니다 :
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;
string inputDirectory = @"C:\DicomStudies\Input";
string outputDirectory = @"C:\DicomStudies\Anonymized";
// Ensure output directory exists
Directory.CreateDirectory(outputDirectory);
// Get all DICOM files
string[] dicomFiles = Directory.GetFiles(inputDirectory, "*.dcm", SearchOption.AllDirectories);
Console.WriteLine($"Found {dicomFiles.Length} DICOM files to process.\n");
// Create anonymizer
Anonymizer anonymizer = new();
int successCount = 0;
int failCount = 0;
int total = dicomFiles.Length;
foreach (string filePath in dicomFiles)
{
try
{
DicomFile dcm = DicomFile.Open(filePath);
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
string relativePath = Path.GetRelativePath(inputDirectory, filePath);
string outputPath = Path.Combine(outputDirectory, relativePath);
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
anonymizedDcm.Save(outputPath);
successCount++;
// Progress reporting
double progress = (double)(successCount + failCount) / total * 100;
Console.WriteLine($"[{progress:F1}%] ✓ {relativePath}");
}
catch (Exception ex)
{
failCount++;
Console.WriteLine($"✗ Failed: {Path.GetFileName(filePath)} - {ex.Message}");
}
}
Console.WriteLine($"\n========================================");
Console.WriteLine($"Batch Anonymization Complete");
Console.WriteLine($"Succeeded: {successCount}");
Console.WriteLine($"Failed: {failCount}");
Console.WriteLine($"========================================");더 나은 성과를 위한 동시 처리
대형 데이터 세트의 경우, 여러 CPU 코어를 활용하기 위해 병렬 처리를 사용하십시오 :
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;
using System.Collections.Concurrent;
string inputDirectory = @"C:\DicomStudies\Input";
string outputDirectory = @"C:\DicomStudies\Anonymized";
Directory.CreateDirectory(outputDirectory);
string[] dicomFiles = Directory.GetFiles(inputDirectory, "*.dcm", SearchOption.AllDirectories);
Console.WriteLine($"Found {dicomFiles.Length} DICOM files to process.\n");
// Thread-safe counters
int successCount = 0;
int failCount = 0;
ConcurrentBag<string> failedFiles = new();
// Process in parallel
Parallel.ForEach(dicomFiles, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, filePath =>
{
try
{
// Each thread gets its own anonymizer instance
Anonymizer anonymizer = new();
DicomFile dcm = DicomFile.Open(filePath);
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
string relativePath = Path.GetRelativePath(inputDirectory, filePath);
string outputPath = Path.Combine(outputDirectory, relativePath);
lock (outputDirectory) // Ensure directory creation is thread-safe
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
}
anonymizedDcm.Save(outputPath);
Interlocked.Increment(ref successCount);
}
catch (Exception ex)
{
Interlocked.Increment(ref failCount);
failedFiles.Add($"{filePath}: {ex.Message}");
}
});
Console.WriteLine($"\nBatch Anonymization Complete");
Console.WriteLine($"Succeeded: {successCount}");
Console.WriteLine($"Failed: {failCount}");
if (failedFiles.Any())
{
Console.WriteLine($"\nFailed files:");
foreach (string failure in failedFiles)
{
Console.WriteLine($" - {failure}");
}
}업그레이드된 버전 Logging
생산 환경을 위해 적절한 로그링을 구현하십시오 :
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;
string inputDirectory = @"C:\DicomStudies\Input";
string outputDirectory = @"C:\DicomStudies\Anonymized";
string logFile = Path.Combine(outputDirectory, "anonymization_log.txt");
Directory.CreateDirectory(outputDirectory);
string[] dicomFiles = Directory.GetFiles(inputDirectory, "*.dcm", SearchOption.AllDirectories);
Anonymizer anonymizer = new();
List<string> logEntries = new();
logEntries.Add($"Anonymization started: {DateTime.Now}");
logEntries.Add($"Input directory: {inputDirectory}");
logEntries.Add($"Output directory: {outputDirectory}");
logEntries.Add($"Total files to process: {dicomFiles.Length}");
logEntries.Add("---");
int successCount = 0;
int failCount = 0;
foreach (string filePath in dicomFiles)
{
string relativePath = Path.GetRelativePath(inputDirectory, filePath);
try
{
DicomFile dcm = DicomFile.Open(filePath);
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
string outputPath = Path.Combine(outputDirectory, relativePath);
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
anonymizedDcm.Save(outputPath);
successCount++;
logEntries.Add($"SUCCESS: {relativePath}");
}
catch (Exception ex)
{
failCount++;
logEntries.Add($"FAILED: {relativePath} - {ex.Message}");
}
}
logEntries.Add("---");
logEntries.Add($"Anonymization completed: {DateTime.Now}");
logEntries.Add($"Succeeded: {successCount}");
logEntries.Add($"Failed: {failCount}");
// Write log file
File.WriteAllLines(logFile, logEntries);
Console.WriteLine($"Processing complete. Log saved to: {logFile}");배치 처리에 대한 최고의 관행
- Data Copy를 실행하십시오: 원본 데이터 자체가 아닌 원래 데이터의 복사본을 항상 처리합니다.
- Log All Operations: 어떤 파일이 처리되었는지 및 발생한 오류에 대한 자세한 기록을 유지합니다.
- Test First: 전체 데이터 세트를 처리하기 전에 작은 샘플을 실행합니다.
- Monitor Disk Space : 출력 파일에 충분한 디스크 공간을 제공합니다.
- Handle Interruptions: 매우 큰 배치에 대한 체크 포인트/수수 기능 구현을 고려하십시오.
Troubleshooting
메모리 문제 대규모 데이터 세트
매우 큰 파일 또는 데이터 세트는 참조를 유지하지 않고 한 번에 하나씩 파일을 처리합니다.
foreach (string filePath in dicomFiles)
{
using (DicomFile dcm = DicomFile.Open(filePath))
{
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
anonymizedDcm.Save(outputPath);
}
// Files are disposed after each iteration
}허가 오류
응용 프로그램이 입력 디렉토리에 대한 액세스를 읽고 출력을 입력하는 데 접근하는지 확인하십시오.
결론
이 튜토리얼은 Aspose.Medical을 사용하여 C#에서 DICOM 파일을 익명화하는 방법을 보여주었습니다.수백 또는 수천 개의 파일를 처리하든, 배치 접근 방식은 전체 데이터 세트를 통해 일관된 익명을 보장하며 생산의 신뢰성을 위해 진보 추적 및 오류 처리을 제공합니다.