Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Dcm4Che-从pacs获取图像_Java_Dicom - Fatal编程技术网

Java Dcm4Che-从pacs获取图像

Java Dcm4Che-从pacs获取图像,java,dicom,Java,Dicom,我有以下问题。我必须编写连接到pacs并获取图像的小应用程序。我决定使用dcm4che工具包。我编写了以下代码: 公共类Dcm4{ /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here DcmQR dcmqr = new MyDcmQR("server"); dcmqr.s

我有以下问题。我必须编写连接到pacs并获取图像的小应用程序。我决定使用dcm4che工具包。我编写了以下代码: 公共类Dcm4{

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    DcmQR dcmqr = new MyDcmQR("server");

    dcmqr.setCalledAET("server", true);
    dcmqr.setRemoteHost("213.165.94.158");
    dcmqr.setRemotePort(104);
    dcmqr.getKeys();

    dcmqr.setDateTimeMatching(true);
    dcmqr.setCFind(true);
    dcmqr.setCGet(true);

    dcmqr.setQueryLevel(MyDcmQR.QueryRetrieveLevel.IMAGE);

    dcmqr.addMatchingKey(Tag.toTagPath("PatientID"),"2011");
    dcmqr.addMatchingKey(Tag.toTagPath("StudyInstanceUID"),"1.2.276.0.7230010.3.1.2.669896852.2528.1325171276.917");
    dcmqr.addMatchingKey(Tag.toTagPath("SeriesInstanceUID"),"1.2.276.0.7230010.3.1.3.669896852.2528.1325171276.916");


    dcmqr.configureTransferCapability(true);
    List<DicomObject> result=null;
    byte[] imgTab=null;
    BufferedImage bImage=null;
    try {
        dcmqr.start();
        System.out.println("started");
        dcmqr.open();
        System.out.println("opened");
        result = dcmqr.query();
        System.out.println("queried");
        dcmqr.get(result);
        System.out.println("List Size = " + result.size());

        for(DicomObject dco:result){
            System.out.println(dco);
            dcmTools.toByteArray(dco);
            System.out.println("end parsing");
        }

    } catch (Exception e) {
        System.out.println("error "+e);
    }

    try{
        dcmqr.stop();
        dcmqr.close();
    }catch (Exception e) {

    }

    System.out.println("done");
}
}
ToByte阵列的源:

public static byte[] toByteArray(DicomObject obj) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BufferedOutputStream bos = new BufferedOutputStream(baos);
    DicomOutputStream dos = new DicomOutputStream(bos);
    dos.writeDicomFile(obj);
    dos.close();
    byte[] data = baos.toByteArray();
    return data;
}
调用toByteArray后,我得到了输出:

error java.lang.IllegalArgumentException: Missing (0002,0010) Transfer Syntax UID
一、 我在其他论坛上发现了一些信息,似乎DcmQR.get()方法不发送imgage数据。是否有可能强制DcmQR这样做。我已经写过这个问题存在于DcmQR.createStorageService()方法中,但我还没有找到解决方案。请帮助我

你好,克内勒

我做了一些您建议的更改:我添加了setMoveDest和setStoreDestination,Dicom对象存储在我添加的目标中-看起来很棒。然后我尝试基于Association.cget方法中使用的FutureDimseRSP编写响应处理程序:

public class MyDimseRSP extends DimseRSPHandler implements DimseRSP{

private MyEntry entry = new MyEntry(null, null);

private boolean finished;
private int autoCancel;
private IOException ex;

@Override
public synchronized void onDimseRSP(Association as, DicomObject cmd,
                                    DicomObject data) {
    super.onDimseRSP(as, cmd, data);
    MyEntry last = entry;
    while (last.next != null)
        last = last.next;

    last.next = new MyEntry(cmd, data);
    if (CommandUtils.isPending(cmd)) {
        if (autoCancel > 0 && --autoCancel == 0)
            try {
                super.cancel(as);
            } catch (IOException e) {
                ex = e;
            }
    } else {
        finished = true;
    }
    notifyAll();
}

@Override
public synchronized void onClosed(Association as) {
    if (!finished) {
//            ex = as.getException();
        ex = null;
        if (ex == null) {
            ex = new IOException("Association to " + as.getRemoteAET()
                    + " closed before receive of outstanding DIMSE RSP");
        }
        notifyAll();
    }
}

public final void setAutoCancel(int autoCancel) {
    this.autoCancel = autoCancel;
}

@Override
public void cancel(Association a) throws IOException {
    if (ex != null)
        throw ex;
    if (!finished)
        super.cancel(a);
}

public DicomObject getDataset() {
    return entry.command;
}

public DicomObject getCommand() {
    return entry.dataset;
}

public MyEntry getEntry() {
    return entry;
}

public synchronized boolean next() throws IOException, InterruptedException {
    if (entry.next == null) {
        if (finished)
            return false;

        while (entry.next == null && ex == null)
            wait();

        if (ex != null)
            throw ex;
    }
    entry = entry.next;
    return true;
}
}
以下是MyEntry代码:

