【问题标题】:Error While retrieving DICOM image from PACS server从 PACS 服务器检索 DICOM 图像时出错
【发布时间】:2014-06-03 12:26:36
【问题描述】:

我正在尝试从 PACS 服务器检索 DICOM 图像,我使用 dcmqr.get 获取 DICOM 对象并将其转换为字节数组,当我将 DICOM 对象的字节数组传递给 getPixelDataAsBufferedImage 方法时,它会给出异常 java.lang.ArrayIndexOutOfBoundsException: 0 at line 'buff = reader.read(0, param);'.

我是 DICOM 的新手,不知道到底是什么问题。查询获取 DICOM 是否有问题或将字节数组转换为缓冲图像有任何问题?

public class TestDCM {

public static DcmQR dcmqr;

public static void main(String[] args) {

    dcmqr = new DcmQR("DCM4CHEE");
    dcmqr.setCalledAET("DCM4CHEE", true);
    dcmqr.setRemoteHost("IP address");
    dcmqr.setRemotePort(11112);

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

    dcmqr.setQueryLevel(DcmQR.QueryRetrieveLevel.IMAGE);

    dcmqr.addMatchingKey(Tag.toTagPath("SOPClassUID"),
            "1.2.840.10008.5.1.4.1.1.12.2");

    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) {
            dco.putString(Tag.TransferSyntaxUID, VR.UI,UID.ImplicitVRLittleEndian);
            // convert dicom object to byte array  
            imgTab = toByteArray(dco);
            // convert byte array to BufferedImage 
            bImage = getPixelDataAsBufferedImage(imgTab);
            File file = new File("filepath.jpg");
            writeBufferedImage(file, bImage);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        if (dcmqr != null) {
            dcmqr.stop();
            dcmqr.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("done");
}
}

// toByteArray method
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;
}

//getPixelDataAsBufferedImage method
public static BufferedImage getPixelDataAsBufferedImage(byte[] dicomData)
        throws IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(dicomData);
    BufferedImage buff = null;
    Iterator<ImageReader> iter = ImageIO
            .getImageReadersByFormatName("DICOM");
    ImageReader reader = (ImageReader) iter.next();
    DicomImageReadParam param = (DicomImageReadParam) reader
            .getDefaultReadParam();
    ImageInputStream iis = ImageIO.createImageInputStream(bais);
    reader.setInput(iis, false);
    buff = reader.read(0, param);
    iis.close();
    if (buff == null)
        throw new IOException(
                "Could not read Dicom file. Maybe pixel data is invalid.");
    return buff;
}

