DICOM(Digital Imaging and Communications in Medicine)即醫(yī)學(xué)數(shù)字成像和通信,是醫(yī)學(xué)圖像和相關(guān)信息的國(guó)際標(biāo)準(zhǔn)(ISO 12052)。它定義了質(zhì)量能滿足臨床需要的可用于數(shù)據(jù)交換的醫(yī)學(xué)圖像格式,可用于處理、存儲(chǔ)、打印和傳輸醫(yī)學(xué)影像信息。DICOM可以便捷地交換于兩個(gè)滿足DICOM格式協(xié)議的工作站之間。目前該協(xié)議標(biāo)準(zhǔn)不僅廣泛應(yīng)用于大型醫(yī)院,而且已成為小型診所和牙科診所醫(yī)生辦公室的標(biāo)準(zhǔn)影像閱讀格式。
DICOM被廣泛應(yīng)用于放射醫(yī)療、心血管成像以及放射診療診斷設(shè)備(X射線,CT,核磁共振,超聲等),并且在眼科和牙科等其它醫(yī)學(xué)領(lǐng)域得到越來(lái)越深入廣泛的應(yīng)用。在數(shù)以萬(wàn)計(jì)的在用醫(yī)學(xué)成像設(shè)備中,DICOM是部署最為廣泛的醫(yī)療信息標(biāo)準(zhǔn)之一。當(dāng)前大約有百億級(jí)符合DICOM標(biāo)準(zhǔn)的醫(yī)學(xué)圖像用于臨床使用。
目前,越來(lái)越多的DICOM應(yīng)用程序和分析軟件被運(yùn)用于臨床醫(yī)學(xué),促使越來(lái)越多的編程語(yǔ)言開(kāi)發(fā)出支持DICOM API的框架。今天就讓我來(lái)介紹一下Python語(yǔ)言下支持的DICOM模塊,以及如何完成基本DICOM信息分析和處理的編程方法。
[Pydicom]
Pydicom是一個(gè)處理DICOM文件的純Python軟件包。它可以通過(guò)非常容易的“Pythonic”的方式來(lái)提取和修改DICOM數(shù)據(jù),修改后的數(shù)據(jù)還會(huì)借此生成新的DICOM文件。作為一個(gè)純Python包,Pydicom可以在Python解釋器下任何平臺(tái)運(yùn)行,除了必須預(yù)先安裝Numpy模塊外,幾乎無(wú)需其它任何配置要求。其局限性之一是無(wú)法處理壓縮像素圖像(如JPEG),其次是無(wú)法處理分幀動(dòng)畫(huà)圖像(如造影電影)。
[SimpleITK]
Insight Segmentation and Registration Toolkit (ITK)是一個(gè)開(kāi)源、跨平臺(tái)的框架,可以提供給開(kāi)發(fā)者增強(qiáng)功能的圖像分析和處理套件。其中最為著名的就是SimpleITK,是一個(gè)簡(jiǎn)化版的、構(gòu)建于ITK最頂層的模塊。SimpleITK旨在易化圖像處理流程和方法。
[PIL]
Python Image Library (PIL) 是在Python環(huán)境下不可缺少的圖像處理模塊,支持多種格式,并提供強(qiáng)大的圖形與圖像處理功能,而且API卻非常簡(jiǎn)單易用。
[OpenCV]
OpenCV的全稱是:Open Source Computer Vision Library。OpenCV是一個(gè)基于BSD許可(開(kāi)源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺(jué)庫(kù),可以運(yùn)行在Linux、Windows和Mac OS操作系統(tǒng)上。它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類(lèi)構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語(yǔ)言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺(jué)方面的很多通用算法。
下面就讓我以實(shí)際Python代碼來(lái)演示如何編程處理心血管冠脈造影DICOM圖像信息。
1. 導(dǎo)入主要框架:SimpleITK、pydicom、PIL、cv2和numpy
import SimpleITK as sitk
from PIL import Image
import dicom
import numpy as np
import cv2
2. 應(yīng)用SimpleITK框架來(lái)讀取DICOM文件的矩陣信息。如果DICOM圖像是三維螺旋CT圖像,則幀參數(shù)則代表CT掃描層數(shù);而如果是造影動(dòng)態(tài)電影圖像,則幀參數(shù)就是15幀/秒的電影圖像幀數(shù)。
def loadFile(filename):
? ? ds = sitk.ReadImage(filename)
? ? img_array = sitk.GetArrayFromImage(ds)
? ? frame_num, width, height = img_array.shape
? ? return img_array, frame_num, width, height
3. 應(yīng)用pydicom來(lái)提取患者信息。
def loadFileInformation(filename):
? ? information = {}
? ? ds = dicom.read_file(filename)
information['PatientID'] = ds.PatientID
information['PatientName'] = ds.PatientName
information['PatientBirthDate'] = ds.PatientBirthDate
information['PatientSex'] = ds.PatientSex
information['StudyID'] = ds.StudyID
information['StudyDate'] = ds.StudyDate
information['StudyTime'] = ds.StudyTime
information['InstitutionName'] = ds.InstitutionName
information['Manufacturer'] = ds.Manufacturer
information['NumberOfFrames'] = ds.NumberOfFrames
return information
4. 應(yīng)用PIL來(lái)檢查圖像是否被提取。
def showImage(img_array, frame_num = 0):
? ? img_bitmap = Image.fromarray(img_array[frame_num])
? ? return img_bitmap
5. 采用CLAHE (Contrast Limited Adaptive Histogram Equalization)技術(shù)來(lái)優(yōu)化圖像。
def limitedEqualize(img_array, limit = 4.0):
? ? img_array_list = []
? ? for img in img_array:
? ? ? ? clahe = cv2.createCLAHE(clipLimit = limit, tileGridSize = (8,8))
? ? ? ? img_array_list.append(clahe.apply(img))
? ? img_array_limited_equalized = np.array(img_array_list)
? ? return img_array_limited_equalized
這一步對(duì)于整個(gè)圖像處理起到很重要的作用,可以根據(jù)不同的原始DICOM圖像的窗位和窗寬來(lái)進(jìn)行動(dòng)態(tài)調(diào)整,以達(dá)到最佳的識(shí)別效果。
原始圖像:
經(jīng)過(guò)自動(dòng)窗位窗寬調(diào)節(jié),生成:
最后應(yīng)用OpenCV的Python框架cv2把每幀圖像組合在一起,生成通用視頻格式。
def writeVideo(img_array):
? ? frame_num, width, height = img_array.shape
? ? filename_output = filename.split('.')[0] + '.avi'
video = cv2.VideoWriter(filename_output, -1, 16, (width, height))
for img in img_array:
video.write(img)
video.release()