fo-dicom,第一个基于.NET Standard 2.0 开发的DICOM开源库

embedded/2024/9/25 19:18:06/

在这里插入图片描述

1. 简介:

fo-dicom是一个基于C#开发的库,用于处理DICOM(Digital Imaging and Communications in Medicine)格式的数据。DICOM是一种用于医学影像和相关信息的标准格式,广泛应用于医学领域。fo-dicom提供了多平台支持,可在 Windows、Linux 和 macOS 等操作系统上运行。

fo-dicom库的设计理念是提供一个方便、易用、功能强大的工具,用于处理、读取、写入和修改DICOM文件。该库提供了丰富的API,支持对DICOM文件的标签进行读取和设置,支持对DICOM文件的编码和解码,支持对DICOM文件的传输和存储。

fo-dicom库还提供了对DICOM消息流的封装,使得开发者可以方便地实现自定义的DICOM服务。该库还支持对网络底层的封装,使得开发者可以轻松地实现基于网络的DICOM通信。

开源库地址

2. 开发的背景和目的:

fo-dicom库的产生是为了解决医学图像处理和DICOM数据交换的需求。在医学领域,DICOM(Digital Imaging and Communications in Medicine)是一种用于存储、传输和共享医学影像和相关信息的标准。由于医学影像数据的特殊性和复杂性,需要一个专门的库来处理DICOM数据,并提供方便的接口和工具。

背景上来说,DICOM标准的出现是为了解决各种医学设备之间的互操作性问题。在过去,不同厂商的医学设备使用自己的私有格式来存储和传输影像数据,这导致了数据共享和集成的困难。DICOM标准的制定使得不同设备可以使用统一的格式和通信协议,从而实现医学影像的无缝交流和协作。

fo-dicom作为一个开源的DICOM库,旨在提供一个易于使用且功能强大的工具,使得开发者能够处理医学图像和相关数据。它基于DICOM标准,提供了读取、创建、修改和存储DICOM数据的功能,同时支持医学图像的加载、处理和保存。此外,fo-dicom还具备与远程PACS(Picture Archiving and Communication System)或其他DICOM节点的网络通信能力,以及查询和检索功能,方便用户根据条件查询和获取DICOM实例。

3.主要特点和安装方式

阅读官方文档,即可获得安装方法:官方文档
在这里插入图片描述

4. 主要功能:

  • DICOM 数据处理:fo-dicom 支持读取、创建、修改和存储 DICOM 数据。用户可以轻松访问和操作 DICOM 文件和数据集。
  • 图像处理:该库提供了对医学图像的加载、处理和保存功能。用户可以进行像素级别的操作、图像增强、格式转换等操作。
  • DICOM 网络通信:fo-dicom 具备与远程 PACS 或其他 DICOM 节点的网络通信能力,使用户可以发送和接收 DICOM 消息。
  • 查询和检索:fo-dicom 实现了查询和检索功能,用户可以根据条件进行 DICOM 实例的查询和获取。这有助于快速访问所需的医学图像和相关数据。

5. 使用说明:

图像渲染配置

开箱即用的 fo-dicom 默认为内部类
FellowOakDicom.Imaging.IImage 样式的图像渲染。若要切换到桌面样式或 ImageSharp 样式的图像呈现,首先必须添加所需的 nuget 包,然后调用:

new DicomSetupBuilder().RegisterServices(s => s.AddFellowOakDicom().AddImageManager<WinFormsImageManager>())
.Build();new DicomSetupBuilder().RegisterServices(s => s.AddFellowOakDicom().AddImageManager<ImageSharpImageManager>())
.Build();

然后,在渲染时,可以通过以下方式将 IImage 强制转换为类型

var image = new DicomImage("filename.dcm");
var bitmap = image.RenderImage().As<Bitmap>();
//或
var image = new DicomImage("filename.dcm");
var sharpimage = image.RenderImage().AsSharpImage();

日志记录配置

