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

使用DCM4CHE3(JAVA)创建多帧dicom图像,java,dcm4che,Java,Dcm4che,我试图通过使用Imagewriter但writer写入多个JPEG文件来从多个JPEG文件创建多帧dicom文件。canWriteSequence()始终为false,因此无法将JPEG文件写入多帧dicom文件,因此是否有任何方法可以从JPEG图像或BuffereImage创建多帧dicom文件 public Attributes createDicomHeader(BufferedImage sampleFrame, int numberOfFrames) { // Ge

我试图通过使用Imagewriter但writer写入多个JPEG文件来从多个JPEG文件创建多帧dicom文件。canWriteSequence()始终为false,因此无法将JPEG文件写入多帧dicom文件,因此是否有任何方法可以从JPEG图像或BuffereImage创建多帧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"));

}
public Attributes createDicomHeader(buffereImage sampleFrame,int numberOfFrames){
//从示例图像中获取一些图像信息:
//所有帧都应该具有相同的信息,因此我们只能获得一次。
int colorComponents=sampleFrame.getColorModel().getNumColorComponents();
int bitsPerPixel=sampleFrame.getColorModel().getPixelSize();
int BitsLocated=(bitsPerPixel/colorComponents);
int samplesperpoixel=彩色组件;
//用于保存帧的DICOM对象
属性dicom=新属性();
//将患者相关信息添加到DICOM数据集
getString(Tag.PatientName,“Aditya^G”);
dicom.getString(Tag.PatientID,“1234ID”);
getDate(Tag.PatientBirthDate,new java.util.Date());
dicom.getString(Tag.PatientSex,“M”);
//将研究相关信息添加到DICOM数据集
dicom.getString(Tag.AccessionNumber,“1234AC”);
dicom.getString(Tag.StudyID,“1”);
getString(Tag.StudyDescription,“多帧研究”);
setDate(Tag.StudyDate,new java.util.Date());
setDate(Tag.StudyTime,new java.util.Date());
//将系列相关信息添加到DICOM数据集
dicom.setInt(标签序列号,VR.US,1);
setDate(Tag.SeriesDate,new java.util.Date());
setDate(Tag.serieTime,new java.util.Date());
getString(Tag.SeriesDescription,“多帧系列”);
dicom.getString(Tag.modity,“SC”);//二次捕获
//将图像相关信息添加到DICOM数据集
dicom.setInt(标记InstanceNumber,VR.US,1);
dicom.setInt(Tag.samplesperpoixel,VR.US,samplesperpoixel);
dicom.setString(标签:光度测量解释,VR.CS,“YBR_FULL_422”);
setInt(Tag.Rows、VR.US、sampleFrame.getHeight());
setInt(Tag.Columns、VR.US、sampleFrame.getWidth());
dicom.setInt(Tag.BitsAllocated,VR.US,BitsAllocated);
dicom.setInt(标记位存储、VR.US、位定位);
dicom.setInt(Tag.HighBit、VR.US、BitsLocated-1);
dicom.setInt(Tag.PixelRepresentation,VR.US,0);
//添加唯一标识符
设置字符串(Tag.SOPClassUID、VR.UI、UID.SecondaryCaptureImageStorage);
设置字符串(Tag.StudyInstanceUID、VR.UI、UIDUtils.createUID());
设置字符串(Tag.serieinstanceuid、VR.UI、UIDUtils.createUID());
setString(Tag.SOPInstanceUID、VR.UI、UIDUtils.createUID());
//多帧信息的开始:
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);//帧数
dicom.setInt(标签建议显示帧率,VR.US,3);
setInt(Tag.FrameIncrementPointer,VR.US,Tag.FrameTime);
//多帧信息结束。
//添加默认字符集
dicom.setString(Tag.SpecificCharacterSet,VR.CS,“ISO_IR 100”);
//使用JPEG无损传输语法初始化元信息
创建文件元信息(UID.JPEGBaseline1);
返回dicom;
}
公共多帧(文件[]帧,文件dest)
抛出IOException{
//状态消息
System.out.println(“创建多帧文件…”);
//创建DICOM image writer实例并设置其输出
ImageReadParam dicomr=新的DicomImageReadParam();
ImageWriter writer=ImageWriterFactory.getImageWriter(ImageWriterFactory.getImageWriterParam(UID.JPEGBaseline1));
FileImageOutputStream输出=新FileImageOutputStream(dest);
writer.setOutput(输出);
//从图像数组中获取图像样本
BuffereImage样本=ImageIO.read(帧[0]);
//为我们的DICOM图像编写器创建一个新的数据集(标题/元数据)
属性ds=this.createDicomHeader(示例,frames.length);
属性fmi=ds.createFileMetaInformation(UID.JPEGBaseline1);
//将元数据设置为我们的DICOM图像编写器,并准备对多帧序列进行编码
//ImageWriteParam iwp=writer.getDefaultWriteParam();
DicomMetaData writeMeta=新的DicomMetaData(fmi,ds);
writeMeta.getAttributes().addAll(ds);
if(writer.canWriteSequence())
编写者。编写顺序(writeMeta);
其他的
System.out.println(“无法写入序列”);
//DICOMMMetadata writeMetadata=(DICOMMMetadata)writer.getDefaultStreamMetadata(null);
//writeMeta.getAttributes().addAll(ds);
//编写者。编写顺序(writeMeta);
//状态消息
System.out.println(“开始写入序列…”);
//对于每个提取的JPEG图像。。。
对于(int i=0;iimport 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();
        }
    }
}