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

Java 从PACS服务器检索DICOM映像时出错,java,dicom,Java,Dicom,我正在尝试从PACS服务器检索DICOM图像,我使用dcmqr.get获取DICOM对象并将其转换为字节数组,当我将DICOM对象的字节数组传递给getPixelDataasBuffereImage方法时,它给出了异常java.lang.ArrayIndexOutOfBoundsException:0,位于行'buff=reader.read(0,param);' 我是DICOM的新手,不知道到底是什么问题。在查询以获取DICOM或将字节数组转换为缓冲图像时是否存在任何问题 public cla

我正在尝试从PACS服务器检索DICOM图像,我使用
dcmqr.get
获取DICOM对象并将其转换为字节数组,当我将DICOM对象的字节数组传递给
getPixelDataasBuffereImage
方法时,它给出了异常
java.lang.ArrayIndexOutOfBoundsException:0,位于行'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.");
}
公共类TestDCM{
公共静态DcmQR-DcmQR;
公共静态void main(字符串[]args){
dcmqr=新的dcmqr(“DCM4CHEE”);
setcalledate(“DCM4CHEE”,true);
dcmqr.setRemoteHost(“IP地址”);
dcmqr.setRemotePort(11112);
dcmqr.setDateTimeMatching(true);
//dcmqr.setCFind(真);
dcmqr.setCGet(真);
dcmqr.configureTransferCapability(true);
setQueryLevel(dcmqr.queryretrievel.IMAGE);
dcmqr.addMatchingKey(Tag.toTagPath(“SOPClassUID”),
"1.2.840.10008.5.1.4.1.1.12.2");
列表结果=空;
字节[]imgTab=null;
BuffereImage双图像=null;
试试{
dcmqr.start();
System.out.println(“已启动”);
dcmqr.open();
系统输出打印项次(“打开”);
result=dcmqr.query();
系统输出打印项次(“查询”);
dcmqr.get(结果);
System.out.println(“List Size=“+result.Size());
对于(双对象dco:结果){
putString(Tag.TransferSyntaxUID、VR.UI、UID.ImplicitVRLittleEndian);
//将dicom对象转换为字节数组
imgTab=toByteArray(dco);
//将字节数组转换为BuffereImage
bImage=GetPixelDataasBuffereImage(imgTab);
File File=新文件(“filepath.jpg”);
writeBufferedImage(文件,双页面);
}
}捕获(例外e){
e、 printStackTrace();
}
试一试{
如果(dcmqr!=null){
dcmqr.stop();
dcmqr.close();
}
}捕获(例外e){
e、 printStackTrace();
}
系统输出打印项次(“完成”);
}
}
//toByteArray方法
公共静态字节[]toByteArray(DicomObject obj)引发IOException{
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
BufferedOutputStream bos=新的BufferedOutputStream(BAS);
DicomOutputStream dos=新的DicomOutputStream(bos);
dos.writeDicomFile(obj);
dos.close();
字节[]数据=baos.toByteArray();
返回数据;
}
//GetPixelDataAsBuffereImage方法
公共静态缓冲区图像GetPixelDataAsBuffereImage(字节[]dicomData)
抛出IOException{
ByteArrayInputStream bais=新的ByteArrayInputStream(dicomData);
buffereImage buff=null;
迭代器iter=ImageIO
.getImageReadersByFormatName(“DICOM”);
ImageReader=(ImageReader)iter.next();
DicomImageReadParam参数=(DicomImageReadParam)读取器
.getDefaultReadParam();
ImageInputStream iis=ImageIO.CreateMageInputStream(BAI);
reader.setInput(iis,false);
buff=读卡器读取(0,参数);
iis.close();
如果(buff==null)
抛出新IOException(
“无法读取Dicom文件。可能像素数据无效。”);
返回buff;
}
//writeBufferedImage方法
公共静态void writeBufferedImage(文件文件、缓冲区映像、缓冲区映像){
试一试{
write(bufferedImage,“jpg”,文件);
}捕获(IOE异常){
e、 printStackTrace();
}
System.out.println(“成功创建Jpeg图像”);
}

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


我已成功检索并转换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);
//步骤1:检索DICOM
//传输语法
字符串[]DEF_TS={
UID.jpeg无损,
UID.jpeglslessNonHierarchical14,UID.jpeglslessless,
UID.JPEGLSLossyNearLossless,UID.JPEG2000LosslessOnly,
UID.JPEG2000、UID.JPEGBaseline1、UID.JPEGExtended24、UID.MPEG2、,
UID.deflatedexplicitvrlittledian,UID.ExplicitVRBigEndian,
UID.ExplicitVRLittleEndian,UID.ImplicitVRLittleEndian
}; 
DcmQR DcmQR=新的DcmQR();
/*设置远程PACS服务器参数*/
dcmqr.setCalledate(“[Called AET]”,false)//在PACS服务器中配置的AET、主机和端口
dcmqr.setRemoteHost(“[PACS服务器主机]”);
dcmqr.setRemotePort(“[Pacs服务器端口]”);
/*将本地端口设置为侦听*/
dcmqr.setCalling(“接收AET”)//接收AET时,应在PACS服务器中关联配置主机和端口
setLocalHost(“接收主机(本地服务器主机)”;
setLocalPort(“接收端口(本地服务器post)”);
//设置用户详细信息
UserIdentity dcmuserId=新的UserIdentity.UsernamePasscode(userId,
pin.toCharArray());
dcmuserId.setPositiveResponseRequested(true);
setUserIdentity(dcmuserId);
//添加传输语法UID
dcmqr.addStoreTransferCapability(“1.2.840.10008.5.1.4.1.1.1”,定义);//铬
dcmqr.addStoreTransferCapability(“1.2.840.10008.5.1.4.1.1.2”,定义);//计算机断层扫描
dcmqr.addStoreTransferCapability(“1.2.840.10008.5.1.4.1.1.4”,定义);//磁共振成像
//.... 根据需要添加所有UID
dcmqr.setEvalRetrieveAET(真);
dcmqr.setCFind(真);
dcmqr.setCGet(真);
dcmqr.setMoveDest([接收AE]);
dcmqr.configureTransferCapability(true);
//设置要存储DICOM的完整目标目录路径
dcmqr.setStoreDestination(“[dicomFilePath]”);
dcmqr.setQueryLevel(dcmqr.queryretrievel.STUDY);
setQueryLevel(dcmqr.queryretrievel.SERIES);
setQueryLevel(dcmqr.queryretrievel.IMAGE);
dcmqr.addMatchingKey(Tag.toTagPath(“StudyID”),[study id]);//也可以在此处添加其他过滤器
dcmqr.addReturnKey(Tag.t