从 dcm4che2 迁移到 dcm4che3

2024-02-11

我使用了下面提到的来自此存储库的 dcm4che2 APIhttp://www.dcm4che.org/maven2/dcm4che/ http://www.dcm4che.org/maven2/dcm4che/在我的java项目中。

dcm4che-core-2.0.29.jar

org.dcm4che2.data.DicomObject  
org.dcm4che2.io.StopTagInputHandler  
org.dcm4che2.data.BasicDicomObject  
org.dcm4che2.data.UIDDictionary  
org.dcm4che2.data.DicomElement  
org.dcm4che2.data.SimpleDcmElement  
org.dcm4che2.net.service.StorageCommitmentService  
org.dcm4che2.util.CloseUtils  

dcm4che-net-2.0.29.jar

org.dcm4che2.net.CommandUtils  
org.dcm4che2.net.ConfigurationException  
org.dcm4che2.net.NetworkApplicationEntity  
org.dcm4che2.net.NetworkConnection  
org.dcm4che2.net.NewThreadExecutor  
org.dcm4che3.net.service.StorageService  
org.dcm4che3.net.service.VerificationService  

目前我想迁移到 dcm4che3,但是,在我从该存储库下载的 dcm4che3 中找不到上面列出的 APIhttp://sourceforge.net/projects/dcm4che/files/dcm4che3/ http://sourceforge.net/projects/dcm4che/files/dcm4che3/
您能指导我采用替代方法吗?


正如您已经观察到的,BasicDicomObject 与其他一些对象一样已经成为历史。

新的“Dicom 对象”是属性——对象是属性的集合。

因此,您创建属性,用 RQ 行为(C-FIND 等)所需的标签填充它们,而您得到的回报是另一个属性对象,您可以从中提取所需的标签。

在我看来,dcm4che 2.x 在处理个体值表示的主题上含糊不清。 dcm4che 3.x 更加清晰。

迁移需要重写有关如何查询以及如何处理各个标签的代码。另一方面,dcm4che 3.x 使新代码不再那么复杂。

根据要求,我添加了与某些服务类提供商 (SCP) 的连接的初始设置:

// Based on org.dcm4che:dcm4che-core:5.25.0 and org.dcm4che:dcm4che-net:5.25.0
import org.dcm4che3.data.*;
import org.dcm4che3.net.*;
import org.dcm4che3.net.pdu.AAssociateRQ;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.pdu.RoleSelection;
import org.dcm4che3.net.pdu.UserIdentityRQ;


// Client side representation of the connection. As a client, I will 
// not be listening for incoming traffic (but I could choose to do so
// if I need to transfer data via MOVE)
Connection local = new Connection();
local.setHostname("client.on.network.com");
local.setPort(Connection.NOT_LISTENING);

// Remote side representation of the connection
Connection remote = new Connection();
remote.setHostname("pacs.on.network.com");
remote.setPort(4100);

remote.setTlsProtocols(local.getTlsProtocols());
remote.setTlsCipherSuites(local.getTlsCipherSuites());

// Calling application entity
ApplicationEntity ae = new ApplicationEntity("MeAsAServiceClassUser".toUpperCase());
ae.setAETitle("MeAsAServiceClassUser");
ae.addConnection(local); // on which we may not be listening
ae.setAssociationInitiator(true);
ae.setAssociationAcceptor(false);

// Device
Device device = new Device("MeAsAServiceClassUser".toLowerCase());
device.addConnection(local);
device.addApplicationEntity(ae);

// Configure association
AAssociateRQ rq = new AAssociateRQ();
rq.setCallingAET("MeAsAServiceClassUser");
rq.setCalledAET("NameThatIdentifiesTheProvider"); // e.g. "GEPACS"
rq.setImplVersionName("MY-SCU-1.0"); // Max 16 chars

// Credentials (if appropriate)
String username = "username";
String passcode = "so secret";
if (null != username && username.length() > 0 && null != passcode && passcode.length() > 0) {
    rq.setUserIdentityRQ(UserIdentityRQ.usernamePasscode(username, passcode.toCharArray(), true));
}

例如,对 PACS 执行 ping 操作(使用上面的设置):

String[] TRANSFER_SYNTAX_CHAIN = {
        UID.ExplicitVRLittleEndian,
        UID.ImplicitVRLittleEndian
};

// Define transfer capabilities for verification SOP class
ae.addTransferCapability(
        new TransferCapability(null,
            /* SOP Class */ UID.Verification,
            /* Role */ TransferCapability.Role.SCU,
            /* Transfer syntax */ TRANSFER_SYNTAX_CHAIN)
);

// Setup presentation context
rq.addPresentationContext(
        new PresentationContext(
                rq.getNumberOfPresentationContexts() * 2 + 1,
                /* abstract syntax */ UID.Verification,
                /* transfer syntax */ TRANSFER_SYNTAX_CHAIN
        )
);

