В этом руководстве предполагается, что среда разработки уже настроена, поэтому, прежде чем продолжить, вам необходимо настроить ее, следуя другому руководству Настройка 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, мы можем написать следующий код для отображения имени пациента на консоли:

В моем случае результат выполнения этого кода:

Как я уже говорил в начале этого руководства, вот весь код приложения, созданного для этого руководства:

Я надеюсь, что это руководство послужило облегчению введения в программирование с помощью этой библиотеки, любые сомнения или предложения вы можете сообщить мне без проблем, я всегда постараюсь ответить :)