从PACS服务器检索DICOM图像时出错

时间:2014-06-03 12:26:36

标签: java dicom

我正在尝试从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.");
}

2 个答案:

答案 0 :(得分: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已准备就绪。干杯

答案 1 :(得分:0)

虽然使用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