Python 处理医学影像学中的DICOM

DICOMDICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信,是医学图像和相关信息的国际标准(ISO 12052)。它定义了质量能满足临床需要的可用于数据交换的医学图像格式,可用于处理、存储、打印和传输医学影像信息。DICOM可以便捷地交换于两个满足DICOM格式协议的工作站之间。目前该协议标准不仅广泛应用于大型医院,而且已成为小型诊所和牙科诊所医生办公室的标准影像阅读格式。

这里写图片描述

DICOM被广泛应用于放射医疗、心血管成像以及放射诊疗诊断设备(X射线,CT,核磁共振,超声等),并且在眼科和牙科等其它医学领域得到越来越深入广泛的应用。在数以万计的在用医学成像设备中,DICOM是部署最为广泛的医疗信息标准之一。当前大约有百亿级符合DICOM标准的医学图像用于临床使用。

目前,越来越多的DICOM应用程序和分析软件被运用于临床医学,促使越来越多的编程语言开发出支持DICOM API的框架。今天就让我来介绍一下Python语言下支持的DICOM模块,以及如何完成基本DICOM信息分析和处理的编程方法。


Pydicom


Pydicom是一个处理DICOM文件的纯Python软件包。它可以通过非常容易的“Pythonic”的方式来提取和修改DICOM数据,修改后的数据还会借此生成新的DICOM文件。作为一个纯Python包,Pydicom可以在Python解释器下任何平台运行,除了必须预先安装Numpy模块外,几乎无需其它任何配置要求。其局限性之一是无法处理压缩像素图像(如JPEG),其次是无法处理分帧动画图像(如造影电影)。

这里写图片描述


SimpleITK


Insight Segmentation and Registration Toolkit (ITK)是一个开源、跨平台的框架,可以提供给开发者增强功能的图像分析和处理套件。其中最为著名的就是SimpleITK,是一个简化版的、构建于ITK最顶层的模块。SimpleITK旨在易化图像处理流程和方法。

这里写图片描述


PIL


Python Image Library (PIL) 是在Python环境下不可缺少的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能,而且API却非常简单易用。


OpenCV


OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

这里写图片描述


下面就让我以实际Python代码来演示如何编程处理心血管冠脉造影DICOM图像信息。

1. 导入主要框架:SimpleITK、pydicom、PIL、cv2和numpy

import SimpleITK as sitk
from PIL import Image
import pydicom
import numpy as np
import cv2

2. 应用SimpleITK框架来读取DICOM文件的矩阵信息。如果DICOM图像是三维螺旋CT图像,则帧参数则代表CT扫描层数;而如果是造影动态电影图像,则帧参数就是15帧/秒的电影图像帧数。

def loadFile(filename):ds = sitk.ReadImage(filename)img_array = sitk.GetArrayFromImage(ds)frame_num, width, height = img_array.shapereturn img_array, frame_num, width, height

3. 应用pydicom来提取患者信息。

def loadFileInformation(filename):information = {}ds = pydicom.read_file(filename)    information['PatientID'] = ds.PatientIDinformation['PatientName'] = ds.PatientNameinformation['PatientBirthDate'] = ds.PatientBirthDateinformation['PatientSex'] = ds.PatientSexinformation['StudyID'] = ds.StudyIDinformation['StudyDate'] = ds.StudyDateinformation['StudyTime'] = ds.StudyTimeinformation['InstitutionName'] = ds.InstitutionNameinformation['Manufacturer'] = ds.Manufacturerinformation['NumberOfFrames'] = ds.NumberOfFrames    return information

4. 应用PIL来检查图像是否被提取。

def showImage(img_array, frame_num = 0):img_bitmap = Image.fromarray(img_array[frame_num])return img_bitmap

5. 采用CLAHE (Contrast Limited Adaptive Histogram Equalization)技术来优化图像。

def limitedEqualize(img_array, limit = 4.0):img_array_list = []for img in img_array:clahe = cv2.createCLAHE(clipLimit = limit, tileGridSize = (8,8))img_array_list.append(clahe.apply(img))img_array_limited_equalized = np.array(img_array_list)return img_array_limited_equalized

这一步对于整个图像处理起到很重要的作用,可以根据不同的原始DICOM图像的窗位和窗宽来进行动态调整,以达到最佳的识别效果。

最后应用OpenCV的Python框架cv2把每帧图像组合在一起,生成通用视频格式。