//writeBufferedImage method
public static void writeBufferedImage(File file , BufferedImage bufferedImage){
    try {
        ImageIO.write(bufferedImage, "jpg", file);
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("Jpeg image created successfully.");
}

【问题讨论】:

    标签: java dicom


    【解决方案1】:

    我已成功检索和转换 DICOM。我正在分享检索和转换的完整步骤。它也会帮助其他人。

    //Step 1: Retrieve DICOM
    
    // Transfer Syntax
    String[] DEF_TS = { 
        UID.JPEGLossless,
        UID.JPEGLosslessNonHierarchical14, UID.JPEGLSLossless,
        UID.JPEGLSLossyNearLossless, UID.JPEG2000LosslessOnly,
        UID.JPEG2000, UID.JPEGBaseline1, UID.JPEGExtended24, UID.MPEG2,
        UID.DeflatedExplicitVRLittleEndian, UID.ExplicitVRBigEndian,
        UID.ExplicitVRLittleEndian, UID.ImplicitVRLittleEndian 
    }; 
    
    DcmQR dcmqr = new DcmQR();
    
    /* Set remote PACS server parameter */
    dcmqr.setCalledAET("[Called AET]", false); //AET, host and port configured in PACS server
    dcmqr.setRemoteHost("[PACS server host]"); 
    dcmqr.setRemotePort("[Pacs server port]");
    
    /* Set local port to listen */
    dcmqr.setCalling("Receiving AET"); //Receiving AET, host and port should be configured in PACS server in association
    dcmqr.setLocalHost("Receiving host(Local server host)");
    dcmqr.setLocalPort("Receiving port(Local server post)");
    
    // Set user detail
    UserIdentity dcmuserId = new UserIdentity.UsernamePasscode(userId,
    pin.toCharArray());
    dcmuserId.setPositiveResponseRequested(true);
    dcmqr.setUserIdentity(dcmuserId);
    
    // Add Transfer syntax UID
    dcmqr.addStoreTransferCapability("1.2.840.10008.5.1.4.1.1.1", DEF_TS); // CR
    dcmqr.addStoreTransferCapability("1.2.840.10008.5.1.4.1.1.2", DEF_TS); // CT
    dcmqr.addStoreTransferCapability("1.2.840.10008.5.1.4.1.1.4", DEF_TS); // MR/MRI
    //.... Add all UID as required
    
    dcmqr.setEvalRetrieveAET(true);
    
    dcmqr.setCFind(true);
    
    dcmqr.setCGet(true);
    
    dcmqr.setMoveDest([Receving AE]);
    
    dcmqr.configureTransferCapability(true);
    
    // Set complete destination directory path, Where you want to store DICOMs
    dcmqr.setStoreDestination("[dicomFilePath]");
    
    dcmqr.setQueryLevel(DcmQR.QueryRetrieveLevel.STUDY);
    
    dcmqr.setQueryLevel(DcmQR.QueryRetrieveLevel.SERIES);
    
    dcmqr.setQueryLevel(DcmQR.QueryRetrieveLevel.IMAGE);
    
    dcmqr.addMatchingKey(Tag.toTagPath("StudyID"), [study id]); // other filters also can be add here
    
    dcmqr.addReturnKey(Tag.toTagPath("SeriesNumber"));
    
    dcmqr.start();
    dcmqr.open();
    List<DicomObject> result = dcmqr.query(); 
    dcmqr.move(result);
    // Here found dicoms with matching criteria will move from PACS server to your machine in provided destination path.
    
    
    //step 2: DICOM file to DICOM object
    DicomInputStream din = new DicomInputStream("dicom file path");
    DicomObject dicomObject = din.readDicomObject();
    
    
    //step 3: Convert DICOM to JPEG
    byte[] imgTab = toByteArray(dicomObject); // See in question
    /* create buffered image from byte array */
    BufferedImage bufferedImage = getPixelDataAsBufferedImage(imgTab); // See in question
    File outPutFile = new File("JPEG file path");
    /* creating jpeg image from buffered image */
    ImageIO.write(bufferedImage, "jpeg", outPutFile);
    

    您的 JPEG 已准备就绪。干杯

    【讨论】:

    • 我正在寻找类似的东西,但在 Python 中使用 pynetdicom3。
    【解决方案2】:

    虽然使用 C-GET 可以提取包括像素数据在内的完整 dicom 对象,但它充满了困难。使用 C-MOVE 要简单得多。 dcmqr 实用程序和其他堆栈溢出讨论的文档都涵盖了这一点。

    http://www.dcm4che.org/confluence/download/attachments/438/dcmqr+usage.txt?version=1&modificationDate=1351401060265

    DICOM C-GET vs C-MOVE

    【讨论】:

    • 嗨,布雷特,感谢您的回复。我如何在 java 中使用 C-MOVE?我在上面的链接中使用图像检索命令它为我工作。但是我如何在 java 中实现它?我试图实现这一点,我在发布的代码中添加了 2 行第一个是 dcmqr.setMoveDest("C:/dicom");在 dcmqr.get(result) 的地方;我用 dcmqr.move(result);但目标文件夹仍然是空的。
    • 我建议直接查看源代码作为参考:svn.code.sf.net/p/dcm4che/svn/dcm4che2/trunk/dcm4che-tool/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2020-06-14
    • 2015-11-17
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多