如何将元数据添加到图像(使用Java代码),然后将其转换为dicom

时间:2019-07-17 11:55:14

标签: java dicom dcm4che

我找到了一个Java代码,该文件将jpg和Dicom(需要一个元数据)转换为最终的Dicom文件。我想做的是将jpg图像转换成Dicom图像,并使用Java代码生成元数据。

BufferedImage jpg = ImageIO.read(new File("myjpg.jpg"));

// Convert the image to a byte array    
DataBuffer buff = jpg.getData().getDataBuffer();
DataBufferUShort buffer = new DataBufferUShort(buff.getSize());

for (int i = 0; i < buffer.getSize(); ++i)
    buffer.setElem(i, buff.getElem(i));

short[] data = buffer.getData();
ByteBuffer byteBuf = ByteBuffer.allocate(2 * data.length);
int i = 0;
while (data.length > i) {
    byteBuf.putShort(data[i]);
    i++;
}
// Copy a header
DicomInputStream dis = new DicomInputStream(new File("fileToCopyheaderFrom.dcm"));
Attributes meta = dis.readFileMetaInformation();
Attributes attribs = dis.readDataset(-1, Tag.PixelData);
dis.close();
// Change the rows and columns
attribs.setInt(Tag.Rows, VR.US, jpg.getHeight());
attribs.setInt(Tag.Columns, VR.US, jpg.getWidth());
System.out.println(byteBuf.array().length);
// Write the file
attribs.setBytes(Tag.PixelData, VR.OW, byteBuf.array());
DicomOutputStream dcmo = new DicomOutputStream(new File("myDicom.dcm"));
dcmo.writeFileMetaInformation(meta);
attribs.writeTo(dcmo);
dcmo.close();

3 个答案:

答案 0 :(得分:1)

我不是工具箱(当然也包括Java)方面的专家。

您的“ //复制标题”部分将读取源DICOM文件,并将所有属性保留在Attributes attribs变量中。

然后,您的“ //更改行和列”部分将根据需要修改少量属性。

然后,您的“ //写文件”部分只需将从源文件读取的属性添加到目标文件。

现在,您要绕过源DICOM文件,并自己添加属性将纯JPEG转换为DICOM。

将“ //复制标题”部分替换为build的实例Attributes

Attributes attribs = new Attributes();
attribs.setString(Tag.StudyDate, VR.DA, "20110404");
attribs.setString(Tag.StudyTime, VR.TM, "15");

以上示例中提及的标签仅作为示例。您必须自己决定要包括哪些标签。请注意,规范已根据要处理的SOP类为标签定义了类型1、1C,2、2C和3。
添加标签时,还必须注意正确的VR。规范也谈到那件事。
我在这里无法解释所有这些;太宽了。

答案 1 :(得分:1)

对于dcm4che我无能为力,但是如果您可以选择使用其他Java DICOM库,则使用DeCaMino(http://dicomplugin.com)可以轻松完成此任务:

  BufferedImage jpg = ImageIO.read(new File("myjpg.jpg"));
  DicomWriter dw = new DicomWriter();
  dw.setOutput(new File("myjpg.dcm"));
  DicomMetadata dmd = new DicomMetadata();
  dw.write(dmd, new IIOImage(jpg, null, null), null);

这将编写一个具有SOP类“辅助捕获”和默认元数据的DICOM兼容文件。

要自定义元数据,请在写入之前将数据元素添加到dmd,例如:

  DataSet ds = dmd.getDataSet();
  ds.set(Tag.StudyDate, LocalDate.of(2011, 4, 4));
  ds.set(Tag.StudyTime, LocalTime.of(15, 0, 0));

您还可以更改传输语法(从而控制像素数据编码):

  dw.setTransferSyntax(UID.JPEG2000TS);

免责声明:我是DeCaMino的作者。

编辑:正如kritzel_sw所说,我强烈建议您不要通过更改像素数据和某些数据元素来修改和现有的DICOM对象,您通常会以不合格的对象结尾。更好的方法是从头开始编写对象,最简单的对象来自辅助捕获类。 DeCaMino通过生成具有强制性数据元素的合格二级捕获对象来帮助您,但不会帮助您生成模态对象(如CT采集)。

答案 2 :(得分:0)

仅附带说明:

  

attribs.setBytes(Tag.PixelData,VR.OW,byteBuf.array());

VR.OW表示每个像素/通道16位。由于您将像素数据替换为从JPEG图像读取的像素数据,并且将缓冲区命名为“ byteBuf”,因此我怀疑这是不一致的。 VR.OB是每个像素/通道图像8位的值表示形式。

在谈论频道时,我了解到您想通过修改现有的DICOM图像而不是从头开始创建一个新的DICOM对象来简化DICOM对象的构造。但是,彩色像素数据不适用于所有类型的DICOM图像。例如。如果您的fileToCopyheaderFrom.dcm是放射线,CT或MRI图像(或许多其他放射线类型),则不允许向其中添加彩色像素数据。

此外,每个图像都包含标识信息(Study-,Series-,SOP实例UID是最重要的),这些信息应由新生成的值替换。

我知道用新的像素数据修改现有的DICOM对象似乎很吸引人,但是此过程可能比您预期的要复杂得多。在这两种情况下,学习基本的DICOM概念都是不可避免的。