RT struct 文件 保存为nii文件及解析
最近在做放療劑量預測相關工作,需要將TPS系統中的RTdose、RTstruct文件等進行解析。開個帖子記錄一下,僅供參考。
本帖記錄RT struct文件解析
目的:
將TPS導出的病人文件相關文件轉換.nii 或者 .npy
病例文件結構:
導出的數據應該包括病人的dcm原始CT圖像以及RTstruct文件,結構目錄如下:
處理流程:
參考開源的 dcmrtstruct2nii 工具包,pip 安裝后,修改部分源代碼 。以解決dcm文件不能讀取以及是否保存文件到磁盤的問題。
1、安裝dcmrtstruct2nii 包
pip install dcmrtstruct2nii2、簡單的使用
from dcmrtstruct2nii import dcmrtstruct2nii, list_rt_structs path = './StrctrSets.dcm' print(list_rt_structs(path)) dcmrtstruct2nii(path, './test', './outputa') #分別對應rtstruct.dcm,病人圖像文件夾,輸出文件夾通過以上代碼可以直接將RTstruct文件 提取出來并保存為nii?,如果報錯不能加載dcm文件,請參考第三節。
dcmrtstruct2nii具體參數請自行參考源碼:
?3、修改dcmrtstruct2nii源碼,使得可以讀入自己的數據。在讀入過程報錯:
File is missing DICOM File Meta Information header or the 'DICM' prefix is missing from the header. Use force=True to force reading.如下圖請點擊報錯的地方,?然后在讀入文件的那句話加入參數force=true。修改后如圖 一般是在rtstructinputadapter.py中
?修改完后,即可以讀入圖像。這個一般是因為TPS導出的dcm,pydicom無法識別。加一個force便可以對其進行讀取。
4、為了方便調試,重寫dcmrtstruct2nii函數,添加返回值:結構體名字,結構體的Sitk.Image 數據
并根據output是否為空決定是否保存圖像到磁盤。修改后的源碼如下:
def dcmrtstruct2nii(rtstruct_file, dicom_file, output_path='', structures=None, gzip=True,mask_background_value=0, mask_foreground_value=255,convert_original_dicom=True):"""Converts A DICOM and DICOM RT Struct file to nii:param rtstruct_file: Path to the rtstruct file:param dicom_file: Path to the dicom file:param output_path: Output path where the masks are written to:param structures: Optional, list of structures to convert:param gzip: Optional, output .nii.gz if set to True, default: True:param save:Optional, whether to save nii file default:True:raise InvalidFileFormatException: Raised when an invalid file format is given.:raise PathDoesNotExistException: Raised when the given path does not exist.:raise UnsupportedTypeException: Raised when conversion is not supported.:raise ValueError: Raised when mask_background_value or mask_foreground_value is invalid."""output_path = os.path.join(output_path, '') # make sure trailing slash is thereif not os.path.exists(rtstruct_file):raise PathDoesNotExistException(f'rtstruct path does not exist: {rtstruct_file}')if not os.path.exists(dicom_file):raise PathDoesNotExistException(f'DICOM path does not exists: {dicom_file}')if mask_background_value < 0 or mask_background_value > 255:raise ValueError(f'Invalid value for mask_background_value: {mask_background_value}, must be between 0 and 255')if mask_foreground_value < 0 or mask_foreground_value > 255:raise ValueError(f'Invalid value for mask_foreground_value: {mask_foreground_value}, must be between 0 and 255')if structures is None:structures = []#### 如果輸出路徑為空,不進行文件保存if output_path != '':os.makedirs(output_path, exist_ok=True)filename_converter = FilenameConverter()rtreader = RtStructInputAdapter()rtstructs = rtreader.ingest(rtstruct_file)dicom_image = DcmInputAdapter().ingest(dicom_file)dcm_patient_coords_to_mask = DcmPatientCoords2Mask()nii_output_adapter = NiiOutputAdapter()mask_name = [] ##定義保存結構體名字的列表mask_Image = [] ##定義保存Image的列表for rtstruct in rtstructs:if len(structures) == 0 or rtstruct['name'] in structures:if not 'sequence' in rtstruct:logging.info('Skipping mask {} no shape/polygon found'.format(rtstruct['name']))continuelogging.info('Working on mask {}'.format(rtstruct['name']))try:mask = dcm_patient_coords_to_mask.convert(rtstruct['sequence'], dicom_image, mask_background_value, mask_foreground_value)except ContourOutOfBoundsException:logging.warning(f'Structure {rtstruct["name"]} is out of bounds, ignoring contour!')continuemask.CopyInformation(dicom_image)mask_filename = filename_converter.convert(f'mask_{rtstruct["name"]}')mask_name.append(mask_filename)mask_Image.append((mask))if output_path != '':#### 如果輸出路徑為空,不進行文件保存nii_output_adapter.write(mask, f'{output_path}{mask_filename}', gzip)return mask_name,mask_Image ##返回對應的兩個列表if convert_original_dicom:logging.info('Converting original DICOM to nii')nii_output_adapter.write(dicom_image, f'{output_path}image', gzip)logging.info('Success!')在修改代碼后,便可以通過以下的代碼對函數進行調用
from dcmrtstruct2nii import dcmrtstruct2nii, list_rt_structs path = './RTDICOM/20220356_StrctrSets.dcm' print(list_rt_structs(path)) name, image = dcmrtstruct2nii(path, './RTDICOM/patient') #參數分別為struct文件、病人圖像文件夾,輸出文件夾img = sitk.GetArrayFromImage(image[0]) import matplotlib.pyplot as plt plt.imshow(img[60]) plt.show()可以print name和image[0]的類型進行查看,并進行后續工作。
5、關于RTdose的解析,請見后續。
總結
以上是生活随笔為你收集整理的RT struct 文件 保存为nii文件及解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringMVC原理
- 下一篇: MATLAB 产生线性调频信号