Проблема качества медицинского изображения с файлами DICOM - PullRequest
0 голосов
/ 10 ноября 2019

Я пытаюсь выполнить некоторые задачи сегментации изображений CT в формате DICOM, используя python.

Основная проблема заключается в том, что при попытке прочитать файл DICOM (https://www.dicomlibrary.com/meddream/md5/index.html?study=1.2.826.0.1.3680043.8.1055.1.20111102150758591.92402465.76095170)используя библиотеку pydicom и используя атрибут pixel_array для отображения изображения, я получаю изображение гораздо худшего качества, чем оригинал (см. код и снимки экрана ниже).

dicom_file = pydicom.read_file('Anonymized20191102.dcm')
plt.imshow(dicom_file.pixel_array, cmap='gray')
plt.show()

The original image

The image displayed with matplotlib

Мой вопрос, чтобы лучше понять проблему,:

  1. Что представляет собой атрибут pixel_array? Я видел, что он принимает значения в диапазоне [0, 2250].

Наблюдения:

Я такжепопытался получить значения единицы hounsfield (HU) путем умножения на уклон и добавления смещения следующим образом:

def convert_to_hu(dicom_file):
    bias = dicom_file.RescaleIntercept
    slope = dicom_file.RescaleSlope
    pixel_values = dicom_file.pixel_array
    new_pixel_values = (pixel_values * slope) + bias
    return new_pixel_values

hu_pixels = convert_to_hu(dicom_file)
plt.imshow(hu_pixels, cmap='gray')
plt.show()

Результат с точки зрения визуализации практически совпадает с результатом с исходными значениями из pixel_arrayТакже значения находятся в диапазоне [-1000, 1250] (что, на мой взгляд, хорошо, учитывая тот факт, что HU обычно составляет от -1000 до 1000).

Ответы [ 2 ]

3 голосов
/ 11 ноября 2019

Второе изображение выглядит так, как будто оно построило пиксели с использованием диапазона градаций серого, который соответствует всем предоставленным значениям HU, а не просто отображением диапазона значений HU, который соответствует отображаемой анатомии.

Пока яЯ не уверен, как Pydicom справляется с этим, вам нужно «окно и уровень» изображение, чтобы получить результат от первого изображения. Применение окна / уровня, обычно через линейную VOI LUT для изображений CT, ограничит диапазон отображаемых пикселей и масштабирует их до отображаемого диапазона, обычно 8-битного, если не используются мониторы в градациях серого.

Изображение CT, скорее всего, имеет теги для Window Center (0028,1050) для установки уровня и Window Width (0028,1051) для установки окна. Значения центра и ширины в изображении обеспечивались модальностью, которая генерировала изображение, и соответствуют хорошему диапазону для отображения области живота на изображении. Ссылка ниже предоставляет несколько общих настроек окна / уровня для изображений CT, основанных на просматриваемой части тела, а также предоставляет дополнительную информацию о том, как настройки влияют на отображаемое изображение.

https://radiopaedia.org/articles/windowing-ct

Несмотря на то, что применение окна / уровня полезно для отображения изображения, вы теряете битовую глубину, конвертируя из 10 или 12 бит, сохраненных на пиксель (общий для изображения CT), в 8 бит, отображаемых на пиксель. Вам нужно будет определить, нужна ли эта дополнительная битовая глубина для вашей задачи сегментации.

0 голосов
/ 14 ноября 2019

Как и Колби сказал , причина, по которой он выглядит неправильно, почти наверняка является уровнем окна.

Для изображения CT, подобного этому, вы, вероятно, захотите уровень окна около w = 400, уровень= 50, то есть мин = -150, макс = 250. См. Статью Colby, связанную с.

Вы можете выбрать подходящие значения уровня окна (т. Е. Min / max) или, как упоминал Колби, извлечь их из вероятных сохраненных значений WL в файле dicom,и вычислите мин / макс из них (мин = уровень - окно / 2, макс = уровень + окно / 2).

В вашем коде измените его на:

level = dicom_file.WindowCenter
window = dicom_file.WindowWidth
# ...or set window/level manually to values you want
vmin = level - window/2
vmax = level + window/2
plt.imshow(hu_pixels, cmap='gray', vmin=vmin, vmax=vmax)
plt.show()

ТакжеВы сказали в начале: «Я пытаюсь выполнить некоторые задачи сегментации».

Если это так, вам нужно использовать 16-битные данные как есть, а не 8-битную версию, поскольку

  1. у него гораздо больший диапазон данных, поэтому он намного лучше для сегментации, и
  2. для КТ, фактические значения имеют клиническое значение, поэтому являются критическими для сегментации.

... так что, если вашей общей целью является сегментирование, а не просто отображение изображения, то отображение с правильным окном / уровнем не является большой проблемой. Для сегментации вам необходимо понять, что данные заполнены 16-разрядными данными и использовать их во всем 16-разрядном диапазоне данных.

Просто выясните, как работает WL и как отображать его так, как вам нравится / нужно /хотите с imshow (), и вам будет хорошо.

...