rq.addRoleSelection(new RoleSelection(UID.Verification, /* is SCU? */ true, /* is SCP? */ false));

try {
    // 1) Open a connection to the SCP
    Association association = ae.connect(local, remote, rq);

    // 2) PING!
    DimseRSP rsp = association.cecho();
    rsp.next(); // Consume reply, which may fail

    // Still here? Success!
    // 3) Close the connection to the SCP
    if (as.isReadyForDataTransfer()) {
        as.waitForOutstandingRSP();
        as.release();
    }
} catch (Throwable ignore) {
    // Failure
}

另一个例子,从给定登录号的 PACS 中检索研究;设置查询并处理结果:

String modality = null; // e.g. "OT"
String accessionNumber = "1234567890";

//--------------------------------------------------------
// HERE follows setup of a query, using an Attributes object
//--------------------------------------------------------
Attributes query = new Attributes();

// Indicate character set
{
    int tag = Tag.SpecificCharacterSet;
    VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
    query.setString(tag, vr, "ISO_IR 100");
}

// Study level query
{
    int tag = Tag.QueryRetrieveLevel;
    VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
    query.setString(tag, vr, "STUDY");
}

// Accession number
{
    int tag = Tag.AccessionNumber;
    VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
    query.setString(tag, vr, accessionNumber);
}

// Optionally filter on modality in study if 'modality' is provided,
// otherwise retrieve modality
{
    int tag = Tag.ModalitiesInStudy;
    VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
    if (null != modality && modality.length() > 0) {
        query.setString(tag, vr, modality);
    } else {
        query.setNull(tag, vr);
    }
}

// We are interested in study instance UID
{
    int tag = Tag.StudyInstanceUID;
    VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
    query.setNull(tag, vr);
}

// Do the actual query, needing an AppliationEntity (ae),
// a local (local) and remote (remote) Connection, and
// an AAssociateRQ (rq) set up earlier.

try {
    // 1) Open a connection to the SCP
    Association as = ae.connect(local, remote, rq);

    // 2) Query
    int priority = 0x0002; // low for the sake of demo :)
    as.cfind(UID.StudyRootQueryRetrieveInformationModelFind, priority, query, null,
            new DimseRSPHandler(as.nextMessageID()) {

                @Override
                public void onDimseRSP(Association assoc, Attributes cmd,
                                       Attributes response) {

                    super.onDimseRSP(assoc, cmd, response);

                    int status = cmd.getInt(Tag.Status, -1);
                    if (Status.isPending(status)) {
                        //--------------------------------------------------------
                        // HERE follows handling of the response, which
                        // is just another Attributes object
                        //--------------------------------------------------------
                        String studyInstanceUID = response.getString(Tag.StudyInstanceUID);
                        // etc...
                    }
                }
            });

    // 3) Close the connection to the SCP
    if (as.isReadyForDataTransfer()) {
        as.waitForOutstandingRSP();
        as.release();
    }
}
catch (Exception e) {
    // Failure
}

