-1

I found a java code that converts a jpg and a Dicom(it takes the metadata fri¡om that one) files to a final Dicom one. What I want to do is convert the jpg image into a Dicom one, generating the metadata with java code.

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();
Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
celia
  • 67
  • 9

3 Answers3

1

I am not expert in toolkit (and of-course Java as well).

Your "// Copy a header" section reads the source DICOM file and holds all the attributes in Attributes attribs variable.

Then, your "// Change the rows and columns" section modifies few attributes as per need.

Then, your "// Write the file" section simply add the attributes read from source file to destination file.

Now, you want to bypass the source DICOM file and convert plain JPEG to DICOM with adding attributes yourself.

Replace your "// Copy a header" section to build the instance of Attributes.

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

The tags mentioned in above example are for example only. You have to decide yourself which tags you want to include. Note that specifications have defined Types 1, 1C, 2, 2C and 3 for tags depending on the SOP class you are dealing with.
While adding the tags, you have to take care of correct VR as well. Specifications talk about that thing as well.
I cannot explain all this here; too broad.

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
1

I cannot help about dcm4che, but if using another Java DICOM library is an option for you, this task is quite simple using 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);

This will write a DICOM conform file with SOP class "secondary capture" and default metadata.

To customize the metadata, add data elements to dmd before writing, e.g. :

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

You can also change the transfer syntax (thus controlling the pixel data encoding) :

  dw.setTransferSyntax(UID.JPEG2000TS);

Disclaimer: I'm the author of DeCaMino.

EDIT: As kritzel_sw says, I'll strongly advice against modifying and existing DICOM object by changing pixel data and some data element, you'll mostly end with a non-conform object. Better is to write an object from scratch, and the simplest objects are from the secondary capture class. DeCaMino helps you by generating a conform secondary capture object with mandatory data elements, but it won't help you to generate a modality (like a CT acquisition) object.

  • Sorry for downvoting your answer, but it does not really answer the question (just recommends a different toolkit), plus it is missing any hint that just replacing pixel data is by far not sufficient to create a new DICOM image out of pixel data. If an image constructed the way that you are suggesting it would be sent to a PACS, this could have very harmful impact on data integrity and in the worst case on patient's health. DICOM is about medical imaging, and we should not forget about the "medical" part. – Markus Sabin Jul 19 '19 at 11:10
  • The question, as far as I understood it, was "how to convert a jpg image into a Dicom one, generating the metadata with java code." I believe my post does bring an answer. Concerning data integrity, you're right, but DeCaMino defaut SOP class is Secondary Capture, which means some non-original data and any DICOM software will recognize it as such. Up to the developer to add the necessary metadata to make the file useful for what it is meant for, like Patient name,etc... – Hervé Guillemet Jul 19 '19 at 14:09
  • You are right, I agree. I reverted my downvote. Thanks for adding the "EDIT". – Markus Sabin Jul 22 '19 at 05:55
0

Just a side note:

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

VR.OW means 16 bits per pixel/channel. Since you are replacing the pixel data with pixel data read from a JPEG image, and you named the buffer "byteBuf", I suspect that this is inconsistent. VR.OB is the value representation for 8 bits per pixel/channel image.

Talking about channels, I understand that you want to make construction of a DICOM object easy by modifying an existing DICOM image rather than creating a new one from scratch. However, color pixel data is not appropriate for all types of DICOM images. E.g. if your fileToCopyheaderFrom.dcm is a Radiography, CT or MRI image (or many other radiology types), it is not allowed to add color pixel data to it.

Furthermore, each image contains identifying information (Study-, Series-, SOP Instance UID are the most important ones) which should be replaced by newly generated values.

I understand that it appears appealing to modify an existing DICOM object with new pixel data, but this process is probably much more complicated than you would expect it to be. In both cases, it is inevitable to learn basic DICOM concepts.

Markus Sabin
  • 3,916
  • 14
  • 32