import glob
import pydicom
import matplotlib.pyplot as plt
import numpy as np
import os
import multiprocessing
import threading
import time
def extractDicomFileInfo(filename):
"""
提取Dicom文件的tag信息
input :文件名
output:相关信息
"""
info = {}
dcm = pydicom.read_file(filename)
info["PatientID"] = dcm.PatientID # 患者ID
info["PatientName"] = dcm.PatientName # 患者姓名
info["PatientBirthData"] = dcm.PatientBirthData # 患者出生日期
info["PatientAge"] = dcm.PatientAge # 患者年龄
info['PatientSex'] = dcm.PatientSex # 患者性别
info['StudyID'] = dcm.StudyID # 检查ID
info['StudyDate'] = dcm.StudyDate # 检查日期
info['StudyTime'] = dcm.StudyTime # 检查时间
info['InstitutionName'] = dcm.InstitutionName # 机构名称
info['Manufacturer'] = dcm.Manufacturer # 设备制造商
info['StudyDescription'] = dcm.StudyDescription # 检查项目描述
return info
def saveAsJPGImage(img_array, jpg_path, uid, lens):
"""
格式转换函数
input : 像素矩阵,图片保存路径,uid,lens
output:
"""
plt.figure(figsize=(12,6), dpi=80) # 绘制画板
arr_temp = np.reshape(img_array, (lens,))
max_val = max(arr_temp) # 获取像素极大值
min_val = min(arr_temp) # 获取像素极小值
img_array = (img_array-min_val)/(max_val-min_val) # 像素值归一化
plt.imshow(img_array, cmap=plt.cm.bone)
plt.title("UID:{}".format(uid))
# print("saving image:{}".format(jpg_path.split('JPG图像/')[1]))
plt.savefig(jpg_path)
plt.close()
def getDicomFile(dicom_dir, jpg_dir):
"""
获取dicom文件的参数信息
input : dicom_dir,jpg_dir
output: args_list
"""
# 定位绝对路径
all_file_list = os.listdir(dicom_dir)
# 初始化args_list
args_list = []
extension = 'dcm'
for f in all_file_list:
dcm_dir = os.path.join(dicom_dir, f, 'st01', '*.' + extension)
dcm_files = glob.glob(dcm_dir)
for i, d in enumerate(dcm_files):
dicom_file_path = d
# dicom_info = extractDicomFileInfo(dicom_file_path) # 提取tag信息备用
dcm_name = os.path.basename(d) # t2640000201al.dcm
# jpg_name = jpg_dir + d
# print(jpg_name)
dcm = pydicom.read_file(dicom_file_path) # 读取dicom文件
if "PixelData" not in dcm:
print(f"Dataset found with no Pixel Data: {d}")
continue
if len(dcm.pixel_array.shape) > 2:
# 循环提取图片
for index in range(int(dcm.pixel_array.shape[0])):
# 根据dicom文件的BitAllocation显示1
img = np.asarray(dcm.pixel_array[index], dtype='uint16')
img_upload_path = os.path.join(jpg_dir, f, dcm_name.split('.d')[0], str(index) + ".png")
if not os.path.exists(os.path.join(jpg_dir, f, dcm_name.split('.d')[0])):
os.makedirs(os.path.join(jpg_dir, f, dcm_name.split('.d')[0]))
# cmap参数是重点,选择plt.cm.bone,胸片显示才会正常
plt.imsave(img_upload_path, img, cmap=plt.cm.bone)
else:
# 单图
img = np.asarray(dcm.pixel_array, dtype='uint16')
img_upload_path = os.path.join(jpg_dir, "x.png")
plt.imsave(img_upload_path, img, cmap=plt.cm.bone)
# img_array = dcm.pixel_array # 获取图像像素矩阵
# lens = img_array.shape[0]*img_array.shape[1] # 获取像素矩阵大小
# uid = dcm.SOPInstanceUID # 获取图像uid
# args_tuple = (img_array, jpg_name, uid, lens) # 添加参数tuple
# args_list.append(args_tuple)
def main():
"""
main function
"""
# 存放DICOM文件的文件夹
dicom_dir = "D:\papilla_detection\DICOM"
# dicom_dir = r'E:\scripts\dicom2png'
# 存放转换后的JPG图片的文件夹
jpg_dir = "D:\papilla_detection\PNG"
# jpg_dir = r'E:\scripts\dicom2png\png'
begin_time = time.time() # 开始时间
pool = multiprocessing.Pool(processes=5) # 创建进程池
args_list = getDicomFile(dicom_dir, jpg_dir) # 获取参数list
# pool.starmap(saveAsJPGImage, args_list) # 多进程保存jpg文件
# pool.close() # 关闭进程
end_time = time.time() # 结束时间
print("耗时:{}s".format(round(end_time-begin_time, 4))) # 打印耗时
if __name__ == '__main__':
main()
DICOM文件读取及PNG格式图片展示
于 2022-09-26 17:02:30 首次发布