2024-08-13 給RD.dcm添加DVH Sequence (1)

# Py_add_dcm_DVH.py
# 這個代碼是在安裝了pydicom的環(huán)境運行的灰署,
# 用來導出把dcm_folder里面的患者目錄下面的All_ROI_DVH_data.txt
# 添加到RD.dcm的ds.DVHSequence里面

import os
import zipfile
import pydicom
from pydicom.dataset import Dataset
from pydicom.sequence import Sequence

# 設置DICOM文件夾路徑
dcm_folder = r'X:\dcm_temp'

# 解壓ZIP文件的函數(shù)
def unzip_files(dcm_folder):
    for root, _, files in os.walk(dcm_folder):
        for file in files:
            if file.endswith('.zip'):
                zip_file_path = os.path.join(root, file)
                extract_folder = os.path.splitext(zip_file_path)[0]
                if not os.path.exists(extract_folder):
                    os.makedirs(extract_folder)
                with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
                    zip_ref.extractall(extract_folder)
                print(f'Unzipped {file} to {extract_folder}')

# 處理DICOM和DVH的函數(shù)
def process_dvh_and_dcm_files(dcm_folder):
    for patient_dir in os.listdir(dcm_folder):
        patient_path = os.path.join(dcm_folder, patient_dir)
        if os.path.isdir(patient_path):
            # 查找DICOM文件
            rtstruct_file_path = None
            dicom_file_path = None
            for file in os.listdir(patient_path):
                file_path = os.path.join(patient_path, file)
                if file_path.endswith('.dcm'):
                    dcm_data = pydicom.dcmread(file_path, stop_before_pixels=True)
                    if dcm_data.Modality == 'RTSTRUCT':
                        rtstruct_file_path = file_path
                    elif dcm_data.Modality == 'RTDOSE':
                        dicom_file_path = file_path

            # 查找DVH數(shù)據(jù)
            txt_file_path = os.path.join(patient_path, "All_ROI_DVH_data.txt")

            if txt_file_path and rtstruct_file_path and dicom_file_path:
                # 讀取RTSTRUCT文件以獲取ROI的ROINumber
                rtstruct = pydicom.dcmread(rtstruct_file_path)
                roi_number_map = {roi_seq.ROIName: roi_seq.ROINumber for roi_seq in rtstruct.StructureSetROISequence}

                # 讀取TXT文件中的DVH數(shù)據(jù)
                with open(txt_file_path, 'r') as file:
                    lines = file.readlines()

                # 讀取現(xiàn)有的RTDOSE DICOM文件
                dicom_data = pydicom.dcmread(dicom_file_path)

                # 檢查并初始化DVHSequence
                if not hasattr(dicom_data, 'DVHSequence'):
                    dicom_data.DVHSequence = Sequence()

                # 處理每個ROI的數(shù)據(jù)
                i = 0
                while i < len(lines):
                    if lines[i].startswith("ROI Name:"):
                        roi_name = lines[i].split(":")[1].strip()
                        dvh_type = lines[i+1].split(":")[1].strip()
                        dose_units = lines[i+2].split(":")[1].strip()
                        dose_type = lines[i+3].split(":")[1].strip()
                        dvh_dose_scaling = float(lines[i+4].split(":")[1].strip())
                        dvh_volume_units = lines[i+5].split(":")[1].strip()
                        dvh_number_of_bins = int(lines[i+6].split(":")[1].strip())
                        dvh_minimum_dose = float(lines[i+7].split(":")[1].strip())
                        dvh_maximum_dose = float(lines[i+8].split(":")[1].strip())
                        dvh_mean_dose = float(lines[i+9].split(":")[1].strip())
                        dvh_data = []
                        i += 11
                        while not lines[i].startswith("End of ROI"):
                            dose_value, volume_value = map(float, lines[i].strip().split(":"))
                            dvh_data.append((dose_value, volume_value))
                            i += 1

                        # 創(chuàng)建一個新的DVH序列項
                        dvh_item = Dataset()
                        dvh_item.DVHType = dvh_type
                        dvh_item.DoseUnits = dose_units
                        dvh_item.DoseType = dose_type
                        dvh_item.DVHDoseScaling = dvh_dose_scaling
                        dvh_item.DVHVolumeUnits = dvh_volume_units
                        dvh_item.DVHNumberOfBins = dvh_number_of_bins
                        dvh_item.DVHMinimumDose = dvh_minimum_dose
                        dvh_item.DVHMaximumDose = dvh_maximum_dose
                        dvh_item.DVHMeanDose = dvh_mean_dose
                        dvh_item.DVHData = '\\'.join([f'{dose}\\{volume}' for dose, volume in dvh_data])

                        # 獲取Referenced ROI Number
                        referenced_roi_number = roi_number_map.get(roi_name)
                        if referenced_roi_number:
                            referenced_roi_item = Dataset()
                            referenced_roi_item.ReferencedROINumber = referenced_roi_number
                            referenced_roi_item.DVHROIContributionType = 'INCLUDED'
                            dvh_item.DVHReferencedROISequence = Sequence([referenced_roi_item])

                            # 將DVH序列項添加到DICOM文件
                            dicom_data.DVHSequence.append(dvh_item)

                    i += 1

                # 覆蓋保存修改后的RTDOSE DICOM文件
                dicom_data.save_as(dicom_file_path)

                print(f'Modified DICOM file saved to: {dicom_file_path}')

# 執(zhí)行解壓和處理功能
if __name__ == '__main__':
    unzip_files(dcm_folder)
    process_dvh_and_dcm_files(dcm_folder)

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末哈雏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子给郊,更是在濱河造成了極大的恐慌,老刑警劉巖蚤蔓,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件续膳,死亡現(xiàn)場離奇詭異,居然都是意外死亡兰粉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門顶瞳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玖姑,“玉大人,你說我怎么就攤上這事慨菱⊙媛纾” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵符喝,是天一觀的道長闪彼。 經常有香客問我,道長协饲,這世上最難降的妖魔是什么畏腕? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮茉稠,結果婚禮上描馅,老公的妹妹穿的比我還像新娘。我一直安慰自己而线,他們只是感情好流昏,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吞获,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谚鄙。 梳的紋絲不亂的頭發(fā)上各拷,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音闷营,去河邊找鬼烤黍。 笑死,一個胖子當著我的面吹牛傻盟,可吹牛的內容都是我干的速蕊。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼娘赴,長吁一口氣:“原來是場噩夢啊……” “哼规哲!你這毒婦竟也來了?” 一聲冷哼從身側響起诽表,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤唉锌,失蹤者是張志新(化名)和其女友劉穎隅肥,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袄简,經...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡腥放,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绿语。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秃症。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吕粹,靈堂內的尸體忽然破棺而出种柑,到底是詐尸還是另有隱情,我是刑警寧澤昂芜,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布莹规,位于F島的核電站,受9級特大地震影響泌神,放射性物質發(fā)生泄漏良漱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一欢际、第九天 我趴在偏房一處隱蔽的房頂上張望母市。 院中可真熱鬧,春花似錦损趋、人聲如沸患久。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒋失。三九已至,卻和暖如春桐玻,著一層夾襖步出監(jiān)牢的瞬間篙挽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工镊靴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铣卡,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓偏竟,卻偏偏與公主長得像煮落,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子踊谋,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內容