使用DCM4CHE3(JAVA)创建多帧dicom图像

时间:2016-11-08 09:14:19

标签: java dcm4che

我试图通过使用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"));

}

}

1 个答案:

答案 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);
  •