前言
在用神經網絡推理3D醫學圖像之後,可能會存在一些小塊的連通區域,不是我們想保留下來的預測結果,就需要把它們删掉。例如下圖,預測結果中有很多這種點,我希望把它們濾掉。
注意我這裡處理的是d,h,w的3D圖像,截圖隻展示了某一個截面的結果
代碼
# 後處理檔案,去除獨立的小點
import os
import SimpleITK as sitk
import numpy as np
import tqdm
def postProcessing(image,file_name,reseve_area_minvalue):
"""
對标簽的後處理
:param image: sitk image圖像
:param reseve_area_minvalue: 保留下來的最小連通區域面積
:return: None. 将處理後的檔案寫入本地
"""
closingImage = sitk.BinaryMorphologicalClosing(image,[3,3,3])
imageArray = sitk.GetArrayFromImage(image)
ccFilter = sitk.ConnectedComponentImageFilter()
ccFilter.SetFullyConnected(True)
outputMask = ccFilter.Execute(closingImage)
lssFilter = sitk.LabelShapeStatisticsImageFilter()
lssFilter.Execute(outputMask)
numConnectedLabel = ccFilter.GetObjectCount()
# 連通域label從1開始,0表示背景
areaLabels = []
for i in range(1,numConnectedLabel+1):
area = lssFilter.GetNumberOfPixels(i)
if area>=reseve_area_minvalue:
areaLabels.append(i) # 把這個塊區域的label存進去
# print(len(areaLabels))
npOutputMask = sitk.GetArrayFromImage(outputMask)
resMask = np.zeros_like(npOutputMask).astype("uint8")
for labelIndex in areaLabels:
# print(labelIndex)
resMask[npOutputMask==labelIndex] = imageArray[npOutputMask==labelIndex]
outImage = sitk.GetImageFromArray(resMask)
outImage.SetDirection(image.GetDirection())
outImage.SetSpacing(image.GetSpacing())
outImage.SetOrigin(image.GetOrigin())
savePath = os.path.join(saveDir,file_name)
sitk.WriteImage(outImage,savePath)
if __name__ == '__main__':
workDir = r"I:\2023label_2\label"
# workDir = "mergeThreeLabel"
saveDir = r"I:\2023label_2\label2"
fileNames = os.listdir(workDir)
for fileName in tqdm.tqdm(fileNames):
filePath = os.path.join(workDir,fileName)
orgImage = sitk.ReadImage(filePath)
postProcessing(orgImage,fileName,500)
# input('zzz')