2016-11-08 500 views
1

我试图通过使用Imagewriter写入它们来创建多个JPEG文件的多帧dicom文件,但writer.canWriteSequence()始终给出false,因此无法写入jpeg文件复帧DICOM文件,有没有什么办法,我可以创建JPEG图像的多帧DICOM文件或BufferedImage的使用DCM4CHE3(JAVA)创建多帧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

尝试使用此代码

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_01Java Advanced Imaging Image,并尝试使用运行这段代码的Java 32位版本

  • 一)JAI的ImageIO库之前未安装;
  • b)安装了JAI ImageIO,但没有在PATH环境变量中设置值;
  • c)无法找到带有JAI本机代码的DLL文件(安装错误); d)你的Windows是64位的(它只适用于Win32);