从 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 的相关文章

随机推荐

  • 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