本文由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:
参考链接:
未完待续…