使用 Mask R-CNN 进行血细胞分割

news2024/11/26 3:24:28

介绍

血细胞分析是诊断各种医学疾病的重要步骤,从感染和贫血到更严重的疾病如白血病。传统上,这一过程是通过老方法进行的——实验室技术员通过显微镜查看血涂片玻片,花费几个小时。这一过程不仅令人乏味,还容易出现人为错误,尤其是在处理大量样本或复杂病例时。

难怪医疗专业人员一直渴望自动化这一重要分析。借助计算机视觉和深度学习算法的力量,我们可以以更高的准确性和效率处理血细胞检查。一项改变这一应用的技术是图像分割——本质上是从图像的周围区域中挑选出并分离单个细胞。

目录

  1. 图像分割与 Mask R-CNN

  2. Mask R-CNN 简介及其在实例分割中的作用

  3. Mask R-CNN 架构和关键组件概述

  4. 使用 Mask R-CNN 实现血细胞分割

  • 步骤1. 导入依赖项

  • 步骤2. 设置种子

  • 步骤3. 定义文件路径

  • 步骤4. 定义自定义数据集类

  • 步骤5. 创建 DataLoader

  • 步骤6. 定义和修改模型

  • 步骤7. 训练模型

  • 步骤8. 评估模型

  • 步骤9. 计算交并比(IoU)

  1. 与其他技术的比较

  2. 结论

图像分割与 Mask R-CNN

图像分割涉及将图像分成几个片段或区域,每个片段或区域代表图像中单独的对象或对象的一部分。此过程对于获取有价值的数据和理解图像的内容至关重要。语义分割和实例分割是分割的两个基本类别。

  • 语义分割:语义分割为图像中的每个像素分配一个类标签,而不区分同一类的不同实例。

  • 实例分割:实例分割为像素分配类标签,这有助于区分同一类的许多实例。

c93913ca982345dae84eccd653651428.png

图像分割的应用多种多样,包括医学成像(如肿瘤检测和器官描绘)到自动驾驶(识别和跟踪行人和车辆等物体)、卫星图像(土地覆盖分类)和增强现实。

Mask R-CNN 简介及其在实例分割中的作用

现代深度学习模型(如 Mask R-CNN(基于掩码区域的卷积神经网络))用于处理实例分割。它在每个感兴趣区域(RoI)上增加了分割掩码预测分支,扩展了用于对象检测的Faster R-CNN模型。通过这一新增强,Mask R-CNN现在可以通过检测图像中的对象并为每个对象生成像素级的掩码来实现实例分割。

Mask R-CNN是一种在需要精确对象边界的应用中非常成功的方法,例如在医学影像中分割血液样本中的不同类型细胞。它在正确识别和勾画图像中的特定对象方面表现出色。

Mask R-CNN 架构和关键组件概述

Mask R-CNN 架构建立在 Faster R-CNN 框架之上,并包含几个关键组件:

  • 主干网络:通常为深度卷积神经网络(例如 ResNet 或 ResNeXt),充当特征提取器。该网络处理输入图像并生成特征图。

  • 区域提议网络 (RPN):此组件生成区域提议,即特征图中可能包含对象的潜在区域。RPN 是一个轻量级神经网络,可输出这些区域的边界框和对象性分数。

  • RoI Align:对 RoI Pooling 的改进,RoI Align 通过避免量化问题,准确地从建议的感兴趣区域中提取特征,确保特征的精确对齐。

  • 边界框头:一个完全连接的网络,采用 RoI 特征并执行对象分类和边界框回归以细化初始区域提议。

  • Mask Head:一个小型卷积网络,采用 RoI 特征并预测每个对象的二进制掩码,在像素级别对对象进行分割。

e4421bf5a6a669160bbb0c01838ed4fc.png

这些组件的集成使 Mask R-CNN 能够有效检测物体并生成高质量的分割蒙版,使其成为执行详细而准确的实例分割任务的强大工具。血细胞分割等医疗应用尤其受益于此架构,其中精确的物体边界对于准确分析和诊断至关重要。

