前言
個(gè)人認(rèn)為,比如說醫(yī)學(xué)圖像分割這個(gè)方向,再具體一點(diǎn)比如腹部器官分割或者肝臟腫瘤分割,需要掌握兩方面的知識(shí):(1)醫(yī)學(xué)圖像預(yù)處理方法;(2)深度學(xué)習(xí)知識(shí)。而第一點(diǎn)是進(jìn)行第二點(diǎn)的必要條件,因?yàn)槟阈枰私廨斎氲紻L網(wǎng)絡(luò)中的到底是長(zhǎng)啥樣的數(shù)據(jù)。這篇文章主要介紹常見的醫(yī)學(xué)圖像讀取方式和預(yù)處理方法。
這兩天又重新回顧了一下醫(yī)學(xué)圖像數(shù)據(jù)的讀取和預(yù)處理方法,在這里總結(jié)一下。
基于深度學(xué)習(xí)做醫(yī)學(xué)圖像數(shù)據(jù)分析,例如病灶檢測(cè)、腫瘤或者器官分割等任務(wù),第一步就是要對(duì)數(shù)據(jù)有一個(gè)大概的認(rèn)識(shí)。但是我剛剛?cè)腴T醫(yī)學(xué)圖像分割的時(shí)候,很迷茫不知道自己該干啥,不知道需要準(zhǔn)備哪些知識(shí),慢慢到現(xiàn)在才建立了一個(gè)簡(jiǎn)陋的知識(shí)體系。個(gè)人認(rèn)為,比如說醫(yī)學(xué)圖像分割這個(gè)方向,再具體一點(diǎn)比如腹部器官分割或者肝臟腫瘤分割,需要掌握兩方面的知識(shí):(1)醫(yī)學(xué)圖像預(yù)處理方法;(2)深度學(xué)習(xí)知識(shí)。 而第一點(diǎn)是進(jìn)行第二點(diǎn)的必要條件,因?yàn)槟阈枰私廨斎氲紻L網(wǎng)絡(luò)中的到底是長(zhǎng)啥樣的數(shù)據(jù)。
這篇文章主要介紹常見的醫(yī)學(xué)圖像讀取方式和預(yù)處理方法。
1. 醫(yī)學(xué)圖像數(shù)據(jù)讀取
1.1 ITK-SNAP軟件
首先介紹一下醫(yī)學(xué)圖像可視化軟件ITK-SNAP, 可以作為直觀感受醫(yī)學(xué)圖像3D結(jié)構(gòu)的工具,也可以用來做為分割和檢測(cè)框標(biāo)注工具,免費(fèi),很好用,安利一下:ITK-SNAP官方下載地址:http://www.itksnap.org/pmwiki/pmwiki.php。此外,mango(http://ric.uthscsa.edu/mango/)是另一個(gè)非常輕量的可視化軟件,也可以試試。我一般用ITK-SNAP。
ITK-SNAP的使用方法可以參考大佬的這篇博文,講的很簡(jiǎn)潔:
JunMa:ITK-SANP使用入門:
https://zhuanlan.zhihu.com/p/104381149
ITK-snap界面
首先要明確一下和人體對(duì)應(yīng)的方向,其中三個(gè)窗口對(duì)應(yīng)三個(gè)切面,對(duì)應(yīng)關(guān)系如下圖所示,按照字母索引即可。例如,左上圖對(duì)應(yīng)R-A-L-P這個(gè)面,是從腳底往頭部方向看的切面(即z方向),另外兩張類似。
紅色切面為矢狀面,紫色切面為冠狀面,綠色切面為橫斷面
也可以同時(shí)將分割結(jié)果導(dǎo)入,對(duì)比觀察。
對(duì)于標(biāo)注不太嚴(yán)謹(jǐn)?shù)牡胤揭部梢跃?xì)化修改。當(dāng)然公開集的話,絕大多數(shù)都挺好的。自己標(biāo)注也是類似。(如果顯示不太清晰,對(duì)比度太低,需要在軟件中調(diào)節(jié)窗寬和窗位)
1.2 SimpleITK
我們知道,最常見的醫(yī)學(xué)圖像有CT和MRI,這都是三維數(shù)據(jù),相比于二維數(shù)據(jù)要難一些。而且保存下來的數(shù)據(jù)也有很多格式,常見的有.dcm .nii(.gz) .mha .mhd(+raw)。這些類型的數(shù)據(jù)都可以用Python的SimpleITK來處理,此外pydicom可以對(duì).dcm文件進(jìn)行讀取和修改。
讀取操作的目的是從每一個(gè)病人數(shù)據(jù)中抽取tensor數(shù)據(jù),用Simpleitk讀取上面的.nii數(shù)據(jù)為例:
import numpy as np import os import glob import SimpleITK as sitk from scipy import ndimage import matplotlib.pyplot as plt ?# 載入需要的庫(kù) # 指定數(shù)據(jù)root路徑,其中data目錄下是volume數(shù)據(jù),label下是segmentation數(shù)據(jù),都是.nii格式 data_path = r'F:LiTS_datasetdata' label_path = r'F:LiTS_datasetlabel' ? dataname_list = os.listdir(data_path) dataname_list.sort() ori_data = sitk.ReadImage(os.path.join(data_path,dataname_list[3])) # 讀取其中一個(gè)volume數(shù)據(jù) data1 = sitk.GetArrayFromImage(ori_data) # 提取數(shù)據(jù)中心的array print(dataname_list[3],data1.shape,data1[100,255,255]) #打印數(shù)據(jù)name、shape和某一個(gè)元素的值 plt.imshow(data1[100,:,:]) # 對(duì)第100張slice可視化 plt.show()
輸出結(jié)果:
['volume-0.nii', 'volume-1.nii', 'volume-10.nii', 'volume-11.nii',... volume-11.nii (466, 512, 512) 232.0
表明該數(shù)據(jù)shape為(466,512,512),注意對(duì)應(yīng)的順序是z,x,y。z其實(shí)是slice的索引。x和y是某一個(gè)slice的寬和高。
z索引為100的plot結(jié)果:
同一個(gè)slice在ITK-SNAP可視化結(jié)果(注意這里(x,y,z=(256,256,101)),因?yàn)閕tk-snap默認(rèn)從1開始索引):
可以發(fā)現(xiàn),上下兩張x軸一樣但y軸方向上下翻轉(zhuǎn)了,這是由于matplotlib顯示方式不同,但是不會(huì)出現(xiàn)讀取數(shù)據(jù)對(duì)不齊的問題。
對(duì)于dicom和mhd的處理方式,可以參考這篇博文:
譚慶波:常見醫(yī)療掃描圖像處理步驟:
https://zhuanlan.zhihu.com/p/52054982
2.醫(yī)學(xué)圖像預(yù)處理
這部分內(nèi)容比較雜亂。因?yàn)椴煌娜蝿?wù)、不同的數(shù)據(jù)集,通常數(shù)據(jù)預(yù)處理的方法有很大不同。但基本思路是要讓處理后的數(shù)據(jù)更有利于網(wǎng)絡(luò)訓(xùn)練。那么二維圖像預(yù)處理的一些方法都是可以借鑒的,如對(duì)比度增強(qiáng)、去噪、裁剪等等。此外還有醫(yī)學(xué)圖像本身的一些先驗(yàn)知識(shí)也可以利用,比如CT圖像中不同仿射劑量(單位:HU) 會(huì)對(duì)應(yīng)人體不同的組織器官。
不同放射劑量對(duì)應(yīng)的組織器官
基于上表,可以對(duì)原始數(shù)據(jù)進(jìn)行歸一化處理:
MIN_BOUND = -1000.0 MAX_BOUND = 400.0 def norm_img(image): # 歸一化像素值到(0,1)之間,且將溢出值取邊界值 ? ?image = (image - MIN_BOUND) / (MAX_BOUND - MIN_BOUND) ? ?image[image > 1] = 1. ? ?image[image < 0] = 0. ? ?return image
也可以將其標(biāo)準(zhǔn)化/0均值化,將數(shù)據(jù)中心轉(zhuǎn)移到原點(diǎn)處:
image = image-meam
上述歸一化處理適用于絕大多數(shù)數(shù)據(jù)集,其他一些都是可有可無(wú)的針對(duì)于具體數(shù)據(jù)的操作,這些操作包括上面的MIN_BOUND 和MAX_BOUND 都最好參考優(yōu)秀論文的開源代碼的處理方式。
預(yù)處理后的數(shù)據(jù)集建議保存在本地,這樣可以減少訓(xùn)練時(shí)的部分資源消耗。此外,如隨機(jī)裁剪、線性變換等數(shù)據(jù)增強(qiáng)處理步驟,還是需要在訓(xùn)練時(shí)進(jìn)行。
審核編輯:黃飛
評(píng)論
查看更多