首页 > 其他分享 >医学DICOM文件与PACS系统进行数据传输

医学DICOM文件与PACS系统进行数据传输

时间:2024-09-14 11:35:33浏览次数:11  
标签:PACS DICOM connectPara client 服务器 WriteLine Dicom 数据传输

最近在做一个医疗项目,其中设计到医学影像数据Dicom文件的传输,其中的一个功能是需要Dicom文件和PACS系统进行互通,就是能将本地的DICOM文件传输到PACS系统,并且本地系统能查询到PACS系统数据并下载。针对将文件上传到PACS系统。之前我们项目中都是使用的C++来处理的。C#的项目都是通过调用C++封装的接口来实现与PACS的数据传输。我这里做了实现了两种方案,都是纯C#实现,并且都已走通。
方式一:通过C#的开源库fo-dicom来实现的数据传输,直接通过NuGet安装相关的依赖包,比如我这里是NET6,搜索并下载fo-dicom.NetCore,如果是.net framework版本的,应该是搜索fo-dicom安装即可。也可以去github上下载源码笔记编译。这里直接上代码,代码中都有注释。

方式一:基于fo-dicom的开源库来实现
        /// <summary>
        /// 发送Dicom数据到PACS系统,C#实现方式
        /// </summary>
        /// <param name="dicomFilePath">Dicom文件路径</param>
        /// <param name="nodeName">Dicom节点名称,我这里是根据节点来找到对应的PACS服务器信息</param>
        /// <returns></returns>
        public async Task SendDicomFileToPacs(string dicomFilePath, string nodeName)
        {
            DICOMConnectParameterWrapper connectPara = new DICOMConnectParameterWrapper();
            DICOMConnectKeyWrapper connectKey = new DICOMConnectKeyWrapper();
            bool isSecure = false;
            if (GetConnectionParameter(nodeName, ref connectPara, ref connectKey, ref isSecure) == false)
            {
                await Task.CompletedTask; //如果找不到配置的PACS服务器信息,直接返回
            }
            //connectPara.ServiceIP=PACS服务器IP,connectPara.ServicePort=PACS服务器端口,connectPara.ClientAETitle=客户端AETITLE,connectPara.ServiceAETitle=PACS服务器AEtitle
            var client = new Dicom.Network.Client.DicomClient(connectPara.ServiceIP, Convert.ToInt32(connectPara.ServicePort), false, connectPara.ClientAETitle, connectPara.ServiceAETitle);
            var file = DicomFile.Open(@dicomFilePath);

            client.AssociationAccepted += (sender, args) =>
            {
                Console.WriteLine("Association accepted");
            };
            client.AssociationRejected += (sender, args) =>
            {
                Console.WriteLine("Association rejected");
            };
            client.RequestTimedOut += (sender, args) =>
            {
                Console.WriteLine("DIMSE timeout");
            };
            client.StateChanged += (sender, args) =>
            {
                Console.WriteLine("DIMSE progress: {0} / {1}", args.NewState.ToString(), args.OldState.ToString());
            };
            await client.AddRequestAsync(new Dicom.Network.DicomCStoreRequest(@dicomFilePath)
            {
                OnResponseReceived = (req, res) =>
                {
                    Console.WriteLine($"C-STORE response: {res.Status}");
                }
            });
            try
            {
                await client.SendAsync();
            }
            catch(Exception ex)
            {
                Console.WriteLine("An error occurred while sending the DICOM file: {0}", ex.Message);
            }
            
        }

在方式一中,这里封装的是针对简单的传输。是在PACS系统不需要认证等前提下,就是说数据传输不需要加密认证等。 当然,实际使用时,PACS系统有些会有安全和认证机制,我们需要根据实际情况处理。我这里的方法GetConnectionParameter是封装的根据PACS节点名来找到对应的PACS的配置,比如PACS的服务器IP,Port,是否加密,证书,等等。如果有加密或认证什么的,还需要进一步处理,我这里会涉及到多个PACS服务器系统,我是在系统中做了配置,通过nodeName来找到对一个的PACS系统的信息。

