2016-04-02 9 views
-2

Я хотел бы прочитать изображения DICOM на C++ и манипулировать ими с помощью opencv.Прочтите DICOM в C++ и конвертируйте в OpenCV

Мне удалось прочитать изображение dicom, используя DCMTK, однако я не уверен, как преобразовать его в opencv Mat.

Ниже то, что я до сих пор:

DicomImage DCM_image("test.dcm"); 
cv::Mat image(int(DCM_image.getWidth()), int(DCM_image.getHeight()), CV_8U, (uchar*)DCM_image.getOutputData(8)); 

, что приводит к следующему:

enter image description here

В средстве просмотра DICOM, это выглядит следующим образом:

enter image description here

После нормализующее, посеревшую изображение выглядит следующим образом:

enter image description here

Любая помощь будет принята с благодарностью.

ответ

1

Основная проблема, которую я вижу сейчас, заключается в различии диапазонов значений пикселей (глубин).

AFAIK, DICOM может иметь довольно большую глубину (16 бит), и вы пытаетесь вписаться в CV_8U, который всего 8 бит. Вы можете получить глубину экземпляра DicomImage с помощью DicomImage::getDepth(), а затем создать cv::Mat с соответствующей глубиной для хранения данных изображения.

Вам также может потребоваться нормализовать данные, чтобы максимально использовать доступный вам диапазон, чтобы дисплей с cv::imshow() выглядел так, как ожидалось.

Итак:

  • ли DicomImage::getDepth() на вашем DCM_image
  • Создать cv::Mat с достаточной глубиной, чтобы держать ваши данные
  • Scale при необходимости
+0

Я отдам его.Кроме того, нормализация должна выполняться до или после передачи данных в opencv? Если раньше, это нужно делать с помощью getOutputData? Спасибо – user3126802

+0

Я думаю, что если вы выберете глубину соответствующим образом, нет никакой разницы. Кроме того, по моему опыту, у некоторых зрителей DICOM необычная нормализация, из-за чего данные выходят за пределы диапазона (структура на скриншоте выглядит совершенно белой, как и переэкспонированной). Поэтому, возможно, вы хотели бы нормализовать свои данные по-разному. – alexisrozhkov

+0

Я создаю cv :: mat следующим образом: 'cv :: Mat test (int (DCM_image.getHeight()), int (DCM_image.getWidth()), CV_MAKETYPE (DCM_image.getDepth(), 1), (длинный *) DCM_image.getOutputData()); ' Однако выход по-прежнему не очень хорош. Любая идея почему? – user3126802

-1

U необходимо прочитать тип данных в кодировке изображения DICOM, преобразовать это в opencv type Mat. Документы opencv предоставляют всю информацию об их заголовке Mat.

+0

Изменен вопрос, чтобы показать вам, что у меня есть до сих пор и каков результат. Спасибо – user3126802

+0

В заголовке коврика CV ширина и высота должны быть заменены. Как отличается результат от оригинала. –

+0

Вы правы. Тем не менее, я больше беспокоюсь об интенсивности. Я отправлю изображение, чтобы показать вам, как оно появляется на считывателе DICOM. – user3126802

0

Перед вызовом DicomImage :: getOutputData () на монохромном изображении DICOM, вы должны убедиться, что выбрали соответствующее преобразование VOI (например, Window Center & Widt час). Это можно сделать с помощью DicomImage :: setMinMaxWindow(), DicomImage :: setWindow() и т. Д. См. Документацию класса DicomImage.

Обратите внимание, что DicomImage :: getOutputData() всегда возвращает отображаемые пиксельные данные, то есть не оригинальные пиксельные данные, которые хранятся в наборе данных DICOM.