医学图像预处理(一)——读取图片(dcm,nii,PIL,skimage,cv2)

总结一下目前遇到的一些医学图像预处理步骤,但才开始自学两周,所以很多东西或许不对或者不全面,以后争取每两周回顾以前的文章,将内容完善,并提高质量。(2019-3-5)
由于篇幅原因,将预处理的步骤分开来,这一篇将总结读取图片的方法
2019/7/7更新,写在最前:关于图片读取出来宽、高顺序问题
(文中nii读取图片那节也有提到图片读取出来的w,h先后问题。)
有这样的疑问是看得多了之后发现有时候图片是(height, width),有时候又是(width, height)
特别是训练网络,有时候宽高一样,弄反了也没有什么影响。
下面是进行的测验,先直接说结论
对于屏幕坐标而言,(x,y)=(0,0)位于左上角,x代表width,即column,y代表height,即row
因此,图片原生的表示,应该是(width,height),这也是电脑编辑图片能看到的分辨率格式 但由于图片的储存形式为矩阵,而对于矩阵,
我们熟悉的都是row first(一般的数学概念上都会是row first),所以说在涉及到具体操作时,
还是将图片转化为(height, width)比较方便,因为index时[i-th row][j-th column]也就对应着(height, width)。
这也是下面例子中,原生格式为(w,h)转化为numpy数组后,就自动变成了(h,w)
(顺带一提,对于point而言,则不会有这种变化,因此opencv中画点还是(x,y)即(col,raw),
画矩阵或图片就得变化一下)

import cv2
from PIL import Image
import numpy as np
from skimage.io import  imread

filepath = './liver.jpg'

cv2_im = cv2.imread(filepath)
print('cv2_im shape ',cv2_im.shape) # (height, width, ch)

im = Image.open(filepath)
print('PIL image size', im.size) # (width, height, ch)
pil_im = np.asarray(im)
print('pil_im shape ',pil_im.shape) # (height, width, ch)

sk_im = imread(filepath)
print('sk_im shape', sk_im.shape) # (height, width, ch)

# pydicom: dcm_slice = pydicom.dcmread(filename)
#          slice_data = dcm_slice.pixel_array   shape:(height, width)
#          若想更改原始像素size或其他操作,必须写回至原始二进制属性PixelData 中
#          dcm_slice.PixelData = dcm_slice.pixel_array.tobytes()
# SimpleITK: itk_im = sitk.ReadImage()  size:(width, height, depth)
#            np_im = sitk.GetArrayFromImage(itk_im) shape:(depth, height, width)

读取DICOM格式

用到的包:pydicom

例如,以公共数据集3Dircadb为例,其文件组织如下:
在这里插入图片描述
其中3Dircadb1.1代表病人1.1号,PATIENT_DICOM是病人腹部切面,LABELED_DICOM 是标记了不同部位的切片,MASKS_DICOM下面又有子文件夹,分别是不同部位的mask。所有的图片都是灰度图像。

读取dicom文件

label_path = '~/Downloads/3Dircadb/3Dircadb1.1/LABELLED_DICOM'
# 若不遍历读出,则获得的是单张切片,而非三维图片
slices = [pydicom.dcmread(label_path + '/' + s) for s in os.listdir(label_path)]
slices.sort(key = lambda x: int(x.InstanceNumber))
# slice[i]为pydicom.dataset.FileDataset,储存了切片相关的信息
# .pixel_array用来获取像素信息,每张切片都是灰度图
#2019-6-5更新:s.pixel_array.shape:(height,width)
image = np.stack([s.pixel_array for s in slices])
image = image.astype(np.int16)
# 目前还不知道这些label值对应的器官分别是什么?
np.unique(image)
#array([  0,   1,  17,  33,  65,  97, 129, 193, 257, 321, 385, 449, 451,
#       453, 465, 481, 513], dtype=int16)
label_path = '~/Downloads/3Dircadb/3Dircadb1.1/MASKS_DICOM/artery'
slices = [pydicom.dcmread(label_path + '/' + s) for s in os.listdir(label_path)]
slices.sort(key = lambda x: int(x.InstanceNumber))
image = np.stack([s.pixel_array for s in slices])
image = image.astype(np.int16)
np.unique(image)
# array([  0, 255], dtype=int16)

读取普通的图片

用到的包 PIL,cv2, skimage
注意它们读取出的格式有细微的区别

图片通道 格式
PIL RGB Image channel_last
cv2 BGR array channel_last
skimage RGB array channel_last

还需要注意,对于opencv来说,无论读取灰度图还是彩图都是(H,W,3)的shape,灰度图的读取会把单通道复制三遍。因此,读取灰度图时得显示声明img = cv2.imread('gray.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)或者img = cv2.imread('gray.jpg',0)其中0代表灰度图,1代表彩图,读出来的shape为(H,W)

案例一:skimage读取图片

下面使kaggle竞赛的一个数据集,数据集为超声波灰度图像。


import os
import numpy as np

from skimage.io import imsave, imread

data_path = '~/kaggle_Ultrasound'

image_rows = 420
image_cols = 580

train_data_path = os.path.join(data_path, 'train')
images = os.listdir(trai
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值