本文由Markdown語法編輯器編輯完成。
1. 需求背景
產品要進行體系認證,而體系中對影像過濾進行了一些限制。其中一條規則是,需要篩選出所有影像中年齡大於等於16歲的影像。
要注意,這裏的年齡,是患者在當時拍攝影像時的年齡,而不是患者當前的年齡。
在dicom標籤中,有一個標籤是表明患者拍攝時的年齡的,(0x0010, 0x1010) PatientAge.
但是由於這個標籤不是一類標籤,不一定存在。因此,可以根據另外兩個標籤,來計算出患者當時拍攝時的年齡。這兩個標籤是:(0x0008, 0x0020) StudyDate, (0x0010, 0x0030) PatientBirthDate. 然後根據這兩個標籤,計算出年份的差異,也就知道了患者當時拍攝時的年齡。
明確了以上的方案,就可以寫代碼來實現了。
2. 需求實現
def check_age_restriction():
patient_age_str = get_tag_values(ds, (0x0010, 0x1010), None)
if patient_age_str:
if patient_age_str.__contains__('D') or \
patient_age_str.__contains__('W') or \
patient_age_str.__contains__('M') or \
(patient_age_str.__contains__('Y') and
int(patient_age_str.split('Y')[0]) < 16):
return False
return True
patient_birthdate_str = get_tag_values(ds, (0x0010, 0x0030), None)
study_date = get_tag_values(ds, (0x0008, 0x0020), None)
series_date = get_tag_values(ds, (0x0008, 0x0021), None)
acquisition_date = get_tag_values(ds, (0x0008, 0x0022), None)
content_date = get_tag_values(ds, (0x0008, 0x0023), None)
if not patient_birthdate_str:
return True
else:
patient_birthdate = \
datetime.strptime(patient_birthdate_str, '%Y%m%d').date()
actual_study_date = datetime.strptime(
study_date or series_date or acquisition_date or
content_date, '%Y%m%d').date()
patient_age = cal_age_by_study_and_birth_date(
actual_study_date, patient_birthdate)
if patient_age < DR_CE_AGE_LOWER_LIMIT:
return False
return True
def get_tag_values(ds, tag, default=None):
"""
獲取dataset
:param ds: Dataset 待獲取對象dataset
:param tag: tuple tag十六進制數
:param default: object 缺省返回
:return: object
"""
if tag[0] == 0x0002:
val = ds.file_meta.get(tag)
else:
val = ds.get(tag, default=default)
if hasattr(val, 'value'):
val = val.value
return normalize_tag(val)
def normalize_tag(tag):
"""
把tag的值轉化爲python的內置類型
:param tag: Tag
:return: object
"""
type_map = [
('DSfloat', float),
('DSdecimal', float),
('IS', int),
('MultiString', lambda x: [normalize_tag(i) for i in x]),
('MultiValue', lambda x: [normalize_tag(i) for i in x]),
('PersonName3', str),
('PersonNameBase', str),
('PersonName', str),
('PersonNameUnicode', unicode),
]
cls_name = tag.__class__.__name__
val = dict(type_map).get(cls_name, lambda _: _)(tag)
return val
def cal_age_by_study_and_birth_date(study_date, birth_date):
if not study_date:
raise Exception("StudyDate, SeriesDate, AcquisitionDate and "
"ContentDate do not exist!")
if isinstance(study_date, date) and isinstance(birth_date, date):
return study_date.year - birth_date.year - \
((study_date.month, study_date.day) <
(birth_date.month, birth_date.day))
raise Exception("StudyDate or BirthDate is not date type.")
以下是相應的測試case:
case1:
case2:
參考鏈接:
未完待續…