def writeVideo(img_array):frame_num, width, height = img_array.shapefilename_output = filename.split('.')[0] + '.avi'    video = cv2.VideoWriter(filename_output, -1, 16, (width, height))    for img in img_array:video.write(img)video.release()

VTK加载DICOM数据


import vtk  
from vtk.util import numpy_support  
import numpy  PathDicom = "./dir_with_dicom_files/"  
reader = vtk.vtkDICOMImageReader()  
reader.SetDirectoryName(PathDicom)  
reader.Update()  # Load dimensions using `GetDataExtent`  
_extent = reader.GetDataExtent()  
ConstPixelDims = [_extent[1]-_extent[0]+1, _extent[3]-_extent[2]+1, _extent[5]-_extent[4]+1]  # Load spacing values  
ConstPixelSpacing = reader.GetPixelSpacing()  # Get the 'vtkImageData' object from the reader  
imageData = reader.GetOutput()  
# Get the 'vtkPointData' object from the 'vtkImageData' object  
pointData = imageData.GetPointData()  
# Ensure that only one array exists within the 'vtkPointData' object  
assert (pointData.GetNumberOfArrays()==1)  
# Get the `vtkArray` (or whatever derived type) which is needed for the `numpy_support.vtk_to_numpy` function  
arrayData = pointData.GetArray(0)  # Convert the `vtkArray` to a NumPy array  
ArrayDicom = numpy_support.vtk_to_numpy(arrayData)  
# Reshape the NumPy array to 3D using 'ConstPixelDims' as a 'shape'  
ArrayDicom = ArrayDicom.reshape(ConstPixelDims, order='F')  

PYDICOM加载DICOM数据:
可以在https://github.com/darcymason/pydicom的test里面看怎么用代码。


import dicom  
import os  
import numpy  PathDicom = "./dir_with_dicom_series/"  
lstFilesDCM = []  # create an empty list  
for dirName, subdirList, fileList in os.walk(PathDicom):  for filename in fileList:  if ".dcm" in filename.lower():  # check whether the file's DICOM  lstFilesDCM.append(os.path.join(dirName,filename))  # Get ref file  
RefDs = dicom.read_file(lstFilesDCM[0])  # Load dimensions based on the number of rows, columns, and slices (along the Z axis)  
ConstPixelDims = (int(RefDs.Rows), int(RefDs.Columns), len(lstFilesDCM))  # Load spacing values (in mm)  
ConstPixelSpacing = (float(RefDs.PixelSpacing[0]), float(RefDs.PixelSpacing[1]), float(RefDs.SliceThickness))  # The array is sized based on 'ConstPixelDims'  
ArrayDicom = numpy.zeros(ConstPixelDims, dtype=RefDs.pixel_array.dtype)  # loop through all the DICOM files  
for filenameDCM in lstFilesDCM:  # read the file  ds = dicom.read_file(filenameDCM)  # store the raw image data  ArrayDicom[:, :, lstFilesDCM.index(filenameDCM)] = ds.pixel_array  

转换VTK built-in types to SimpleITK/ITK built-ins and vice-versa


import vtk  
import SimpleITK  dctITKtoVTK = {SimpleITK.sitkInt8: vtk.VTK_TYPE_INT8,  SimpleITK.sitkInt16: vtk.VTK_TYPE_INT16,  SimpleITK.sitkInt32: vtk.VTK_TYPE_INT32,  SimpleITK.sitkInt64: vtk.VTK_TYPE_INT64,  SimpleITK.sitkUInt8: vtk.VTK_TYPE_UINT8,  SimpleITK.sitkUInt16: vtk.VTK_TYPE_UINT16,  SimpleITK.sitkUInt32: vtk.VTK_TYPE_UINT32,  SimpleITK.sitkUInt64: vtk.VTK_TYPE_UINT64,  SimpleITK.sitkFloat32: vtk.VTK_TYPE_FLOAT32,  SimpleITK.sitkFloat64: vtk.VTK_TYPE_FLOAT64}  
dctVTKtoITK = dict(zip(dctITKtoVTK.values(),   dctITKtoVTK.keys()))  def convertTypeITKtoVTK(typeITK):  if typeITK in dctITKtoVTK:  return dctITKtoVTK[typeITK]  else:  raise ValueError("Type not supported")  def convertTypeVTKtoITK(typeVTK):  if typeVTK in dctVTKtoITK:  return dctVTKtoITK[typeVTK]  else:  raise ValueError("Type not supported")  

