DICOM 연구의 폴더를 익명화하는 방법

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 파일을 익명화하는 방법을 보여주었습니다.수백 또는 수천 개의 파일를 처리하든, 배치 접근 방식은 전체 데이터 세트를 통해 일관된 익명을 보장하며 생산의 신뢰성을 위해 진보 추적 및 오류 처리을 제공합니다.

 한국어