医学图像处理
- opencv批量分片高像素图像
- 病理图像色彩特征提取
- 基于 imgaug、skimage 实现色彩增强
- 基于 Cycle-GAN 完成染色标准化
- 病理图像细微特征提取
- 自动数据标注
- 分类场景下的医学图像分析
- 分割场景下的医学图像分析
- 检测场景下的医学图像分析
, i ] k 8 + = < * I
opencv批量分片高像素图像
医学图像通常是大像素(1920x1080)、超大像素(4096x2160)。
深度学习输入数据尺寸通常是 640x640、32x32。
所以我们会切分医学图像, 变成小像素片, 并对每一个方片识别或预测。
星辰图和病理图类似:
- 星辰和病灶细胞一样,可能分布在图像各个位置,也可以集中在图像上的某个区域
- 而且都非常小,可能不到图的1%
方片尺寸最小是1x1
, 一般我们用50x50
。
怎么实现这种分割呢?
- 选定截取区域
- 截取保存
# 截取图像[高的起点:高的终点,宽的起点:宽的终点],并保存
cv2.imwrite(os.path.join(path, "1.jpg"), imgcopy[0:1200,0:1200]
每个方片尺寸为 50*50,左上角第一个被切分的方片索引为 imgcopy[:50, :50],紧接着左数第二个方片的索引为 imgcopy[:50,50:100],第三个方片索引为 imgcopy[:50,100:150],第一行所有方片被表示为 ingcopy[:50, x:x+50]。
只要在宽度上循环,每次让宽的起点增加50,宽的终点增加50,就可以做第一行的截取。
imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy # 每次分割前,获取完整的原始图像imgheight = imgcopy.shape[0] # 获取高度
imgwidth = imgcopy.shape[1] # 获取宽度patch_height = 50 # 方片尺寸50*50
patch_weight = 50for y in range(0, imgheight, patch_height): # y 是高的起点for x in range(0, imgwidth, patch_weight): # x 是宽的起点if patch_height > imgheight or patch_weight > imgwidth: # 边界判断,如果图片小于截取尺寸取消break y_ = y + patch_heightx_ = x + patch_weightif imgheight >= y_ and imgwidth >= x_: # 如果图片已经被截取到连50都到不得了,这部分就舍去,不影响patch = imgcopy[y:y_, x:x_]cv2.imwrite(os.path.join(path, "x"+str(x)+"_"+str(x_)+"y"+str(y)+"_"+str(y_)+".jpg"), patch)# 保存截取图像cv2.rectangle(imgcopy, (x,y), (x_,y_),(255,255,255),2) # 把刚刚截取区域在原图上用白色矩形圈出来
分割后。读取大批量文件:
def load_images_from_folder(folder): # 批量读取文件夹中的图片images = [] # 把所有方片保存在列表for filename in os.listdir(folder):img = cv2.imread(os.path.join(folder, filename))if img is not None:images.append(img)return imagesimages = load_images_from_folder("分割文件夹路径")
完整代码:
import cv2
import os
import matplotlib.pyplot as pltpath = r"文件夹路径"
img = cv2.imread(os.path.join(path, "图片名字.jpg"))if img is None:print("opencv读取图像时,没有成功也不会报错")else:print("读取图像成功")imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy # 将BGR颜色空间的图像转换为RGB颜色空间,并创建一个副本以供后续使用。每次分割前,获取完整的原始图像def extract_images_from_folder(folder):"""对图像进行批量分片(对一个文件夹中所有的图像进行分片)"""# 图像导入for filename in os.listdir(folder):img = cv2.imread(os.path.join(folder, filename))if img is not None:# 如果导入成功,则创建该图片专属的文件夹subfolder = os.path.join(PATH,filename.split(".")[0])if os.path.exists(subfolder):print("folder exists")else:os.mkdir(subfolder)# 开始分割,所有被分割出的切片都位于该图片的文件夹中imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy()imgheight = imgcopy.shape[0]imgwidth = imgcopy.shape[1]patch_height = 50patch_weight = 50for y in range(0, imgheight, patch_height):for x in range(0, imgwidth, patch_weight):if patch_height > imgheight or patch_weight > imgwidth:breaky_ = y + patch_heightx_ = x + patch_weightif imgheight >= y_ and imgwidth >= x_:patch = imgcopy[y:y_, x:x_]# 将每一张图像保存到单独的文件夹cv2.imwrite(os.path.join(subfolder,str(filename.split(".")[0])+"x"+str(x)+"_"+str(x_)+"y"+str(y)+"_"+ str(y_) +".jpg"), patch)# 保存之后,在原始图像上对当前索引出的区域绘制白色边框# 注意这一操作将会在正在被切片的图像上进行cv2.rectangle(imgcopy # 要绘制长方体的对象, (x, y), (x_, y_) # 绘制长方体的4角的坐标, (255, 255, 255) # 使用的颜色, 2 # 线条的粗细,数字越大越粗)#循环完毕后,绘制被我们分割后的图像 plt.figure(dpi=300)plt.imshow(imgcopy)plt.axis("off");extract_images_from_folder(PATH)
使用函数 load_images_from_folder
和 extract_images_from_folder
对任意图像进行批量分割处理了。
病理图像色彩特征提取
不同类型的图像需要使用不同的预处理和增强方式,主要是因为不同图像成像过程存在的干扰因素是大不相同的。
对高像素图像进行分片解释医疗特有的预处理方式。读这个领域数据处理和数据增强的论文,找出有用的方法。
恶性病灶原色往往比良性病灶越深。所以色彩差异是神经网络需要学习的一大关键点。
但是模态太多,不同实验室、不同专业人员、不同批次染色剂、不同扫描仪、不同玻片原材料、不同组织对颜色的响应程度等因素而引起的颜色差异,影响学习效果
病理图像的预处理方式、增强:排除染色操作干扰,提升模型泛化能力。
色彩的本质是明度,灰度图也有明度差异,彩色图像的丰富信息要最大程度保留。
具体方向:
- 色彩增强:训练集覆盖尽可能多的色彩
- 色彩多样化:把所有图像(训练集和测试集)进行色彩标准化,让所有图像尽量在色彩上一致
- 超精细化提取,而非多尺度提取
具体手段:
- 随机仿射变换:随机移动、随机旋转、随机拉伸、随机透视等
- 随机噪声:高斯噪声、脉冲噪声、散粒噪声等
- 随机线性变换:随机亮度、随机对比度、随机色相、随机饱和度、随机色温
- 改变色彩空间:RGB-HSV、基于反卷积的RGB-H&E、RGB-HED等
- 针对单通道的随机线性变换(随机加减乘除、随机调整亮度和对比度)
- 色彩均衡、自动对比度、随机翻转、随机剪裁或填充
参考论文:
- 为H&E染色的组织病理学定制自动数据增强
- HE染色增强改进了用于组织病理学有丝分裂检测的卷积网络的泛化
基于 imgaug、skimage 实现色彩增强
色彩匹配和染色分裂的问题:目标图像与现有标准化的数据差异过大
基于 Cycle-GAN 完成染色标准化
生成对抗网络:借助真实数据生成一组假数据训练网络,输出一组以假乱真的数据
先把彩图灰度化,把灰度图输入生成器,生成彩色图像,用生成彩色图像和原来彩色图像进行判别,在对抗的过程中,让俩者越来越接近
参考论文:
- 使用 GAN 处理组织病理学图像的神经染色式迁移学习