public class MyEntry {

final DicomObject command;
final DicomObject dataset;
MyEntry next;

public MyEntry(DicomObject command, DicomObject dataset) {
    this.command = command;
    this.dataset = dataset;
}

public DicomObject getCommand() {
    return command;
}

public DicomObject getDataset() {
    return dataset;
}

public MyEntry getNext() {
    return next;
}

public void setNext(MyEntry next) {
    this.next = next;
}
}
然后,我重新键入了Dmcqr中的get方法,如下所示:

public void getObject(DicomObject obj, DimseRSPHandler rspHandler)throws IOException, InterruptedException{
    TransferCapability tc = selectTransferCapability(qrlevel.getGetClassUids());
    MyDimseRSP myRsp=new MyDimseRSP();
    if (tc == null)
        throw new NoPresentationContextException(UIDDictionary
                .getDictionary().prompt(qrlevel.getGetClassUids()[0])
                + " not supported by " + remoteAE.getAETitle());
    String cuid = tc.getSopClass();
    String tsuid = selectTransferSyntax(tc);
    DicomObject key = obj.subSet(MOVE_KEYS);
    assoc.cget(cuid, priority, key, tsuid, rspHandler);
    assoc.waitForDimseRSP();
}

在这个方法的第二个参数中,我使用了我的响应处理程序(MyDimseRSP)的一个实例。我运行我的代码,得到了我的响应处理程序的command和dataset的null值不为null,当然这不是我需要的Dicom对象。我做错了什么!!!!

您必须逐步完成代码(包括DCM4CHE工具包代码)。我怀疑您使用的是默认响应处理程序,它只计算已完成操作的数量,实际上并不存储get命令中的图像数据

显然,下面的for循环是在find操作的结果上循环,而不是get(需要在响应处理程序中处理)

我希望您必须重写响应处理程序才能正确写入DICOM文件。另请参阅DcmRcv类,以从您将收到的DICOM对象写入DICOM文件

:

从上面的编辑中,我假设您只是试图获取原始DICOM实例数据(而不是存储它的命令)。响应处理程序大致如下:

List<DicomObject> dataList = new ArrayList<DicomObject>();

@Override
public void onDimseRSP(Association as, DicomObject cmd, DicomObject data) {
    if( shouldAdd(as, cmd) ) {
        dataList.add( data )
    }
}
List dataList=new ArrayList();
@凌驾
public void onDimseRSP(关联为、双对象cmd、双对象数据){
如果(应添加(as,cmd)){
添加(数据)
}
}

注意大列表,但它会将数据存储在内存中。

谢谢您的回答-我是新的dcm4che,文档也很差-这就是为什么我想请您提供示例代码的原因。您能提供正确的解决方案吗…谢谢!!!在配置TransferCapability之前,请确保添加StoreTransferCapability和SetTo为您期望的对象重新指定目标。默认操作应至少为您将图像存储在文件系统中。此外,在抱怨文档太多之前,请仔细阅读代码。DCM4CHE2工具包中的功能非常丰富,其体系结构非常可靠。这比任何人为此付出的代价都值得重点是,我不想将图像存储在文件系统上,而是将它们保存在内存中以供进一步处理。你是对的-我应该尝试遵循源DCM4CHE2。我希望如果我有问题,你会帮助我…嗨,cneller,我已经添加了我的get()实现处理程序-你能检查一下并写下你的想法吗!!!请看下面答案中的编辑。另外,你的MyDimseRSP类的getDataset和getCommand混淆了。
for(DicomObject dco:result)
List<DicomObject> dataList = new ArrayList<DicomObject>();

@Override
public void onDimseRSP(Association as, DicomObject cmd, DicomObject data) {
    if( shouldAdd(as, cmd) ) {
        dataList.add( data )
    }
}