Использование изображений dicom с OpenCV в Python
Я пытаюсь использовать изображение dicom и манипулировать им, используя OpenCV в среде Python. До сих пор я использовал библиотеку pydicom для чтения данных изображения dicom(.dcm) и использования атрибута массива пикселей для отображения изображения с помощью метода OpenCV imshow. Но вывод - просто пустое окно. Вот фрагмент кода, который я использую в данный момент.
import numpy as np
import cv2
import pydicom as dicom
ds=dicom.dcmread('sample.dcm')
cv2.imshow('sample image dicom',ds.pixel_array)
cv2.waitkey()
Если я распечатаю массив, который используется здесь, результат будет отличаться от того, что я получу с обычным массивом numpy. Я также попытался использовать метод matplotlib imshow, и он смог отобразить изображение с некоторыми искажениями цвета. Есть ли способ конвертировать массив в удобочитаемый формат для OpenCV?
4 ответа
Я нашел способ заставить изображение показать. Как отметил Дэн в комментариях, значение матрицы было уменьшено, и из-за функции imshow выходные данные были слишком темными, чтобы человеческий глаз не мог их различить. Итак, в конце концов, единственное, что мне нужно было сделать, - это умножить все данные по мату на 128. Изображение теперь отлично видно. умножение матрицы на 255 обнажает изображение и приводит к потере определенных функций. Вот пересмотренный код.
import numpy as np
import cv2
import pydicom as dicom
ds=dicom.dcmread('sample.dcm')
dcm_sample=ds.pixel_array*128
cv2.imshow('sample image dicom',dcm_sample)
cv2.waitkey()
Столкнулся с аналогичной проблемой. Используемыйexposure.equalize_adapthist()
(источник). Полученное изображение не является стопроцентным по сравнению с тем, которое вы могли бы увидеть с помощью средства просмотра DICOM Viewer, но это лучшее, что мне удалось получить.
import numpy as np
import cv2
import pydicom as dicom
from skimage import exposure
ds=dicom.dcmread('sample.dcm')
dcm_sample=ds.pixel_array
dcm_sample=exposure.equalize_adapthist(dcm_sample)
cv2.imshow('sample image dicom',dcm_sample)
cv2.waitkey()
Это лучший способ (на мой взгляд) открыть изображение в opencv в виде массива numpy, сохраняя при этом качество изображения:
import numpy as np
import pydicom, os, cv2
def dicom_to_numpy(ds):
DCM_Img = ds
rows = DCM_Img.get(0x00280010).value #Get number of rows from tag (0028, 0010)
cols = DCM_Img.get(0x00280011).value #Get number of cols from tag (0028, 0011)
Instance_Number = int(DCM_Img.get(0x00200013).value) #Get actual slice instance number from tag (0020, 0013)
Window_Center = int(DCM_Img.get(0x00281050).value) #Get window center from tag (0028, 1050)
Window_Width = int(DCM_Img.get(0x00281051).value) #Get window width from tag (0028, 1051)
Window_Max = int(Window_Center + Window_Width / 2)
Window_Min = int(Window_Center - Window_Width / 2)
if (DCM_Img.get(0x00281052) is None):
Rescale_Intercept = 0
else:
Rescale_Intercept = int(DCM_Img.get(0x00281052).value)
if (DCM_Img.get(0x00281053) is None):
Rescale_Slope = 1
else:
Rescale_Slope = int(DCM_Img.get(0x00281053).value)
New_Img = np.zeros((rows, cols), np.uint8)
Pixels = DCM_Img.pixel_array
for i in range(0, rows):
for j in range(0, cols):
Pix_Val = Pixels[i][j]
Rescale_Pix_Val = Pix_Val * Rescale_Slope + Rescale_Intercept
if (Rescale_Pix_Val > Window_Max): #if intensity is greater than max window
New_Img[i][j] = 255
elif (Rescale_Pix_Val < Window_Min): #if intensity is less than min window
New_Img[i][j] = 0
else:
New_Img[i][j] = int(((Rescale_Pix_Val - Window_Min) / (Window_Max - Window_Min)) * 255) #Normalize the intensities
return New_Img
file_path = "C:/example.dcm"
image = pydicom.read_file(file_path)
image = dicom_to_numpy(image)
#show image
cv2.imshow('sample image dicom',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Я не думаю, что это правильный ответ. Это работает для этого конкретного изображения, потому что большинство ваших значений пикселей находятся в нижнем диапазоне. Отметьте этот OpenCV: Как визуализировать изображение глубины. Он предназначен для C++, но легко адаптируется к Python.