首页 > 其他分享 >使用Mask R-CNN实现图像分割

使用Mask R-CNN实现图像分割

时间:2024-08-12 18:52:04浏览次数:12  
标签:loss gt Mask image torch mask 图像 CNN model

使用 Mask R-CNN 实现分割

步骤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

标签:loss,gt,Mask,image,torch,mask,图像,CNN,model
From: https://blog.csdn.net/2301_76924624/article/details/141138513

相关文章

  • 裁剪图像--原始大小变换
    用QPainter画出图像,画出要取出的矩形位置头文件源码如下:CusImageCrop.h点击查看代码`#pragmaonce#include<QObject>#include<QPaintEvent>#include<QLabel>#include<QMutex>#include<QTimer>#pragmaexecution_character_set("utf-8")class......
  • 基于人工智能的图像物体擦除与背景填充技术
    摘要:本文介绍了一种基于人工智能的图像处理技术,该技术能够自动识别并擦除图像中的指定物体,同时智能填充背景,以实现图像的自然恢复。该技术为用户提供了一种高效、简便的图像编辑工具,适用于多种应用场景。关键词:人工智能,图像编辑,物体擦除,背景填充1.引言在图像编辑领域,去......
  • 图像数据处理1
    一、图像数据的表示与基本运算1.1图像文件的读写与显示1.1.1OpenCV读写与显示图像文件①彩色图像转为灰度图像importcv2ascvimportsysimportos#从当前工作目录下读入一幅彩色图像img_path='E:\PyCharmCommunityEdition2024.1.1\image\slpn.jpg'#此处为绝对......
  • 图像分割算法
    5.1阈值分割(Thresholding)介绍阈值分割是一种简单而有效的图像分割方法,通过设置一个或多个阈值,将图像分割为前景和背景区域。常见的阈值分割方法包括全局阈值、自适应阈值和Otsu阈值。原理阈值分割通过比较像素值与设定的阈值,将像素分类为前景或背景。公式在阈值分割......
  • 电子商务图像生成技术:AI驱动的自动化流程
    摘要:本文介绍了一种基于人工智能技术的电子商务图像生成系统,该系统能够自动化地完成商品图像的生成过程。通过简单的三个步骤,用户可以快速生成高质量的电商主图和头图,从而提高工作效率并降低成本。**关键词:**人工智能,电商图像,自动化生成,图像处理1.引言在电子商务领域,高质......
  • AI在医学领域:nnSynergyNet3D高精度分割肝硬化肝脏体MRI图像
    关键词:肝硬化肝脏分割、协同深度学习模型、跨模态泛化    肝硬化是慢性肝病(CLD)的最后阶段,是一个重大的全球性健康问题。2019年,它是全球死亡原因的第11位,占全球死亡人数的2.4%。尽管病毒性肝炎仍然是终末期肝病的主要原因,但与代谢功能障碍相关的脂肪肝病(MASLD)预计将由于......
  • 利用OpenCvSharp进行图像相关操作
    前言程序设计过程,有时也需要对图像进行一些简单操作,C#没有现成的图像处理库,但有人对OpenCV进行了包装,我们可以很方便的使用OpenCvSharp对图像进行操作。当然了,这也需要使用的人员进行一些研究,但相对于C++版本,它已经非常友好了。1、显示图像代码:privatevoidbutton1_Click(......
  • 【大作业-17】使用TensorFlow快速实现图像风格迁移系统
    使用TensorFlow快速实现图像风格迁移系统资源地址:28-基于Tensorflow的风格迁移+代码+模型+系统界面+教学视频.zip资源-CSDN文库视频地址:[使用Tensorflow实现图像风格迁移系统_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1VE421w7RY/)随着GPT的横空出世,生成......
  • Ai绘画|如何安装使用最简单的秋叶版ComfyUI 整合包,万字长文手把手详细教你安装部署,快速
    大家好,我是灵魂画师向阳AI绘画界的国内开源大神——B站的秋叶大佬在1月份就已经发布了AI绘画工具ComfyUI的整合包。用户将压缩包下载后,能够一键启动comfyui。其便利性与之前的webui整合包如出一辙。然而在整合包下载完成后,新手或许会遭遇插件以及模型缺失的情况,同......
  • 图像滤波算法
    3.1平滑滤波器(SmoothingFilters)介绍平滑滤波器用于去除图像中的噪声,使图像更加平滑和柔和。常见的平滑滤波器包括均值滤波和高斯滤波。原理平滑滤波器通过对像素及其邻域像素的值进行平均或加权平均,来减少图像中的噪声。均值滤波采用简单的均值计算,而高斯滤波则使用加......