Как получить доступ к массивам пикселей RGB из файлов DICOM, используя pydicom?
Я пытаюсь получить доступ к пиксельному массиву RGB файла DICOM с неизвестным сжатием (может быть, ни одного). Извлечение пиксельных массивов в градациях серого работает совершенно нормально.
Однако, используя
import dicom
import numpy as np
data_set = dicom.read_file(path)
pixel_array = data_set.pixel_array
size_of_array = pixel_array.shape
if len(size_of_array ) == 3:
chanR = pixel_array[0][0:size_of_array[1], 0:size_of_array[2]]
chanG = pixel_array[1][0:size_of_array[1], 0:size_of_array[2]]
chanB = pixel_array[2][0:size_of_array[1], 0:size_of_array[2]]
output_array = (0.299 ** chanR) + (0.587 ** chanG) + (0.114 ** chanB)
с целью преобразовать его в общий массив оттенков серого. К сожалению, массив результатов output_array
не содержит правильных данных пикселей Содержимое не ложно масштабировано, оно пространственно нарушено. Где проблема?
3 ответа
Это не массив пикселей RGB, и лучший способ - преобразовать изображение в серое.
Чтобы получить изображение CT, нужно получить атрибут pixel_array в файле CT dicom. Типы элементов в pixel_array файла CT dicom - все uint16, но многие инструменты в Python, такие как OpenCV, некоторые вещи AI, не могут быть совместимы с этим типом.
После получения pixel_array (CT Image) из файла CT dicom вам всегда нужно преобразовать pixel_array в серое изображение, чтобы вы могли обработать это серое изображение с помощью большого количества инструментов обработки изображений в python.
Следующий код представляет собой рабочий пример преобразования pixel_array в серое изображение.
import matplotlib.pyplot as plt
import os
import pydicom
import numpy as np
# Abvoe code is to import dependent libraries of this code
# Read some CT dicom file here by pydicom library
ct_filepath = r"<YOUR_CT_DICOM_FILEPATH>"
ct_dicom = pydicom.read_file(ct_filepath)
img = ct_dicom.pixel_array
# Now, img is pixel_array. it is input of our demo code
# Convert pixel_array (img) to -> gray image (img_2d_scaled)
## Step 1. Convert to float to avoid overflow or underflow losses.
img_2d = img.astype(float)
## Step 2. Rescaling grey scale between 0-255
img_2d_scaled = (np.maximum(img_2d,0) / img_2d.max()) * 255.0
## Step 3. Convert to uint
img_2d_scaled = np.uint8(img_2d_scaled)
# Show information of input and output in above code
## (1) Show information of original CT image
print(img.dtype)
print(img.shape)
print(img)
## (2) Show information of gray image of it
print(img_2d_scaled.dtype)
print(img_2d_scaled.shape)
print(img_2d_scaled)
## (3) Show the scaled gray image by matplotlib
plt.imshow(img_2d_scaled, cmap='gray', vmin=0, vmax=255)
plt.show()
И следующее - результат того, что я распечатал.
Вы, наверное, уже обошли это, но я думаю, что pydicom неправильно интерпретирует плоскую конфигурацию.
Вы должны сделать это в первую очередь:
img = data_set.pixel_array
img = img.reshape([img.shape[1], img.shape[2], 3])
Отсюда ваше изображение будет иметь форму [rows cols 3]
с разделенными каналами
Как сказал @Daniel, поскольку у вас есть PlanarConfiguration
== 1
вам нужно переставить цвета в столбцах через np.reshape
а затем преобразование в оттенки серого, например, с помощью OpenCV:
import pydicom as dicom
import numpy as np
import cv2 as cv
data_set = dicom.read_file(path)
pixel_array = data_set.pixel_array
## converting to shape (m,n,3)
pixel_array_rgb = pixel_array.reshape((pixel_array.shape[1], pixel_array.shape[2], 3))
## converting to grayscale
pixel_array_gs = cv.cvtColor(pixel_array_rgb, cv.COLOR_RGB2GRAY)