VTK-SimpleITK绘制数据


#!/usr/bin/python  import SimpleITK as sitk  
import vtk  
import numpy as np  from vtk.util.vtkConstants import *  def numpy2VTK(img,spacing=[1.0,1.0,1.0]):  # evolved from code from Stou S.,  # on http://www.siafoo.net/snippet/314  importer = vtk.vtkImageImport()  img_data = img.astype('uint8')  img_string = img_data.tostring() # type short  dim = img.shape  importer.CopyImportVoidPointer(img_string, len(img_string))  importer.SetDataScalarType(VTK_UNSIGNED_CHAR)  importer.SetNumberOfScalarComponents(1)  extent = importer.GetDataExtent()  importer.SetDataExtent(extent[0], extent[0] + dim[2] - 1,  extent[2], extent[2] + dim[1] - 1,  extent[4], extent[4] + dim[0] - 1)  importer.SetWholeExtent(extent[0], extent[0] + dim[2] - 1,  extent[2], extent[2] + dim[1] - 1,  extent[4], extent[4] + dim[0] - 1)  importer.SetDataSpacing( spacing[0], spacing[1], spacing[2])  importer.SetDataOrigin( 0,0,0 )  return importer  def volumeRender(img, tf=[],spacing=[1.0,1.0,1.0]):  importer = numpy2VTK(img,spacing)  # Transfer Functions  opacity_tf = vtk.vtkPiecewiseFunction()  color_tf = vtk.vtkColorTransferFunction()  if len(tf) == 0:  tf.append([img.min(),0,0,0,0])  tf.append([img.max(),1,1,1,1])  for p in tf:  color_tf.AddRGBPoint(p[0], p[1], p[2], p[3])  opacity_tf.AddPoint(p[0], p[4])  # working on the GPU  # volMapper = vtk.vtkGPUVolumeRayCastMapper()  # volMapper.SetInputConnection(importer.GetOutputPort())  # # The property describes how the data will look  # volProperty =  vtk.vtkVolumeProperty()  # volProperty.SetColor(color_tf)  # volProperty.SetScalarOpacity(opacity_tf)  # volProperty.ShadeOn()  # volProperty.SetInterpolationTypeToLinear()  # working on the CPU  volMapper = vtk.vtkVolumeRayCastMapper()  compositeFunction = vtk.vtkVolumeRayCastCompositeFunction()  compositeFunction.SetCompositeMethodToInterpolateFirst()  volMapper.SetVolumeRayCastFunction(compositeFunction)  volMapper.SetInputConnection(importer.GetOutputPort())  # The property describes how the data will look  volProperty =  vtk.vtkVolumeProperty()  volProperty.SetColor(color_tf)  volProperty.SetScalarOpacity(opacity_tf)  volProperty.ShadeOn()  volProperty.SetInterpolationTypeToLinear()  # Do the lines below speed things up?  # pix_diag = 5.0  # volMapper.SetSampleDistance(pix_diag / 5.0)      # volProperty.SetScalarOpacityUnitDistance(pix_diag)   vol = vtk.vtkVolume()  vol.SetMapper(volMapper)  vol.SetProperty(volProperty)  return [vol]  def vtk_basic( actors ):  """ Create a window, renderer, interactor, add the actors and start the thing Parameters ---------- actors :  list of vtkActors Returns ------- nothing """       # create a rendering window and renderer  ren = vtk.vtkRenderer()  renWin = vtk.vtkRenderWindow()  renWin.AddRenderer(ren)  renWin.SetSize(600,600)  # ren.SetBackground( 1, 1, 1)  # create a renderwindowinteractor  iren = vtk.vtkRenderWindowInteractor()  iren.SetRenderWindow(renWin)  for a in actors:  # assign actor to the renderer  ren.AddActor(a )  # render  renWin.Render()  # enable user interface interactor  iren.Initialize()  iren.Start()  #####  filename = 'toto.nii.gz'  img = sitk.ReadImage( filename ) # SimpleITK object  
data = sitk.GetArrayFromImage( img ) # numpy array  from scipy.stats.mstats import mquantiles  
q = mquantiles(data.flatten(),[0.7,0.98])  
q[0]=max(q[0],1)  
q[1] = max(q[1],1)  
tf=[[0,0,0,0,0],[q[0],0,0,0,0],[q[1],1,1,1,0.5],[data.max(),1,1,1,1]]  actor_list = volumeRender(data, tf=tf, spacing=img.GetSpacing())  vtk_basic(actor_list)  

