Я нашел код 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();
Я не эксперт в наборе инструментов (и, конечно, в Java).
Ваш раздел «// Копировать заголовок» читает исходный файл DICOM и содержит все атрибуты в переменной Attributes attribs
.
Затем ваш раздел «// Изменить строки и столбцы» изменяет несколько атрибутов по мере необходимости.
Затем ваш раздел «// Запись файла» просто добавляет атрибуты, считанные из исходного файла, в целевой файл.
Теперь вы хотите обойти исходный файл DICOM и самостоятельно преобразовать обычный JPEG в DICOM с добавлением атрибутов.
Замените раздел «// Скопируйте заголовок» на строить экземпляром Attributes
.
Attributes attribs = new Attributes();
attribs.setString(Tag.StudyDate, VR.DA, "20110404");
attribs.setString(Tag.StudyTime, VR.TM, "15");
Теги, упомянутые в приведенном выше примере, приведены только для примера. Вы должны решить сами, какие теги вы хотите включить. Обратите внимание, что в спецификациях определены типы 1, 1C, 2, 2C и 3 для тегов в зависимости от класса SOP, с которым вы имеете дело.
При добавлении тегов вы также должны позаботиться о правильном VR. Спецификации также говорят об этом.
Я не могу объяснить все это здесь; слишком широкий.
Я не могу помочь с 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);
Это запишет файл соответствия DICOM с классом SOP «вторичный захват» и метаданными по умолчанию.
Чтобы настроить метаданные, добавьте элементы данных в 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 помогает вам, создавая соответствующий вторичный объект захвата с обязательными элементами данных, но он не поможет вам создать объект модальности (например, сбор данных КТ).
Вопрос, насколько я понял, был "как преобразовать изображение jpg в изображение Dicom, сгенерировав метаданные с помощью java-кода". Я считаю, что мой пост действительно приносит ответ. Что касается целостности данных, вы правы, но класс DeCaMino по умолчанию SOP — это вторичный захват, что означает, что некоторые неоригинальные данные и любое программное обеспечение DICOM распознают их как таковые. Разработчик должен добавить необходимые метаданные, чтобы сделать файл полезным для того, для чего он предназначен, например, имя пациента и т. д.
Вы правы, я согласен. Я вернул свой отрицательный голос. Спасибо за добавление "EDIT".
Просто примечание:
attribs.setBytes(Tag.PixelData, VR.OW, byteBuf.array());
VR.OW означает 16 бит на пиксель/канал. Поскольку вы заменяете данные пикселей данными пикселей, считанными из изображения JPEG, и вы назвали буфер «byteBuf», я подозреваю, что это непоследовательно. VR.OB — это представление значения для 8 бит на пиксель/канал изображения.
Говоря о каналах, я понимаю, что вы хотите упростить создание объекта DICOM, изменив существующее изображение DICOM, а не создавая новое с нуля. Однако данные цветных пикселей подходят не для всех типов изображений DICOM. Например. если ваш файлToCopyheaderFrom.dcm является изображением радиографии, КТ или МРТ (или многих других типов радиологии), в него нельзя добавлять данные цветовых пикселей.
Кроме того, каждое изображение содержит идентифицирующую информацию (наиболее важными из них являются UID исследования, серии, экземпляра SOP), которые должны быть заменены вновь сгенерированными значениями.
Я понимаю, что изменение существующего объекта DICOM с помощью новых данных о пикселях кажется привлекательным, но этот процесс, вероятно, намного сложнее, чем вы ожидаете. В обоих случаях изучение основных концепций DICOM неизбежно.
Извините за понижение вашего ответа, но на самом деле он не отвечает на вопрос (просто рекомендует другой набор инструментов), плюс в нем отсутствует какой-либо намек на то, что простой замены данных пикселей недостаточно для создания нового изображения DICOM из данных пикселей. Если изображение построено так, как вы предлагаете отправить его в PACS, это может иметь очень пагубные последствия для целостности данных и, в худшем случае, для здоровья пациента. DICOM предназначен для медицинской визуализации, и мы не должны забывать о «медицинской» части.