Fellow Oak DICOM 使用 ,因此如果您已经在使用它,则 Fellow Oak DICOM 日志记录将自动显示。
Microsoft.Extensions.Logging

过去,Fellow Oak DICOM 有一个用于日志记录的自定义抽象:ILogger 和 ILogManager。 出于向后兼容性的目的,这仍然受支持,但不建议用于新应用程序。

services.AddLogManager<MyLogManager>();

其中 MyLogManager 如下所示:

using FellowOakDicom.Log;public class MyLogManager: ILogManager {public ILogger GetLogger(string name) {...}
}

6示例应用程序

这里有许多使用 fo-dicom 的简单示例应用程序,它们位于单独的存储库中。这些还包括示例 以前包含在 VS 解决方案的“示例”子文件夹中。

文件操作

var file = DicomFile.Open(@"test.dcm");             // Alt 1
var file = await DicomFile.OpenAsync(@"test.dcm");  // Alt 2var patientid = file.Dataset.GetString(DicomTag.PatientID);file.Dataset.AddOrUpdate(DicomTag.PatientName, "DOE^JOHN");// creates a new instance of DicomFile
var newFile = file.Clone(DicomTransferSyntax.JPEGProcess14SV1);file.Save(@"output.dcm");             // Alt 1
await file.SaveAsync(@"output.dcm");  // Alt 2

将图像渲染为 JPEG

var image = new DicomImage(@"test.dcm");
image.RenderImage().AsBitmap().Save(@"test.jpg");                     // Windows Forms

C-Store SCU系列

var client = DicomClientFactory.Create("127.0.0.1", 12345, false, "SCU", "ANY-SCP");
await client.AddRequestAsync(new DicomCStoreRequest(@"test.dcm"));
await client.SendAsync();

C-Echo SCU/SCP

var server = new DicomServer<DicomCEchoProvider>(12345);var client = DicomClientFactory.Create("127.0.0.1", 12345, false, "SCU", "ANY-SCP");
client.NegotiateAsyncOps();
// Optionally negotiate user identity
client.NegotiateUserIdentity(new DicomUserIdentityNegotiation
{UserIdentityType = DicomUserIdentityType.Jwt,PositiveResponseRequested = true,PrimaryField = "JWT_TOKEN"
});
for (int i = 0; i < 10; i++)await client.AddRequestAsync(new DicomCEchoRequest());
await client.SendAsync();
C-Find SCUvar cfind = DicomCFindRequest.CreateStudyQuery(patientId: "12345");
cfind.OnResponseReceived = (DicomCFindRequest rq, DicomCFindResponse rp) => {Console.WriteLine("Study UID: {0}", rp.Dataset.GetString(DicomTag.StudyInstanceUID));
};var client = DicomClientFactory.Create("127.0.0.1", 11112, false, "SCU-AE", "SCP-AE");
await client.AddRequestAsync(cfind);
await client.SendAsync();

C-Move SCU系列

var cmove = new DicomCMoveRequest("DEST-AE", studyInstanceUid);var client = DicomClientFactory.Create("127.0.0.1", 11112, false, "SCU-AE", "SCP-AE");
await client.AddRequestAsync(cmove);
await client.SendAsync(); 

N-Action SCU

