我正在尝试通过使用 Imagewriter 写入多个 JPEG 文件来创建多帧 dicom 文件,但 writer.canWriteSequence() 总是给出错误,因此无法将 jpeg 文件写入多帧 dicom 文件所以有什么方法可以创建多帧来自 jpeg 图像或缓冲图像的 dicom 文件
public Attributes createDicomHeader(BufferedImage sampleFrame, int numberOfFrames) {
// Get some image information from the sample image:
// All frames should have the same information so we will get it only once.
int colorComponents = sampleFrame.getColorModel().getNumColorComponents();
int bitsPerPixel = sampleFrame.getColorModel().getPixelSize();
int bitsAllocated = (bitsPerPixel / colorComponents);
int samplesPerPixel = colorComponents;
// The DICOM object that will hold our frames
Attributes dicom = new Attributes();
// Add patient related information to the DICOM dataset
dicom.getString(Tag.PatientName, "Aditya^G");
dicom.getString(Tag.PatientID, "1234ID");
dicom.getDate(Tag.PatientBirthDate, new java.util.Date());
dicom.getString(Tag.PatientSex, "M");
// Add study related information to the DICOM dataset
dicom.getString(Tag.AccessionNumber, "1234AC");
dicom.getString(Tag.StudyID, "1");
dicom.getString(Tag.StudyDescription, "MULTIFRAME STUDY");
dicom.setDate(Tag.StudyDate, new java.util.Date());
dicom.setDate(Tag.StudyTime, new java.util.Date());
// Add series related information to the DICOM dataset
dicom.setInt(Tag.SeriesNumber,VR.US, 1);
dicom.setDate(Tag.SeriesDate, new java.util.Date());
dicom.setDate(Tag.SeriesTime, new java.util.Date());
dicom.getString(Tag.SeriesDescription, "MULTIFRAME SERIES");
dicom.getString(Tag.Modality, "SC"); // secondary capture
// Add image related information to the DICOM dataset
dicom.setInt(Tag.InstanceNumber, VR.US, 1);
dicom.setInt(Tag.SamplesPerPixel, VR.US, samplesPerPixel);
dicom.setString(Tag.PhotometricInterpretation, VR.CS, "YBR_FULL_422");
dicom.setInt(Tag.Rows, VR.US, sampleFrame.getHeight());
dicom.setInt(Tag.Columns, VR.US, sampleFrame.getWidth());
dicom.setInt(Tag.BitsAllocated, VR.US, bitsAllocated);
dicom.setInt(Tag.BitsStored, VR.US, bitsAllocated);
dicom.setInt(Tag.HighBit, VR.US, bitsAllocated-1);
dicom.setInt(Tag.PixelRepresentation, VR.US, 0);
// Add the unique identifiers
dicom.setString(Tag.SOPClassUID, VR.UI, UID.SecondaryCaptureImageStorage);
dicom.setString(Tag.StudyInstanceUID, VR.UI, UIDUtils.createUID());
dicom.setString(Tag.SeriesInstanceUID, VR.UI, UIDUtils.createUID());
dicom.setString(Tag.SOPInstanceUID, VR.UI, UIDUtils.createUID());
//Start of multiframe information:
dicom.setInt(Tag.StartTrim, VR.US, 1);
dicom.setInt(Tag.StopTrim, VR.US, numberOfFrames);
dicom.getString(Tag.FrameTime, 0, "33.33");
dicom.getString(Tag.FrameDelay, "0.0");
dicom.setInt(Tag.NumberOfFrames, VR.US, numberOfFrames); // The number of frames
dicom.setInt(Tag.RecommendedDisplayFrameRate, VR.US, 3);
dicom.setInt(Tag.FrameIncrementPointer, VR.US, Tag.FrameTime);
//End of multiframe information.
// Add the default character set
dicom.setString(Tag.SpecificCharacterSet, VR.CS, "ISO_IR 100");
// Init the meta information with JPEG Lossless transfer syntax
dicom.createFileMetaInformation(UID.JPEGBaseline1);
return dicom;
}
public void encodeMultiframe(File[] frames, File dest)
throws IOException {
// Status message
System.out.println("Creating Multiframe File...");
// Create DICOM image writer instance and set its output
ImageReadParam dicomr=new DicomImageReadParam();
ImageWriter writer = ImageWriterFactory.getImageWriter(ImageWriterFactory.getImageWriterParam(UID.JPEGBaseline1));
FileImageOutputStream output = new FileImageOutputStream(dest);
writer.setOutput(output);
// Get an image sample from the array of images
BufferedImage sample = ImageIO.read(frames[0]);
// Create a new dataset (header/metadata) for our DICOM image writer
Attributes ds = this.createDicomHeader(sample, frames.length);
Attributes fmi = ds.createFileMetaInformation(UID.JPEGBaseline1);
// Set the metadata to our DICOM image writer and prepare to encode the multiframe sequence
// ImageWriteParam iwp= writer.getDefaultWriteParam() ;
DicomMetaData writeMeta = new DicomMetaData(fmi, ds);
writeMeta.getAttributes().addAll(ds);
if(writer.canWriteSequence())
writer.prepareWriteSequence(writeMeta);
else
System.out.println("can not write to sequence");
// DicomMetaData writeMeta = (DicomMetaData) writer.getDefaultStreamMetadata(null);
// writeMeta.getAttributes().addAll(ds);
// writer.prepareWriteSequence(writeMeta);
// Status message
System.out.println("Start of Write Sequence...");
// For each extracted JPEG images...
for (int i = 0; i < frames.length; i++) {
// Status message
System.out.println("Encoding frame # "+ (i+1));
// Read the JPEG file to a BufferedImage object
BufferedImage frame = ImageIO.read(frames[i]);
// Create a new IIOImage to be saved to the DICOM multiframe sequence
IIOImage iioimage = new IIOImage(frame, null, null);
// Write our image to the DICOM multiframe sequence
writer.writeToSequence(iioimage, null);
}
// Status message
System.out.println("End of Write Sequence.");
// Our multiframe file was created. End the sequence and close the output stream.
writer.endWriteSequence();
output.close();
// Status message
System.out.println("Multiframe File Created.");
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
MultiframeImageCreation mf=new MultiframeImageCreation();
File[] frames = new File("/root/Desktop/multi").listFiles();
// Create the DICOM multiframe file
mf.encodeMultiframe(frames, new File("/root/Desktop/multiframe.dcm"));
}
}