有关此内容的更多信息,请访问https://github.com/FrodeRanders/dicom-tools https://github.com/FrodeRanders/dicom-tools

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 dcm4che2 迁移到 dcm4che3 的相关文章

  • Eclipse 中的 Java 简单电子邮件程序

    我想制作一个简单的程序 您可以从其中发送电子邮件命令行 我找到了这个教程 http www tutorialspoint com java java sending email htm http www tutorialspoint com
  • 如何更改 JComboBox 下拉列表的宽度?

    我有一个可编辑的JComboBox其中包含单个字母值的列表 因此 组合框非常小 每个字母都有特殊的含义 对于很少使用的字母 有时用户并不清楚 因此我创建了一个自定义ListCellRenderer显示下拉列表中每个字母的含义 不幸的是 这个
  • 平衡括号问题的优化解

    给定一个仅包含字符的字符串 and 判断输入字符串是否有效 输入字符串在以下情况下有效 左括号必须由相同类型的括号封闭 左括号必须按正确的顺序关闭 请注意 空字符串也被视为有效 示例1 Input Output true Example 2
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • JSF 错误 - IllegalStateException:PWC3999:提交响应后无法创建会话[重复]

    这个问题在这里已经有答案了 我是 JSF 新手 正在构建一个使用 Facelet 创建的应用程序 这是我的模板master xhtml
  • IntelliJ 建议错误的 @NotNull 注释

    IntelliJ 建议导入com sun istack internal NotNull以下程序中的 NotNull 注释 这是错误的 public class Test implements Comparable
  • 从另一个类添加 Swing 组件

    我正在学习java 我正在尝试从另一个类向我的框架添加一个菜单栏 练习将代码划分为多个类以更好地组织程序 这是我的代码示例 public class MainApp public static void main String args C
  • Android 防火墙与 VpnService

    我正在尝试使用 BS 项目的 VpnService 为 Android 实现一个简单的防火墙 我选择 VpnService 因为它将在非 root 设备上运行 它将记录连接并让您过滤连接 基于IP 有一个应用程序可以做到这一点 因此这是可能
  • Knuth-Morris-Pratt 算法

    解决方案是Knuth Morris Pratt 算法 https en wikipedia org wiki Knuth E2 80 93Morris E2 80 93Pratt algorithm 干草堆 AAAAAAAAA 针 AAA
  • 大型 XML 的 XML 节点到字符串转换

    到目前为止我一直在使用DOM源在我的 Android 应用程序中将 XML 文件转换为字符串 这是我的代码 public String convertElementToString Node element throws Transform
  • JavaFX 动画使用循环?

    我正在尝试制作一款类似太空侵略者的游戏 我画了一个正方形 我想通过使用循环逐步向下移动它thread sleep 然而 正方形立即被绘制出来 我知道有可以使用的动画路径 但我想保持低水平并仅使用坐标系 有没有办法使用这样的循环来制作时间轴动
  • Java中的运算符重载和覆盖

    运算符重载和运算符重写有什么区别 它们在继承和控制台程序中是否相同 Java 不支持运算符重载和重写 检查以下引用自的描述 http java sun com docs white langenv Simple doc2 html http
  • Java Timer 类:如果其中一个任务抛出异常,则计时器任务停止执行

    new Timer scheduleAtFixedRate new TimerTask Override public void run System out println run throw new SomeRandomExceptio
  • 未从线程接收位置数据

    我尝试使用计时器经常发送包含用户位置的短信 最初 我遇到了空指针异常 这是由于我犯了一个简单的错误 一旦解决了这个问题 一切似乎都运行良好 但是 它永远不会获取我的位置 因此 不断发送的文本显示 无法接收位置 我想问的是为什么它无法获取我的
  • 不想保留一对一的实体

    假设我有两节课Employee and Department In Employee我已经写了 OneToOne fetch FetchType EAGER cascade CascadeType ALL JoinColumn name d
  • 错误:列“this_.phitorsionangle”必须出现在 GROUP BY 子句中或在聚合函数中使用

    我在执行 sql 查询时遇到了一些问题 我正在使用 Hibernate Criteria 来构建查询 我通过按一定间隔 binSize 舍入值然后对它们进行分组来从数据库创建一些容器 当我直接在 SQL 中使用查询尝试时 效果非常好 SEL
  • 为什么我的 Java 路径中添加了“L”?

    我在我的类路径中加载了一个 jar 在 iReport 中 如果重要的话 我确信它具有所需的方法 但是当我尝试测试连接 从而调用该 jar 时 我得到一个 java lang NoSuchMethodError 说它正在引用班上 Lorg
  • 使用 OpenNLP 获取句子的解析树。陷入困境。

    OpenNLP 是一个关于自然语言处理的 Apache 项目 NLP 程序的目标之一是解析一个句子 并给出其语法结构的树 例如 天空是蓝色的 这句话 可能会被解析为 S NP VP The sky is blue where S是句子 NP
  • 丰富:数据表行跨度问题

    我需要创建一个 rich dataTable 甚至扩展 具有以下功能 我有一个公司类 其中包含产品对象的集合 我想展示下表 我仍然没有弄清楚如何使用子表执行此操作 在所有示例中 我发现子表具有与主表完全相同的列 据推测 我需要在前两列中使用
  • 使用 Spring Batch 将文件中的日期解析为 LocalDateTime

    我正在尝试使用 Spring Batch 读取包含日期的 CSV 文件 但在将日期解析为LocalDateTime Object 字段 日期 上的对象 目标 中的字段错误 拒绝值 2017 07 20 04 15 25 0 代码 typeM