// It is better to increase 'associationLingerTimeoutInMs' default is 50 ms, which may not be
// be sufficient
var dicomClient = DicomClientFactory.Create("127.0.0.1", 12345, false, "SCU-AE", "SCP-AE",
DicomClientDefaults.DefaultAssociationRequestTimeoutInMs, DicomClientDefaults.DefaultAssociationReleaseTimeoutInMs,5000);
var txnUid = DicomUIDGenerator.GenerateDerivedFromUUID().UID;
var nActionDicomDataSet = new DicomDataset
{{ DicomTag.TransactionUID,  txnUid }
};
var dicomRefSopSequence = new DicomSequence(DicomTag.ReferencedSOPSequence);
var seqItem = new DicomDataset()
{{ DicomTag.ReferencedSOPClassUID, "1.2.840.10008.5.1.4.1.1.1" },{ DicomTag.ReferencedSOPInstanceUID, "1.3.46.670589.30.2273540226.4.54" }
};
dicomRefSopSequence.Items.Add(seqItem);
nActionDicomDataSet.Add(dicomRefSopSequence);
var nActionRequest = new DicomNActionRequest(DicomUID.StorageCommitmentPushModelSOPClass,DicomUID.StorageCommitmentPushModelSOPInstance, 1)
{Dataset = nActionDicomDataSet,OnResponseReceived = (DicomNActionRequest request, DicomNActionResponse response) => {Console.WriteLine("NActionResponseHandler, response status:{0}", response.Status);},
};
await dicomClient.AddRequestAsync(nActionRequest);
dicomClient.OnNEventReportRequest = OnNEventReportRequest;
await dicomClient.SendAsync();private static Task<DicomNEventReportResponse> OnNEventReportRequest(DicomNEventReportRequest request)
{var refSopSequence = request.Dataset.GetSequence(DicomTag.ReferencedSOPSequence);foreach(var item in refSopSequence.Items){Console.WriteLine("SOP Class UID: {0}", item.GetString(DicomTag.ReferencedSOPClassUID));Console.WriteLine("SOP Instance UID: {0}", item.GetString(DicomTag.ReferencedSOPInstanceUID));}return Task.FromResult(new DicomNEventReportResponse(request, DicomStatus.Success));
}

C-ECHO

具有高级 DICOM 客户端连接的 C-ECHO:手动控制 TCP 连接和 DICOM 关联

var cancellationToken = CancellationToken.None;
// Alternatively, inject IDicomServerFactory via dependency injection instead of using this static method
using var server = DicomServerFactory.Create<DicomCEchoProvider>(12345); var connectionRequest = new AdvancedDicomClientConnectionRequest
{NetworkStreamCreationOptions = new NetworkStreamCreationOptions{Host = "127.0.0.1",Port = server.Port,}
};// Alternatively, inject IAdvancedDicomClientConnectionFactory via dependency injection instead of using this static method
using var connection = await AdvancedDicomClientConnectionFactory.OpenConnectionAsync(connectionRequest, cancellationToken);var associationRequest = new AdvancedDicomClientAssociationRequest
{CallingAE = "EchoSCU",CalledAE = "EchoSCP",// Optionally negotiate user identityUserIdentityNegotiation = new DicomUserIdentityNegotiation{UserIdentityType = DicomUserIdentityType.UsernameAndPasscode,PositiveResponseRequested = true,PrimaryField = "USERNAME",SecondaryField = "PASSCODE",}
};var cEchoRequest = new DicomCEchoRequest();using var association = await connection.OpenAssociationAsync(associationRequest, cancellationToken);
try
{DicomCEchoResponse cEchoResponse = await association.SendCEchoRequestAsync(cEchoRequest, cancellationToken).ConfigureAwait(false);Console.WriteLine(cEchoResponse.Status);
}
finally
{await association.ReleaseAsync(cancellationToken);
}

7. 社区和生态:

fo-dicom 有一个活跃的社区,包括众多贡献者和维护者。它在 GitHub 上有一个开放的仓库,用户可以在其中提交问题、提出建议和贡献代码。fo-dicom 的更新频率较高,并得到了广泛的应用和认可。

为了方便新手学习官方构建了样例库:
在这里插入图片描述
同时支持多个平台的案例开发开发。
在这里插入图片描述

8. 优势和劣势:

  • 优势:fo-dicom 是一个强大且易于使用的 DICOM 库,具备处理医学图像和相关数据的核心功能。它提供了多平台支持、良好的文档和示例代码,并拥有一个活跃的社区。
  • 劣势:由于 DICOM 标准的复杂性,初学者可能需要一些时间来适应 fo-dicom 的使用方式。另外,某些高级功能可能需要额外的配置或第三方组件的支持。

