Java 使用dcm4che3将rgb jpg图像转换为dicom

Java 使用dcm4che3将rgb jpg图像转换为dicom,java,jpeg,dicom,dcm4che,Java,Jpeg,Dicom,Dcm4che,我使用了medPhys pl.提出的解决方案 我尝试将文件jpg转换为文件dicom。当jpg是单色时,我的代码是成功的,但是如果文件jpg是RGB,则文件dicom相对于原始图像的颜色发生了变化 有人知道原因吗 谢谢 File fileJpg = new File(path + "tmp_" + numImagen + ".jpg"); File fileDicomFinal = new File(path + "tmp_" + numImagen + ".dcm");

我使用了medPhys pl.提出的解决方案


我尝试将文件jpg转换为文件dicom。当jpg是单色时,我的代码是成功的,但是如果文件jpg是RGB,则文件dicom相对于原始图像的颜色发生了变化

有人知道原因吗

谢谢

    File fileJpg = new File(path + "tmp_" + numImagen + ".jpg");
    File fileDicomFinal = new File(path + "tmp_" + numImagen + ".dcm");
    File fileDicomOrig = new File(cabeceraOriginal);
    File fileDicomTipo = new File(cabeceraTipo);

    BufferedImage jpg = ImageIO.read(fileJpg);

    //Convert the image to a byte array
    DataBufferByte buff = (DataBufferByte) jpg.getData().getDataBuffer();
    byte[] buffbytes = buff.getData(0);
    byte[] b = new byte[5*buff.getData(0).length];
    for (int j = 0; j < 5; j++) {
        System.arraycopy(buffbytes, 0, b, j*buffbytes.length, buffbytes.length);
    }

    //Copy a header 
    DicomInputStream dis = new DicomInputStream(fileDicomTipo);
    Attributes meta = dis.readFileMetaInformation();
    Attributes attribs = dis.readDataset(-1, Tag.PixelData);
    dis.close();
    DicomInputStream disOrig = new DicomInputStream(fileDicomOrig);
    Attributes attribsOrig = disOrig.readDataset(-1, Tag.PixelData);
    disOrig.close();

    //get properties of image
    int colorComponents = jpg.getColorModel().getNumColorComponents();
    int bitsPerPixel = jpg.getColorModel().getPixelSize();
    int bitsAllocated = (bitsPerPixel / colorComponents); 
    int samplesPerPixel = colorComponents; 

    //Change the rows and columns
    attribs.setString(Tag.SpecificCharacterSet, VR.CS, "ISO_IR 100");  
    attribs.setString(Tag.PhotometricInterpretation, VR.CS, samplesPerPixel == 3 ? "RGB" : "MONOCHROME2"); 

    attribs.setInt(Tag.SamplesPerPixel, VR.US, samplesPerPixel);           
    attribs.setInt(Tag.Rows, VR.US, jpg.getHeight());  
    attribs.setInt(Tag.Columns, VR.US, jpg.getWidth());  
    attribs.setInt(Tag.BitsAllocated, VR.US, bitsAllocated);  
    attribs.setInt(Tag.BitsStored, VR.US, bitsAllocated);  
    attribs.setInt(Tag.HighBit, VR.US, bitsAllocated-1);  
    attribs.setInt(Tag.PixelRepresentation, VR.US, 0); 

    /*Also, our Dicom header needs information about date and time of creation:*/
    attribs.setDate(Tag.InstanceCreationDate, VR.DA, new Date());  
    attribs.setDate(Tag.InstanceCreationTime, VR.TM, new Date());  
    /* Every Dicom file has a unique identifier. 
    * Here we’re generating study, series and Sop instances UIDs. 
    * You may want to modify these values, but you should to care about their uniqueness. 
    */
    attribs.setString(Tag.SeriesInstanceUID, VR.UI, UIDUtils.createUID();  
    attribs.setString(Tag.SOPInstanceUID, VR.UI, UIDUtils.createUID());  
    attribs.setString(Tag.StudyInstanceUID, VR.UI, UIDUtils.createUID());
    attribs.setString(Tag.AccessionNumber, VR.IS, attribsOrig.getString(Tag.AccessionNumber));
    attribs.setString(Tag.PatientName, VR.CS, attribsOrig.getString(Tag.PatientName));
    attribs.setString(Tag.InstitutionName, VR.CS, attribsOrig.getString(Tag.InstitutionName));
    attribs.setString(Tag.PatientID, VR.CS, attribsOrig.getString(Tag.PatientID));
    attribs.setString(Tag.PatientBirthDate, VR.DT, attribsOrig.getString(Tag.PatientBirthDate));
    attribs.setString(Tag.PatientSex, VR.CS, attribsOrig.getString(Tag.PatientSex));
    attribs.setString(Tag.OtherPatientIDs, VR.CS, attribsOrig.getString(Tag.OtherPatientIDs));
    attribs.setString(Tag.PatientAge, VR.AS, attribsOrig.getString(Tag.PatientAge));
    attribs.setString(Tag.AcquisitionDateTime, VR.DT, attribsOrig.getString(Tag.AcquisitionDateTime));
    attribs.setString(Tag.AcquisitionDate, VR.DT, attribsOrig.getString(Tag.AcquisitionDate));       
    attribs.setString(Tag.AcquisitionTime, VR.DT, attribsOrig.getString(Tag.AcquisitionTime));
    attribs.setString(Tag.StudyInstanceUID , VR.UI, attribsOrig.getString(Tag.StudyInstanceUID));

    //Write the file                
    attribs.setBytes(Tag.PixelData, VR.OW, b);
    DicomOutputStream dcmo = new DicomOutputStream(fileDicomFinal);
    dcmo.writeFileMetaInformation(meta);
    attribs.writeTo(dcmo);
    dcmo.close();
File fileJpg=新文件(路径+“tmp_”+numImagen+”.jpg);
File fileDicomFinal=新文件(路径+“tmp_”+numImagen+“.dcm”);
文件fileDicomOrig=新文件(cabeceraOriginal);
File fileDicomTipo=新文件(cabeceraTipo);
BuffereImage jpg=ImageIO.read(fileJpg);
//将图像转换为字节数组
DataBufferByte buff=(DataBufferByte)jpg.getData().getDataBuffer();
byte[]buffbytes=buff.getData(0);
byte[]b=新字节[5*buff.getData(0.length];
对于(int j=0;j<5;j++){
System.arraycopy(buffbytes,0,b,j*buffbytes.length,buffbytes.length);
}
//复制标题
DicomInputStream dis=新的DicomInputStream(fileDicomTipo);
Attributes meta=dis.readFileMetaInformation();
属性attribs=dis.readDataset(-1,Tag.PixelData);
dis.close();
DicomInputStream disOrig=新的DicomInputStream(fileDicomOrig);
属性attribsOrig=disOrig.readDataset(-1,Tag.PixelData);
disOrig.close();
//获取图像的属性
int colorComponents=jpg.getColorModel().getNumColorComponents();
int bitsPerPixel=jpg.getColorModel().getPixelSize();
int BitsLocated=(bitsPerPixel/colorComponents);
int samplesperpoixel=彩色组件;
//更改行和列
属性设置字符串(Tag.SpecificCharacterSet,VR.CS,“ISO_IR 100”);
属性设置字符串(Tag.PhotometricInterpretation,VR.CS,samplesPerPixel==3?“RGB”:“单色2”);
attribs.setInt(Tag.samplesperpoixel、VR.US、samplesperpoixel);
attribs.setInt(Tag.Rows、VR.US、jpg.getHeight());
attribs.setInt(Tag.Columns、VR.US、jpg.getWidth());
attribs.setInt(Tag.BitsAllocated,VR.US,BitsAllocated);
attribs.setInt(Tag.BitsStored、VR.US、bitsAllocated);
attribs.setInt(Tag.HighBit、VR.US、bitsAllocated-1);
attribs.setInt(Tag.pixelsrepresentation,VR.US,0);
/*此外,我们的Dicom标头需要有关创建日期和时间的信息:*/
attribs.setDate(Tag.InstanceCreationDate,VR.DA,new Date());
attribs.setDate(Tag.InstanceCreationTime,VR.TM,new Date());
/*每个Dicom文件都有一个唯一的标识符。
*在这里,我们将生成研究、系列和Sop实例UID。
*您可能希望修改这些值,但应该注意它们的唯一性。
*/
attribs.setString(Tag.serieInstanceUID、VR.UI、UIDUtils.createUID();
attribs.setString(Tag.SOPInstanceUID、VR.UI、UIDUtils.createUID());
attribs.setString(Tag.StudyInstanceUID、VR.UI、UIDUtils.createUID());
attribs.setString(Tag.AccessionNumber,VR.IS,attribsOrig.getString(Tag.AccessionNumber));
attribs.setString(Tag.PatientName、VR.CS、attribsOrig.getString(Tag.PatientName));
attribs.setString(Tag.InstitutionName、VR.CS、attribsOrig.getString(Tag.InstitutionName));
attribs.setString(Tag.PatientID、VR.CS、attribsOrig.getString(Tag.PatientID));
attribs.setString(Tag.PatientBirthDate、VR.DT、attribsOrig.getString(Tag.PatientBirthDate));
attribs.setString(Tag.PatientSex、VR.CS、attribsOrig.getString(Tag.PatientSex));
attribs.setString(Tag.OtherPatientIDs、VR.CS、attribsOrig.getString(Tag.OtherPatientIDs));
attribs.setString(Tag.PatientAge、VR.AS、attribsOrig.getString(Tag.PatientAge));
attribs.setString(Tag.AcquisitionDateTime,VR.DT,attribsOrig.getString(Tag.AcquisitionDateTime));
attribs.setString(Tag.AcquisitionDate,VR.DT,attribsOrig.getString(Tag.AcquisitionDate));
attribs.setString(Tag.AcquisitionTime,VR.DT,attribsOrig.getString(Tag.AcquisitionTime));
attribs.setString(Tag.StudyInstanceUID、VR.UI、attribsOrig.getString(Tag.StudyInstanceUID));
//写文件
属性设置(标记像素数据,VR.OW,b);
DicomOutputStream dcmo=新的DicomOutputStream(fileDicomFinal);
dcmo.writeFileMetaInformation(元);
属性写入(dcmo);
dcmo.close();

彩色jpeg有损文件不能是RGB。当您找到一个时,它通常有一个YBRFULL颜色空间(即使颜色空间标记错误地指定了RGB)你应该采取相应的行动。

你尝试过什么?你已经仔细检查了你的代码,并试图看看事情发生了什么变化?我尝试将文件jpg转换为文件dicom。当jpg是单色时,我的代码是成功的,但是如果文件jpg是RGB,则文件dicom相对于原始图像的颜色发生了变化。你的jpg来自哪里?你有吗安装了jai imageio编解码器,或者您正在使用jre的jpeg编解码器?ire中的jpeg图像编写器有一个缺陷,即某些类型的元数据可能会损坏颜色:我不理解您的第一个问题。“您的jpeg来自哪里?”我已经安装了:jai-1_1_3-lib-windows-i586.exe jai-1_1_3-lib-windows-i586-jdk.exe和jai-1_1_3-lib-windows-i586-jre.exe也许我读取图像的方式不正确?我没有旋转图像,我上传了一个示例:jpg original和dicom的捕获,当我更改此行时:attribs.setString(Tag.PhotometricInterpretation,VR.CS,samplesperpoixel==3?“RGB”:“monocary2”);for:attribs.setString(Tag.PhotometricInterpretation,VR.CS,samplesperpoixel==3?“YBR_FULL_422”:“monocary2”);结果是一个文件dicom,图像被粉红色层覆盖:(