下面一个不错的软件:
https://github.com/bastula/dicompyler
还有一个python的库mudicom,https://github.com/neurosnap/mudicom


import mudicom  
mu = mudicom.load("mudicom/tests/dicoms/ex1.dcm")  # returns array of data elements as dicts  
mu.read()  # returns dict of errors and warnings for DICOM  
mu.validate()  # basic anonymization  
mu.anonymize()  
# save anonymization  
mu.save_as("dicom.dcm")  # creates image object  
img = mu.image # before v0.1.0 this was mu.image()  
# returns numpy array  
img.numpy # before v0.1.0 this was mu.numpy()  # using Pillow, saves DICOM image  
img.save_as_pil("ex1.jpg")  
# using matplotlib, saves DICOM image  
img.save_as_plt("ex1_2.jpg")  

本文转自:

http://mp.weixin.qq.com/s?__biz=MzAxOTk4NTIwMw==&mid=2247483968&idx=1&sn=2844930d81f3e1f45260338dae21d8ea&chksm=9c3fe41cab486d0aa9d03a6494865c0ffdbb0e878f4804227a73d2d403382432fe22e9c03b71&mpshare=1&scene=23&srcid=0122xHKRmyLclSvbojaS1ICX##

http://blog.csdn.net/langb2014/article/details/54667905#

http://www.jianshu.com/p/df64088e9b6b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CNN的性别、年龄识别及Demo实现

一、相关理论 本篇博文主要讲解2015年一篇paper《Age and Gender Classification using Convolutional Neural Networks》paper的创新点在哪里。难道是因为利用CNN做年龄和性别分类的paper很少吗?网上搜索了一下,性别预测,以前很多都是用SVM算…

Faster R-CNN的安装及测试(Python版本和Matlab版本)

rbg的Python版本 一、拉取源码 git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git 拉取完成后,在/home/cmwang/目录下增加了py-faster-rcnn文件夹【cmwang是我的ubuntu用户名】 二、安装依赖 sudo apt-get install python-opencvsudo pip…

2016 亚洲共识指南:肺结节的评估

2016 年 2 月,亚洲肺部疾病和胸外科多学科专家小组在美国胸科医师学会(ACCP)制定的肺结节评估指南的基础上结合亚洲患者的自身特点制订了亚洲肺结节患者的评估指南。 亚洲肺结节的评估与 APCC 指南中所指出的重要注意事项大致相同。但该指南…

Ubuntu 15.04 安装TensorFlow(源码编译) 及测试梵高作画

介绍Google的TensorFlow机器学习开源库,在UbuntuKylin上的安装和和源码编译。 原始官方文档参见:http://www.tensorflow.org. 本电脑配置如下: 3.19.0-15-generic #15-Ubuntu x86_64 GNU/Linux NVIDIA Corporation GK110BGL [Tesla K40c] …

Ubuntu SSH Algorithm negotiation failed

问题 解决方法 chmod 777 /etc/ssh/sshd_configgedit /etc/ssh/sshd_config添加如下 Ciphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3des-cbc,arcfour128,arcfour256,arcfour,blowfish-cbc,cast128-cbcMACs hmac-md5,hmac-sha1,umac-64openssh.…

不同matlab版本所支持的gcc g+版本

问题 关于 GCC 和 G 版本问题 Matlab 2014a gcc/g 4.7.x, Matlab 2016a gcc/g 4.9.x Matlab 2017a gcc/g 4.9.x Ubuntu 15.04 gcc/g 4.9.x, Ubuntu 16.04 gcc/g 5.4.x 原则上Matlab需要和Ubuntu版本一致,由于CUDA 8只支持16.04,而且需要GCC 5.4.x 进行编译&#…

Linux 终端配置

一般Linux中的配置文件大多以点开头,而且多以rc结尾。比如vim的配置文件 .vimrc,bash shell的配置文件.bashrc,等等。 像这样的配置文件,如果用ls -l命令是列不出来的,需要用ls -a来列出。 “rc”,它是“…

caffe2 介绍