使用 Mask R-CNN 实现血细胞分割

现在让我们实现 Mask RCNN 进行血细胞分割。

步骤1. 导入依赖项
import os
import torch
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import Compose, ToTensor, Resize
from torchvision.models.detection import maskrcnn_resnet50_fpn
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection.mask_rcnn import MaskRCNNPredictor
步骤2. 设置种子

设置种子将确保我们每次运行代码时都会获得相同的随机生成。

seed = 42
np.random.seed(seed)
torch.manual_seed(seed)
步骤3. 定义文件路径

初始化图像路径和用于检索图像的目标(掩码)。

images_dir = '/content/images_BloodCellSegmentation'
targets_dir = '/content/targets_BloodCellSegmentation'
步骤4. 定义自定义数据集类

BloodCellSegDataset:创建一个自定义数据集类,用于加载和预处理血细胞图像及其掩模。

init此构造函数通过列出所有图像文件名,并为图像和蒙版构建完整路径来初始化数据集。

getitem该函数加载

  • 图像及其掩码,对掩码进行预处理以创建二进制掩码

  • 计算边界框

  • 调整图像和蒙版的大小

  • 应用转换。

len此函数返回数据集中的图像总数。

class BloodCellSegDataset(Dataset):
    def __init__(self, images_dir, masks_dir):
        self.image_names = os.listdir(images_dir)
        self.images_paths = [os.path.join(images_dir, image_name) for image_name in self.image_names]
        self.masks_paths = [os.path.join(masks_dir, image_name.split('.')[0] + '.png') for image_name in self.image_names]
    def __getitem__(self, idx):
        image = Image.open(self.images_paths[idx])
        mask = Image.open(self.masks_paths[idx])
        mask = np.array(mask)
        mask = ((mask == 128) | (mask == 255))
        get_x = (mask.sum(axis=0) > 0).astype(int)
        get_y = (mask.sum(axis=1) > 0).astype(int)
        x1, x2 = get_x.argmax(), get_x.shape[0] - get_x[::-1].argmax()
        y1, y2 = get_y.argmax(), get_y.shape[0] - get_y[::-1].argmax()
        boxes = torch.as_tensor([[x1, y1, x2, y2]], dtype=torch.float32)
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
        mask = Image.fromarray(mask)
        label = torch.ones((1,), dtype=torch.int64)
        image_id = torch.tensor([idx])
        iscrowd = torch.zeros((1,), dtype=torch.int64)
        transform = Compose([Resize(224), ToTensor()])
        boxes *= (224 / image.size[0])
        image = transform(image)
        mask = transform(mask)

        target = {'masks': mask, 'labels': label, 'boxes': boxes, "image_id": image_id, "area": area, "iscrowd": iscrowd}
        return image, target
    def __len__(self):
        return len(self.image_names)
步骤5. 创建DataLoader

collate_fn:此函数用于处理批量数据,确保格式正确。

DataLoader:用于创建 pytorch 数据加载器

  • 处理批处理

  • 改组

  • 并行加载数据。

def collate_fn(batch):
    return tuple(zip(*batch))
dataset = BloodCellSegDataset(images_dir, targets_dir)
data_loader = DataLoader(dataset, batch_size=8, num_workers=2, shuffle=True, collate_fn=collate_fn)
步骤6. 定义和修改模型

maskrcnn_resnet50_fpn:这将加载一个预先训练的 Mask R-CNN 模型,该模型具有 ResNet-50 主干和特征金字塔网络 (FPN)。

num_classes:这设置了我们的数据集中的类别数量。

FastRCNNPredictor:这取代了适合自定义类别数量的分类头。

MaskRCNNPredictor:这取代了适合自定义类别数量的掩码预测头。

model = maskrcnn_resnet50_fpn(pretrained=True)
num_classes = 2
in_features = model.roi_heads.box_predictor.cls_score.in_features
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels
num_filters = 256
model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask, num_filters, num_classes)
步骤7. 训练模型

