我试图通过使用Imagewriter编写来自多个JPEG文件的多帧dicom文件,但是writer.canWriteSequence()总是给出错误,因此无法将jpeg文件写入多帧dicom文件,所以我有什么方法可以从jpeg image或bufferedimage
创建多帧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"));
}
}
答案 0 :(得分:0)
尝试使用此代码
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import org.dcm4che2.data.BasicDicomObject;
import org.dcm4che2.data.DicomObject;
import org.dcm4che2.data.Tag;
import org.dcm4che2.data.UID;
import org.dcm4che2.data.VR;
import org.dcm4che2.imageio.plugins.dcm.DicomStreamMetaData;
import org.dcm4che2.imageioimpl.plugins.dcm.DicomImageWriterSpi;
import org.dcm4che2.util.UIDUtils;
public class Mpeg2Dicom {
public Mpeg2Dicom() {
}
public DicomObject createDicomHeader(BufferedImage sampleFrame, int numberOfFrames) {
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
DicomObject dicom = new BasicDicomObject();
// Add patient related information to the DICOM dataset
dicom.putString(Tag.PatientName, null, "Patient Name");
dicom.putString(Tag.PatientID, null, "1234ID");
dicom.putDate(Tag.PatientBirthDate, null, new java.util.Date());
dicom.putString(Tag.PatientSex, null, "M");
// Add study related information to the DICOM dataset
dicom.putString(Tag.AccessionNumber, null, "1234AC");
dicom.putString(Tag.StudyID, null, "1");
dicom.putString(Tag.StudyDescription, null, "MULTIFRAME STUDY");
dicom.putDate(Tag.StudyDate, null, new java.util.Date());
dicom.putDate(Tag.StudyTime, null, new java.util.Date());
// Add series related information to the DICOM dataset
dicom.putInt(Tag.SeriesNumber, null, 1);
dicom.putDate(Tag.SeriesDate, null, new java.util.Date());
dicom.putDate(Tag.SeriesTime, null, new java.util.Date());
dicom.putString(Tag.SeriesDescription, null, "MULTIFRAME SERIES");
dicom.putString(Tag.Modality, null, "SC"); // secondary capture
// Add image related information to the DICOM dataset
dicom.putInt(Tag.InstanceNumber, null, 1);
dicom.putInt(Tag.SamplesPerPixel, null, samplesPerPixel);
dicom.putString(Tag.PhotometricInterpretation, VR.CS, "YBR_FULL_422");
dicom.putInt(Tag.Rows, null, sampleFrame.getHeight());
dicom.putInt(Tag.Columns, null, sampleFrame.getWidth());
dicom.putInt(Tag.BitsAllocated, null, bitsAllocated);
dicom.putInt(Tag.BitsStored, null, bitsAllocated);
dicom.putInt(Tag.HighBit, null, bitsAllocated-1);
dicom.putInt(Tag.PixelRepresentation, null, 0);
// Add the unique identifiers
dicom.putString(Tag.SOPClassUID, null, UID.SecondaryCaptureImageStorage);
dicom.putString(Tag.StudyInstanceUID, null, UIDUtils.createUID());
dicom.putString(Tag.SeriesInstanceUID, null, UIDUtils.createUID());
dicom.putString(Tag.SOPInstanceUID, VR.UI, UIDUtils.createUID());
//Start of multiframe information:
dicom.putInt(Tag.StartTrim, null, 1); // Start at frame 1
dicom.putInt(Tag.StopTrim, null, numberOfFrames); // Stop at frame N
dicom.putString(Tag.FrameTime, null, "33.33"); // Milliseconds (30 frames per second)
dicom.putString(Tag.FrameDelay, null, "0.0"); // No frame dalay
dicom.putInt(Tag.NumberOfFrames, null, numberOfFrames); // The number of frames
dicom.putInt(Tag.RecommendedDisplayFrameRate, null, 3);
dicom.putInt(Tag.FrameIncrementPointer, null, Tag.FrameTime);
//End of multiframe information.
// Add the default character set
dicom.putString(Tag.SpecificCharacterSet, VR.CS, "ISO_IR 100");
// Init the meta information with JPEG Lossless transfer syntax
// dicom.initFileMetaInformation(UID.JPEGLossless);
dicom.initFileMetaInformation(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
ImageWriter writer = new DicomImageWriterSpi().createWriterInstance();
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
DicomObject ds = this.createDicomHeader(sample, frames.length);
// Set the metadata to our DICOM image writer and prepare to encode the multiframe sequence
DicomStreamMetaData writeMeta = (DicomStreamMetaData) writer.getDefaultStreamMetadata(null);
writeMeta.setDicomObject(ds);
writer.prepareWriteSequence(writeMeta);
System.out.println("Start of Write Sequence...");
for (int i = 0; i < frames.length; i++) {
// Status message
System.out.println("Encoding frame # "+ (i+1));
// Read the PNG 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.");
}
public static void main(String[] args) {
try {
// Create an instance of our class
Mpeg2Dicom f = new Mpeg2Dicom();
// Create the array of files for the extracted FFMPEG images
File[] frames = new File("d://AAA").listFiles();
// Create the DICOM multiframe file
f.encodeMultiframe(frames, new File("d:///multiframe.dcm"));
} catch (Exception e) {
// Print exceptions
e.printStackTrace();
}
}
}
在运行此代码之前,请安装 Java高级映像I / O工具32位版本1.0_01 Java Advanced Imaging Image,并尝试使用 Java 32位版本<运行此代码/ strong>
- a)未安装JAI ImageIO库;
- b)已安装JAI ImageIO,但在PATH环境变量中没有设置值;
- c)找不到具有JAI本机代码的DLL文件(安装错误);
- d)你的Windows是64位(它只适用于Win32);