随机推荐

  • Discord.js 获取具有特定角色的所有成员

    我正在尝试让所有具有特定角色的成员加入 每当我运行该命令时 我只得到我自己和机器人 如果机器人具有该角色 但服务器中还有其他 4 个人具有相同的角色 但他们都没有出现 如果我获取所有成员 他们就会表现得很好 有谁知道为什么会发生这种情况 C
  • WPF 中的全局鼠标挂钩

    我需要获取鼠标在屏幕上的位置NOT在我的应用程序中 我用过全局鼠标和键盘钩子here http www codeproject com Articles 7294 Processing Global Mouse and Keyboard H
  • Julia DataFrames.jl - 使用 NA 过滤数据 (NAException)

    我不知道如何处理NA在 Julia DataFrames 中 例如 使用以下 DataFrame gt import DataFrames gt a DataFrames data 1 2 3 4 5 gt b DataFrames dat
  • JSP Web 应用程序中的国际化?

    在我当前的项目中 我们正在考虑逐步淘汰旧的表示层 并用更现代 更知名的东西取代它 由于各种原因 选择 JSP 作为技术 可能与 Apache Tiles 结合使用 我或许应该提到 如果这很重要的话 我们正在后面使用 Spring 国际化是一
  • SwiftUI ViewModel 发布的属性和绑定

    我的问题可能是误解的结果 但我无法弄清楚 所以这里是 使用 TextField 等组件或任何其他需要绑定作为输入的组件时 TextField title StringProtocol text Binding
  • Python 中的带宽限制

    哪些库可以让您控制网络请求 特别是 http 的下载速度 我没有在 urllib2 中看到任何内置内容 也没有在我打算使用的 Py Qt 中看到 Twisted 可以控制带宽吗 如果没有 如何控制 urllib2 或 Twisted 的读取
  • AngularJS序列化表单数据

    我希望在 angularjs 中序列化表单数据 以下是控制器代码 function SearchCtrl scope element http scope url php search php scope submit function v
  • 导航栏不显示 iOS swift

    我的应用程序中有多个视图控制器 我想隐藏navigationbar在我的第一个视图控制器中 所以我使用下面的代码来隐藏导航栏 navigationController setNavigationBarHidden navigationCon
  • 如何使正则表达式仅匹配西里尔保加利亚字母

    您好 我想用空字符串替换拜尔加字母表中的所有字母 我看过这个链接如何将西里尔字母与正则表达式匹配 https stackoverflow com questions 1716609 how to match cyrillic charact
  • 多重赋值是 Obj-C 中的 hack 吗?

    所以 我有一个带有一堆属性的类 IKImageView 我知道视图 setProp BOOL 返回 void 然而 BOOL b view prop NO 似乎有效 如果我有一个返回布尔值的函数 f 有谁知道这是否真的在做 view set
  • 如何使用特定变量名来 save()

    我反复应用一个函数来读取和处理一堆 csv 文件 每次运行时 该函数都会创建一个数据框 this csv data 并使用 save 将其写入 RData具有唯一名称的文件 问题是 后来当我读到这些时 RData文件使用load 加载的变量
  • 如何检查容器的IP,获取它并将其添加到具有本地域名解析的/etc/hosts文件中

    我正在使用 docker 容器在 Linux Ubuntu 上工作 我希望将以下内容添加到新行中的 etc hosts 的最后一行 IP from docker container 主机名 分配 172 20 1 2 docker dev
  • Python Tkinter:在 for 循环中将函数与标签绑定

    我正在动态创建标签for loop using tkinter 我不知道将创建多少个标签 但单击每个标签时 必须使用特定参数调用特定函数 为此 我使用以下代码 for link in list of links link label Lab
  • zend框架自定义验证类

    我正在编写一个自定义验证器 它将检查电子邮件是否存在 如果数据库中已存在该电子邮件 则该表单无效 我很难找出自定义 Zend Validation 类的辅助路径和命名空间 我想调用类 My Validate EmailUnique 但我不断
  • java中的条形图

    我想更改每个条形的高度 例如红色部分为 10 蓝色部分为 20 但是当我增加高度值时 它会从底部增加图表 而我希望更改到顶部 你知道这有什么问题吗 import java awt Color import java awt Dimensio
  • 永远保留此构建选项 - Jenkins

    我知道有一个Keep this build forever詹金斯上的按钮 对此我有一个疑问 我有一个由一项主要工作和许多子工作 分为各个阶段 组成的配置 我想知道如果我点击主作业中的按钮 子作业中的文物是否也会永久存储 或者我应该进入每个子
  • 如何检索 YouTube 上直播活动的开始时间?

    我正在尝试返回并将已完成或正在进行的实时事件与现实世界的时间戳 例如 Twitter 的逐个播放 同步 我不拥有相关的实时事件 显然 这仅对可以倒带或重播的事件有用 例如许多与游戏相关的广播 有没有办法检索现场活动的开始时间 我尝试过以下方
  • 无法使用创建的新用户登录 sql server

    我创建了一个名为登录测试 SQL 身份验证 然后我创建了一个名为usertest通过此登录 用户创建成功 我将身份验证模式更改为混合模式 并重新启动了 SQLSERVERAGENT 和 MSSQLSERVER 服务 当我尝试使用创建的新用户
  • 我可以将 TypeScript 类型定义为 typeof 的所有可能结果值吗?

    我希望将类型定义为使用typeof某物上的操作员 本质上 我正在寻找一种更快的方法来做到这一点 而不需要任何类型的中间函数或变量 function getTypeOf value any return typeof value type T
  • 从 dcm4che2 迁移到 dcm4che3

    我使用了下面提到的来自此存储库的 dcm4che2 APIhttp www dcm4che org maven2 dcm4che http www dcm4che org maven2 dcm4che 在我的java项目中 dcm4che