model.to(“cuda”):这将我们的模型转移到 GPU 以加速训练。

torch.optim.Adam:这定义了我们的优化器,用于更新模型参数。

model.train():将模型设置为训练模式并使其能够改变权重。

训练循环:

  • 我们经历了多个时期的迭代。

  • 一批批图像和目标被传输到 GPU。

  • 该模型清除下一个时期的梯度,并传递图像来计算损失。

  • 损失反向传播,模型参数更新。

  • 计算并打印每个时期的平均损失。

model = model.to("cuda")
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
model.train()
for epoch in range(10):
    epoch_loss = cnt = 0
    for batch_x, batch_y in tqdm(data_loader):
        batch_x = list(image.to("cuda") for image in batch_x)
        batch_y = [{k: v.to("cuda") for k, v in t.items()} for t in batch_y]
        optimizer.zero_grad()
        loss_dict = model(batch_x, batch_y)
        losses = sum(loss for loss in loss_dict.values())
        losses.backward()
        optimizer.step()
        epoch_loss += loss_dict['loss_mask'].item()
        cnt += 1
    epoch_loss /= cnt
    print("Training loss for epoch {} is {} ".format(epoch + 1, epoch_loss))
步骤8. 评估模型
  • 我们加载一个示例图像及其原始蒙版。

  • 我们对图像和蒙版应用变换。

  • 我们将模型设置为评估模式,这样模型就不会计算梯度。

  • 我们将图像传入模型以获得预测的掩码。

  • 最后,我们使用 Matplotlib 将原始和预测的蒙版可视化。

image = Image.open('/content/images_BloodCellSegmentation/002.bmp')
gt_mask = Image.open('/content/targets_BloodCellSegmentation/002.png')
gt_mask = np.array(gt_mask)
gt_mask = ((gt_mask == 128) | (gt_mask == 255))
gt_mask = Image.fromarray(gt_mask)
transform = Compose([Resize(224), ToTensor()])
image = transform(image)
gt_mask = transform(gt_mask)
model.eval()
output = model(image.unsqueeze(dim=0).to('cuda'))
output = output[0]['masks'][0].cpu().detach().numpy()
plt.imshow(gt_mask.squeeze(), cmap='gray')
plt.imshow((output.squeeze() > 0.5).astype(int), cmap='gray')
步骤9. 计算交并比(IoU)

IoU计算:

  • 在这里,我们将预测的和原始的蒙版压平。

  • 然后我们计算预测掩码和原始掩码的交集和并集。

  • 现在我们计算 IoU 分数,这是评估分割性能的指标。

mask = (output.squeeze() > 0.5).astype(int)
pred = mask.ravel().copy()
gt_mask = gt_mask.numpy()
target = gt_mask.ravel().copy().astype(int)
pred_inds = pred == 1
target_inds = target == 1
intersection = pred_inds[target_inds].sum()
union = pred_inds.sum() + target_inds.sum() - intersection
iou = (float(intersection) / float(max(union, 1)))
iou

与其他技术的比较

虽然Mask R-CNN是分割领域的新秀,但我们不能忽视一些更古老、更传统的方法。阈值和边缘检测等技术长期以来一直是血细胞分割的主力。

但问题是,这些简单的方法通常无法处理现实世界医学图像中无穷无尽的变化。阈值化根据像素强度分离物体/背景,但它很难处理噪音、染色不均匀等问题。边缘检测根据强度梯度寻找边界,但细胞簇和重叠会使其偏离目标。

然后我们有了更新的深度学习模型,如 U-Net 和 SegNet,它们专门为密集像素分割任务而设计。它们确实提升了分割游戏的水平,但它们的最佳点是识别特定类别的所有像素,如“细胞”与“背景”。