GetConnectionParameter获取PACS服务器信息
        private bool GetConnectionParameter(string nodeName, ref DICOMConnectParameterWrapper connectPara, ref DICOMConnectKeyWrapper connectKey, ref bool isSecure)
        {
            if (!DicomPeerDictionary.ContainsKey(nodeName))
            {
                return false;
            }
            DicomNodeBase node = DicomPeerDictionary[nodeName];

            connectPara.ClientAETitle = ConfigInfo.DicomNode_ClientAETitle; //客户端AETitle
            connectPara.ClientIP = CommonHelper.GetAddressIP(); //客户端IP地址
            connectPara.ClientPort = ConfigInfo.DicomNode_ClientPort; //客户端端口
            connectPara.ServiceAETitle = node.AETitle; //PACS服务器AETitle
            connectPara.ServiceIP = node.IP; //PACS服务器IP
            connectPara.ServicePort = node.Port; //PACS服务器端口

            connectKey.PrivateKey = node.PrivateKeyPath; //秘钥
            connectKey.CACertificateFile = node.CACertificatePath; //CA证书文件
            connectKey.CertificateFile = node.CertificatePath; //证书

            isSecure = node.IsEncryptionChecked; //是否加密

            return true;
        }

使用的时候就简单了,直接调用SendDicomFileToPacs方法,传入Dicom文件的全路径,以及PACS配置的NodeName即可。另外,我这里用的fo-dicom的库是fo-dicom.netcore的4.0.8版本的,每个版本的可能会有些差别。这里还有涉及到从PACS查询数据,下载数据的功能,这个在fo-dicom库中可以使用类Dicom.Network.DicomCFindRequest来进行操作,其中封装了好几个查询的方法:CreateStudyQuery,CreateSeriesQuery,CreatePatientQuery,CreateImageQuery,CreateWorklistQuery,然后询请求的响应通过类中的OnResponseReceived事件处理,可以获取到查询结果的数据集。我们可以将查询结果的数据集直接转换成一个DICOM文件保存到本地,这样就可以实现下载功能。

方式二:传输数据到PACS的实现方式
这种方式我是针对Orthanc的PACS系统的实现方式,,Orthanc本身有提供API接口,只需要调用其接口实现数据传输即可。使用的时候传入Dicom文件路径和PACS服务器URL即可。这里代码如下。

发送数据到Orthanc的PACS系统
        /// <summary>
        /// 发送数据到Orthanc的PACS系统,C#实现方式,直接调用Orthanc的API来实现
        /// </summary>
        /// <param name="dicomFilePath">Dicom文件路径</param>
        /// <param name="orthancUrl">PACS系统的URL,类似 http://localhost:8042</param>
        public void UploadDicomToOrthanc(string dicomFilePath, string orthancUrl)
        {
            using (var client = new HttpClient())
            {
                using (var content = new MultipartFormDataContent())
                {
                    // 添加文件内容
                    var fileStream = File.OpenRead(dicomFilePath);
                    var streamContent = new StreamContent(fileStream);
                    content.Add(streamContent, "file", Path.GetFileName(dicomFilePath));

                    // 发送POST请求到Orthanc服务器
                    var response =  client.PostAsync($"{orthancUrl}/instances", content).Result;

                    if (response.IsSuccessStatusCode)
                    {
                        Console.WriteLine("DICOM文件上传成功。");
                    }
                    else
                    {
                        Console.WriteLine("上传失败,HTTP状态码:" + response.StatusCode);
                    }
                }
            }

        }

标签:PACS,DICOM,connectPara,client,服务器,WriteLine,Dicom,数据传输
From: https://www.cnblogs.com/huangqian/p/18413651