9. 未来计划和发展方向:

fo-dicom 的未来计划包括进一步增强图像处理功能、优化性能、改进网络通信和增加对新版 DICOM 标准的支持。通过不断改进和扩展功能,fo-dicom 将继续满足用户对医学图像处理和数据交互的需求。

今天先介绍到这里,后续我将持续分享关于fo-dicom库的使用经验技巧,欢迎有需要的朋友持续关注。


http://www.ppmy.cn/embedded/116783.html

相关文章

【大模型实战篇】关于Bert的一些实操回顾以及clip-as-service的介绍

最近在整理之前的一些实践工作&#xff0c;一方面是为了笔记记录&#xff0c;另一方面也是自己做一些温故知新&#xff0c;或许对于理解一些现在大模型工作也有助益。 1. 基于bert模型实现中文语句的embedding编码 首先是基于bert模型实现中文语句的embedding编码&#xff0c;…

策略模式+模版模式+工厂模式

工厂模式&#xff1a; &#xff08;1&#xff09;避免类中出现过多的组合依赖 &#xff08;2&#xff09;同时减少代码中出现过多的if...else if...语句 &#xff08;2&#xff09;将调用者跟我们的实现类解耦 模版模式&#xff1a; &#xff08;1&#xff09;功能复用 &…

重建大师能否根据兴趣区域对照片进行分块?

针对这种情况可以按kml范围线筛选。 重建大师&#xff0c;这是一款专为超大规模实景三维数据生产设计的集群并行处理软件&#xff0c;支持卫星影像、航空影像、倾斜影像和激光点云多源数据输入建模&#xff0c;可完成超大规模数据的空三解算、自动三维建模&#xff0c;输出高精…

基于MATLAB的虫害检测系统

课题背景介绍 中国为农业大国&#xff0c;因此在农业病虫害防治等方面积累了丰富的经验&#xff0c;但在实际工作过程中也存在许多问题。如过于依赖传统经验&#xff0c;对突如而来的新型病虫害问题研究不够到位&#xff0c;如由于判断者主观上面的一些模糊&#xff0c;而带来…

Unreal Engine 5 C++: Asset Batch Duplication插件编写02

目录 准备工作 "Scripting library" 三个最重要的功能&#xff08;前两个是UEditorUtilityLibrary中的&#xff09; 自动创建声明&#xff1a; TArray T 的含义 F 的含义 Live Coding &#xff08;Ctrlalt F11&#xff09; Live Coding 的工作流程&#xff…

竹云赋能“中国·贵州”全省统一移动应用平台建设,打造政务服务“新引擎”

近日&#xff0c;2024中国国际大数据产业博览会在贵州贵阳圆满落幕。会上&#xff0c;由贵州省政府办公厅牵头建设的“中国贵州”全省统一移动应用平台正式发布&#xff0c;聚焦民生办事、政务公开、政民互动、扁平高效、数据赋能五大模块&#xff0c;旨在打造公平普惠的服务平…

monaco-editor基本使用

前言 公司项目需要代码编辑器&#xff0c;多方参考之后用了monaco-editor。 一、monaco-editor是什么&#xff1f; Monaco Editor 是微软开源的基于 VS Code 的代码编辑器&#xff0c;运行在浏览器环境中。 二、使用步骤 1.npm下载插件 //我下载的版本 npm i monaco-edit…

清理C盘缓存,电脑缓存清理怎么一键删除,操作简单的教程

清理C盘缓存是维护电脑性能、释放磁盘空间的重要步骤。以下是一个详细且操作简单的教程&#xff0c;旨在帮助用户通过一键或几步操作完成C盘缓存的清理。 1.使用Windows系统自带工具 磁盘清理 1.打开磁盘清理工具&#xff1a; -按下“WinE”打开文件资源管理器…