Mask R-CNN 采用不同的基于实例的方法,分离并勾勒出每个单独的对象实例。虽然语义分割会告诉你属于“汽车”的所有像素,但实例分割会告诉你每个不同汽车对象周围的精确边界。对于血细胞分析,能够勾勒出每个细胞至关重要。

因此,尽管其他深度学习模型在各自的语义任务上表现出色,但 Mask R-CNN 在实例分割方面的专长使其在复杂的细胞轮廓描绘方面具有优势(无意双关)。其定位和分割单个实例以及分离聚类细胞的能力是无与伦比的。

结论

Mask R-CNN 在血细胞分割中的应用证明了深度学习技术在医学诊断中的前景。通过足够的研究和投资,我们可以自动化日常任务并提高医疗专业人员的工作效率。

Mask R-CNN 可以通过自动化分割过程极大地影响血细胞分析的有效性和准确性,从而提高患者护理和诊断结果。通过利用 Mask R-CNN 的先进功能,该技术可以轻松克服手动分割技术的缺点,并为更先进的医学成像解决方案创造未来的机会。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

6d58f5f1dfd6203f841990f72a928c02.jpeg

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

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

相关文章

基于Eclipse+JSP+SSH+Mysql开发的实验室设备管理系统

基于EclipseJSPSSHMysql开发的实验室设备管理系统 项目介绍💁🏻 实验室教师端(管理员端)集成了多个核心功能模块,包括通知管理、预约和借用记录管理、实验室管理以及设备信息管理。管理员可以发布和删除通知公告&#…

