В этом руководстве предполагается, что среда разработки уже настроена, поэтому, прежде чем продолжить, вам необходимо настроить ее, следуя другому руководству Настройка dcmtk с помощью cmake для разработки на C++ и Visual Studio 2019.
Без этой конфигурации невозможно выполнить ни одно из следующих действий. Также в этом руководстве я буду использовать проект TestDCMTK, созданный в Руководстве по настройке.
Целью этого руководства является создание небольшого примера приложения, которое послужит введением в программирование с использованием библиотеки DCMTK. Этот пример будет состоять из консольного приложения, которое создаст файл DICOM с определенными данными и тестовым изображением. Информацию, необходимую для реализации этого приложения, можно найти в документации DCMTK и в коде команды img2dcm.
В конце этого руководства вы найдете весь код создаваемого приложения.
В Visual Studio проекты «Консольное приложение» создаются с помощью файла .cpp, в котором вы пишете код для запуска. Поэтому проект TestDCMTK, созданный ранее как «Консольное приложение», имеет файл TestDCMTK.cpp, в котором приложение будет программироваться с использованием библиотеки DCMTK.
Для указанных выше функций необходимо включить следующее:
#include <iostream> #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dcfilefo.h" #include "dcmtk/dcmdata/libi2d/i2d.h" #include "dcmtk/dcmdata/libi2d/i2djpgs.h" #include "dcmtk/dcmdata/libi2d/i2dplsc.h" #include "dcmtk/dcmdata/dctk.h"using namespace std;
DCMTK имеет множество функций, которые указаны в документации. Однако, чтобы использовать их, их необходимо включить/импортировать, как это делалось ранее, чтобы использовать классы и функциональные возможности для управления структурами данных DICOM и для преобразования изображений в DICOM.
После этого внутри функции мы создадим и инициализируем используемые переменные:
char uid[100]; I2DImgSource* inputPlug = new I2DJpegSource(); I2DOutputPlug* outPlug = new I2DOutputPlugSC(); Image2Dcm i2d; E_TransferSyntax writeXfer; DcmDataset* resultDset = NULL;
Им можно дать любое имя, главное, чтобы они использовались правильно.
- uid будет использоваться для создания uid экземпляра SOP.
- inputPlug имеет тип I2DJpegSource, который является реализацией I2DImgSource для анализа изображений JPEG и преобразования их в файлы DICOM.
- outPlug имеет тип I2DOutputPlugSC, который реализует преобразование изображения в файл DICOM.
- i2d — это переменная типа Image2Dcm, в которой реализованы утилиты для преобразования изображения в файл DICOM.
- writeXfer — это переменная типа E_TransferSyntax, которая состоит из перечислителя всех синтаксисов передачи DICOM, известных набору инструментов.
- resultDset — это переменная типа DcmDataset, представляющая собой класс, обрабатывающий формат набора данных DICOM.
Как только это будет сделано, мы настроим входное изображение для чтения с помощью inputPlug, а затем выполним преобразование изображения в DICOM с помощью функции i2d convert, которому в качестве входных параметров передается следующее:
- inputPlug с изображением для преобразования.
- outPlug, чтобы выполнить преобразование.
При этом по выходным параметрам ему передается следующее:
- resultDset для сохранения результирующего объекта DICOM.
- writeXfer, чтобы сохранить синтаксис передачи.
Тогда для этого примера результирующий код будет таким:
inputPlug->setImageFile("test.jpg"); i2d.convert(inputPlug, outPlug, resultDset, writeXfer);
После этого объект resultDset будет состоять из объекта DICOM без изображения, но с ним. Этот объект типа DcmDataset предоставляет определенные функции для установки данных в нем. Используя эти же функции, имя пациента, идентификатор класса СОП и идентификатор экземпляра СОП будут установлены с данными теста:
resultDset->putAndInsertString(DCM_PatientName, "Brandon Lara"); resultDset->putAndInsertString(DCM_SOPClassUID, UID_SecondaryCaptureImageStorage); resultDset->putAndInsertString(DCM_SOPInstanceUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
В первом параметре вы указываете, какие данные будут редактироваться, вы можете указать это напрямую или использовать теги DCMTK. На мой взгляд, я думаю, что более читабельно использовать теги.
Во втором параметре вы вводите новое значение, которое будут иметь данные, переданные первым параметром.
Наконец, resultDset будет сохранен в виде файла DICOM (.dcm) в папке проекта. Для этого необходимо создать DcmFileFormat с этим resultDset, чтобы сохранить его с помощью функции сохранения DcmFileFormat.
Таким образом, код будет выглядеть так:
DcmFileFormat dcmff(resultDset); dcmff.saveFile("test.dcm", writeXfer, EET_ExplicitLength, EGL_recalcGL, EPD_noChange, OFstatic_cast(Uint32, 0), OFstatic_cast(Uint32, 0), EWM_fileformat);
Как видно по первому параметру данные сохраняются в файл test.dcm, а остальные параметры задаются так же, как это сделано в коде команды img2dcm.
Перед выполнением всего этого кода в папке проекта, содержащей файл .cpp, вы должны поместить тестовое изображение для преобразования в файл DICOM (в моем случае test.jpg):
Затем мы запускаем проект TestDCMTK с помощью Visual Studio:
Если все прошло хорошо, вы должны были создать файл test.dcm в папке проекта, содержащей файл .cpp и туда, куда был помещен тестовый образ.
Данные в этом файле можно отобразить с помощью консольных утилит DCMTK, путем программирования кода C++ с использованием библиотек или с помощью средства просмотра DICOM.
- С помощью MicroDicom видно, что все настроено правильно:
- Используя библиотеки DCMTK, мы можем написать следующий код для отображения имени пациента на консоли:
В моем случае результат выполнения этого кода:
Как я уже говорил в начале этого руководства, вот весь код приложения, созданного для этого руководства:
Я надеюсь, что это руководство послужило облегчению введения в программирование с помощью этой библиотеки, любые сомнения или предложения вы можете сообщить мне без проблем, я всегда постараюсь ответить :)