我正在尝试从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.");
}
答案 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实用程序和其他堆栈溢出讨论的文档都涵盖了这一点。