力控算法每日一练:209. 长度最小的子数组(java)

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 class Solution {public int minSu…

YOLOv10改进 | 注意力篇 | YOLOv10改进CA注意力机制

1.CA介绍 摘要:最近关于移动网络设计的研究已经证明了通道注意力(例如,挤压和激励注意力)对于提升模型性能的显着有效性,但它们通常忽略了位置信息,而位置信息对于生成空间选择性注意力图很重要。 在本文中,我们通过将位置信息嵌入到通道注意力中,提出了一种新颖的移动…

为什么构造costVolume中常用逆深度采样

原因:在现实世界中,深度值分布并不均匀。距离相机较远的物体,其深度值变化较慢,而距离较近的物体,深度值变化较快。均匀采样可能会导致成本体积中远处的深度级别具有更多的噪声和不确定性,而近处的深度级别…

NLP自然语言处理课程设计—基于实体识别的智能任务系统

NLP课程设计-基于实体识别的智能任务系统 前言一、数据获取可行性分析和需求分析1. 数据获取可行性分析2. 需求分析 二、程序主要NLP技术2.1 文本分类技术2.2 中文命名实体识别2.2.1 BiLSTM(双向长短期记忆网络)2.2.2 CRF(条件随机场&#xf…

MYSQL 四、mysql进阶 1(mysql逻辑架构以及查询流程)

一、mysql的逻辑架构 1. 逻辑架构剖析 1.1 服务器处理客户端请求 mysql是典型的c/s架构,即 client/server 架构,不论是客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本&am…

30天学会QT---------------大项目之在线考试系统

前段时间真的很忙很忙,忙完这段时间,总算是有空来写文章了,开始写的时候我就以为能够有时间准备和写这个,但是发现有时候忙着忙着就忘记了,没有办法来写项目,真的是非常尴尬。 现在有时间了,就有充分的时间来写了。 为了避免笔记断更,我决定先存稿来写。 1、如何规划项…

打造完美Mac多屏视界,BetterDisplay Pro一键掌控!

BetterDisplay Pro for Mac是一款专为Mac用户打造的显示器管理与优化软件,旨在为用户带来卓越的视觉体验和工作效率。它凭借强大的功能和简洁易用的界面,成为了Mac用户优化显示器设置的得力助手。 一、全方位管理与优化 BetterDisplay Pro for Mac支持…

【python】OpenCV—Segmentation

文章目录 cv2.kmeans牛刀小试 cv2.kmeans cv2.kmeans 是 OpenCV 库中用于执行 K-Means 聚类算法的函数。以下是根据参考文章整理的 cv2.kmeans 函数的中文文档: 一、函数功能 cv2.kmeans 用于执行 K-Means 聚类算法,将一组数据点划分到 K 个簇中&…

DGit介绍

参考地址:http://githubengineering.com/introducing-dgit/ DGit是“Distributed Git”的简写,即分布式Git。 众所周知,Git本身就是分布式的,任何的Git仓库备份都是包含该项目所有历史版本的所有的文件,分支&#xff…

SOLIDWORKS 2024正版软件:新增功能介绍

随着科技的飞速发展,计算机辅助设计(CAD)软件在工业设计领域扮演着越来越重要的角色。SOLIDWORKS作为3D CAD软件提供商,其每一次版本更新都带来了一系列创新功能和改进,旨在为用户提供更有效、更智能、更协同的设计体验…

雨量监测预警系统:非接触式测量防汛预警

TH-SW2雨量监测预警系统是一种用于监测降雨量的重要工具,对于防汛预警工作具有重要意义。该系统采用非接触式测量技术,可以实时监测雨量数据,并自动预警,以便及时采取防汛措施,确保人民生命财产安全。 系统组成 1. 雨…

嵌入式实训day6

1、 from machine import Pin from neopixel import NeoPixel import timeif __name__"__main__"#创建RBG灯带控制对象,包含5个像素(5个RGB LED)rgb_led NeoPixel(Pin(4,Pin.OUT),5)#定义RGB颜色RED(255,0,0)GREEN(0,2…

Vue项目 [WDS] Disconnected解决方法

Vue项目出现这个错误:[WDS] Disconnected! 1.对项目运行本身造成什么实质性的影响 2.红色的提示摆在那里确实不太好看 解决 打开 Application->LocalStorage,在key上添加loglevel:webpack-dev-server,在Value上添加SILENT。

项目计划

1.什么是项目计划? 2.软件项目计划的作用 3.项目计划的内容 4.项目计划的主要内容 5.滚动计划方法 6.WBS方法 7.软件项目的特点 8.制定计划的要点 9.直接成本和间接成本 10.为什么说项目计划不是一个文档,而是一个持续的策划过程? 项目计划不…

C++升级软件时删除老版本软件的桌面快捷方式(附源码)

删除桌面快捷方式其实是删除桌面上的快捷方式文件,那我们如何去删除桌面快捷方式文件呢?软件可能已经发布过多个版本,其中的一些版本的快捷方式文件名称可能做了多次改动,程序中不可能记录每个版本的快捷方式名称,没法直接去删除快捷方式文件。本文就给出一种有效的处理办…

01:HAL库DMA解算舵机

一:实现效果 DMA解算舵机 从下到上分别为舵机1,2,3,分别由函数Servo_SetAngle1(),Servo_SetAngle2(),Servo_SetAngle3()控制。 舵机1…

anaconda的基础用法

python和包以及anaconda的概念关系 环境 “好比一栋楼,在楼里面分配一间屋给各种‘包’放,每间房里面的‘包’互不影响” 激活环境 “告诉电脑,我现在要用这个屋子里面的‘包’来做东西了所以要进这间屋子” 移除环境 “现在这个屋子里…

基于Java的冬奥会科普平台

开头语:你好,我是计算机学姐码农小野。如果你对冬奥会科普平台感兴趣或有其他技术需求,欢迎随时私信我。 开发语言:Java 数据库:MySQL 技术:Java、B/S架构 工具:MyEclipse、MySQL 系统展示…

最值得入手的宠物空气净化器!希喂、352、安德迈真实测评~

随着天气越来越热,猫咪们也都开始掉毛啦。这时候,家里面到处都飘浮着猫咪们的浮毛和粑粑异味。抵抗力较差的铲屎官,身体就会出现一些问题,例如打喷嚏、咳嗽等呼吸道问题。 很多铲屎官以为用粘毛器、吸尘器等工具就能将猫咪们掉落…