相关文章

  • 【干货分享】Ftrans安全数据交换系统 搭建跨网数据传输通道
    安全数据交换系统是一种专门设计用于在不同的网络、系统或组织之间安全地传输数据的软件或硬件解决方案。这种系统通常包含多种安全特性,以确保数据在传输过程中的保密性、完整性和可用性。安全数据交换系统可以解决哪些问题?安全数据交换系统主要解决以下问题:数据泄露风险:通过加......
  • 【带宽、主频、位宽、数据传输速率】DDR带宽怎么计算?
    1.如何计算DDR带宽计算DDR理论带宽的公式为:DDR主频*位宽=理论带宽1其中,位宽(bitwidth)指的是内存总线的位宽,例如64位、128位、16bit、32bit等,bit意为"位"或"比特"。主频指的是DDR内存的实际主频,而不是DDR内存的倍频频率。因此,在计算理论带宽时,需要将DDR主频和位宽相乘即可......
  • ubuntu20.04 Qt6引用dcmtk库实现dicom文件读取和字符集转换
    1环境问题安装完Qt6,新建Qt/QtQuickCMake工程编译出现如下错误:Foundpackageconfigurationfile:Qt6Config.cmakebutitsetQt6FOUNDtoFALSEsopackage"Qt6"isconsideredtobeNOTFOUND.原因:这是因为系统中缺少OpenGL库,可以安装libgl1-mesa-dev解决方法:su......
  • Ftrans无缝替代FTP方案:保障数据传输的安全性与合规性!
    FTP(文件传输协议)是一种用于在网络上进行文件传输的标准网络协议,历史悠久并且被广泛使用。但随着业务规模和文件体量的快速增长,在应用实践中,FTP存在一些安全和效率问题。因此政府单位需要可以平滑替代FTP的文件传输解决方案,从而更好的保障数据安全、提升工作效率。具体存在以下问题......
  • ubuntu 和windows用samba服务器实现数据传输
    1,linux安装samba服务器sudoapt-getinstallsambasamba-common2,linux配置权限,修改目录权限,linux下共享的文件权限设置。sudochmod777/home/lark-R3.添加samba用户 sudosmbpasswd-a lark4,配置共享目录打开/smb.conf在文件末尾添加如下信息: vim/et......
  • IC设计企业进行云租户数据传输最大的问题是什么?如何解决?
    越来越多的IC设计企业基于云租户进行芯片的设计、仿真及验证流程,其原因在于:降低成本:由于资源共享,租户无需单独购买、部署和维护昂贵的硬件设备,只需按需付费,大大降低了初期投资和运营成本。弹性扩展:云租户可以根据业务需求快速、灵活地调整计算和存储资源,无需担心硬件限制或升级......
  • Python2数据传输测试脚本
    服务端#-*-coding:utf-8-*-importsocketimportthreadingHOST='0.0.0.0'PORT=12345defhandle_client(conn,addr):print"连接地址:",addrtry:whileTrue:data=conn.recv(1024000)......
  • Python自动化批量创建CloudWatch告警监控Amazon OpenSearch Service数据传输
    在使用AmazonOpenSearchService时,确保数据传输的可靠性和完整性至关重要。本文将介绍如何使用Python脚本自动批量创建CloudWatch告警,以监控多个KinesisDataFirehose向OpenSearch传输数据的成功率。为什么要监控数据传输成功率?及时发现问题:当数据传输出现异常时,......
  • 数据摆渡工具:构建安全的跨网数据传输通道
    数据摆渡工具可以解决哪些问题?数据摆渡工具的主要作用是实现不同网络环境下,人与人、人与系统或者系统与系统之间的数据安全、高效传输及管理问题。这类工具主要可以解决以下问题:1、数据传输与同步跨网络数据传输:内外网数据摆渡产品可以安全地将数据从内部系统迁移到外部云服务......
  • 边缘计算网关:开启高速数据传输的新篇章
    一、引言随着物联网、大数据和人工智能技术的飞速发展,数据传输速度和效率成为制约系统性能的关键因素。我们自主生产的Mbox边缘计算网关,以其高速数据传输能力,为各类应用场景提供了强大的支持。本文将为您介绍边缘计算网关的高速数据传输原理及其在现实各行各业中的应用。二、边缘计......