Caffe2的特性 Caffe2框架可以通过一台机器上的多个GPU或具有一个及多个GPU的多台机器来进行分布式训练。 也可以在iOS系统、Android系统和树莓派(Raspberry Pi)上训练和部署模型。只需要运行几行代码即可调用Caffe2中预先训练好的Model Zoo模型。Caffe2…

Python 中的numpy 库

待总结 用scikit-learn和pandas学习线性回归 用scikit-learn和pandas学习Ridge回归 待整理的 Numpy & Pandas numpy——主要对其 N 维数组对象有用 http://www.numpy.org/ Pandas数据转为 numpy数据 df_numpyMatrix df.as_matrix() df_numpyMatrixdf.values a([3.23…

Python 中的Pandas库

待总结 用scikit-learn和pandas学习线性回归 用scikit-learn和pandas学习Ridge回归 基于python的数据分析库Pandas pandas——Python 数据分析库,包括数据框架(dataframes)等结构 http://pandas.pydata.org/ 10 Minutes to Pandas&#…

weka和matlab完成完整分类实验

本文 本文简单介绍数据集介绍、weka的使用、weka与LIBSVM、matlab与LIBSVM以及分类的若干细节问题。 1. 数据集介绍 打开网址UCI数据集,如下图。 从右下角可以看到Iris这个数据集,这是使用最多的数据集,目前下载量超过了82万。 打开之后跳…

Python 中的绘图matplotlib mayavi库

python matplotlib 图像可视化 python-data-visualization-course Interactive Web Plotting for Python Interactive Web Plotting for Python-github 待整理的 Matplotlib Introduction to Matplotlib and basic line matplotlib——一个 2D 绘图库,可产生…

ubuntu 16.04 配置Python2.7 和 Python3.5 同时调用OpenCV

安装OpenCV OpenCV 官网,下载见 SourceForge and GitHub。 若使用官网版本安装不成功,则可试试Github版本。 或者 git clone https://github.com/Itseez/opencv.git 安装依赖库 sudo apt-get -y install libopencv-dev sudo apt-get -y install bui…

生成特定分布随机数的方法:Python seed() 函数numpy scikit-learn随机数据生成

描述 seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数。。 语法 以下是 seed() 方法的语法: import random random.seed ( [x] ) 注意:seed(()是不能直接访问的,需要导入 random 模块,然后通过 ra…

scipy.ndimage.zoom上采样与下采样

插值 Bilinear interpolation would be order1, nearest is order0, and cubic is the default (order3). 举例说明 import numpy as np import scipy.ndimagex np.arange(64).reshape(8,8)print Original array: print xprint Resampled by a factor of 2 with nearest i…

UFLDL教程: Exercise: Sparse Autoencoder

自编码可以跟PCA 一样,给特征属性降维 一些matlab函数 bsxfun:Cbsxfun(fun,A,B)表达的是两个数组A和B间元素的二值操作,fun是函数句柄或者m文件,或者是内嵌的函数。在实际使用过程中fun有很多选择比如说加,减等,前面需…

UFLDL教程:Exercise:PCA in 2D PCA and Whitening

相关文章 PCA的原理及MATLAB实现 UFLDL教程:Exercise:PCA in 2D & PCA and Whitening python-A comparison of various Robust PCA implementations Deep Learning and Unsupervised Feature Learning Tutorial Solutions 统计学的基本概念 统计学里最基本…

UFLDL教程:Exercise:Softmax Regression

Softmax分类函数的Python实现 Deep Learning and Unsupervised Feature Learning Tutorial Solutions 逻辑回归假设函数 在线性回归问题中,假设函数具有如下形式: 在 logistic 回归中,我们的训练集由m 个已标记的样本构成:&#…

UFLDL教程: Exercise:Self-Taught Learning

自我学习 Deep Learning and Unsupervised Feature Learning Tutorial Solutions 1.先训练稀疏自编码器提取特征,再把特征和label给softmax分类器进行训练,最后用test数据集进行测试。 2.由于实际应用中找到大量有标注的样本是非常困难的,所…

UFLDL教程: Exercise: Implement deep networks for digit classification

Deep networks Deep Learning and Unsupervised Feature Learning Tutorial Solutions 深度网络的优势 比单层神经网络能学习到更复杂的表达。不同层的网络学习到的特征是由最底层到最高层慢慢上升的。比如在图像的学习中,第一个隐含层网络可能学习的是边缘特征&am…