关于图像分割的预处理 transform

news2025/1/17 6:09:00

目录

1. 介绍

2. 关于分割中的 resize 问题

3. 分割的 transform

3.1 随机缩放 RandomResize

3.2 随机水平翻转 RandomHorizontalFlip

3.3 随机竖直翻转 RandomVerticalFlip

3.4 中心裁剪 RandomCrop

3.5 ToTensor

3.6 normalization

3.7 Compose

4. 预处理结果可视化


1. 介绍

图像分割的预处理不像分类那样好操作,因为分类的label就是一个类别,图像增强的操作都是对原始图像操作的。

图像分割的label和img是严格对应的,或者说两者的空间分辨率(h*w)一样且像素点的对应位置都不能改变。否则,监督学习就失去了作用。而深度学习中,数据增强是不必可少的,对于数据更少的医学图像来说,数据增强更加必不可少。

所以,本章主要聊聊 图像分割中的数据增强

下面是DRIVE数据集的预处理可视化:

2. 关于分割中的 resize 问题

图像分割的resize问题,本人一直没有弄明白....

分割最后的目的应该是将前景从图像中口出来,那么两者的尺寸肯定需要保证一样的。然而,例如unet一类的网络输入都是固定大小480*480,那么最后分割的分辨率也就是480*480,显然已经和最原始的图像不一样了

现在不管是分类,还是分割网络的输入都不需要和原论文一致了,网络里面都做了优化,例如最大池化层等等....

不管网络如何优化,大部分预处理中都增加了resize的操作。那么能保证输入图像和输出的分辨率一样,但是最原始的图像还是不能一致。例如,原始512*512,resize 480*480 输入给网络产生 480*480 的分割图像,480和512已经不一样了

虽然最后分割出来的图像也可以通过resize还原成最原始的尺寸。但是插值又成了问题,更好的线性插值会导致分割图像的灰度值改变。例如分割的图是二值图像,背景为0前景为255,通过插值会导致出现0-255的任何一个数字,变成了灰度图像。当然最近邻插值可以避免这一问题,但最近邻插值显然在图像处理中不是一个好的选择。

之前想过,用双线性插值resize分割图像,然后利用阈值处理产生二值图。但是,这样的方法不仅仅麻烦,还有很多的问题,且违背了end to end的思想

下面纯个人瞎想...仅供参考...

所以说,解决的办法就是训练的图像随机的resize,例如需要给网络的输入是480*480,那么随机将训练图像变成缩放成例如300-500之之间任意的大小,再裁剪成480*480输入给分割网络

这样的好处就是,网络就不会对单纯的图像缩放敏感

那么,再随机分割的时候,就不需要resize,直接输入原图就行了

3. 分割的 transform

如下,分割任务中图像预处理的测试代码

其中就只要保证img和label是同时变换即可

3.1 随机缩放 RandomResize

如下,在给定的min和max直接随机生成一个整数,然后resize即可。

分割的label图像要采用最近邻算法,否则resize之后的label就不是二值图像

class RandomResize(object):
    def __init__(self, min_size, max_size=None):
        self.min_size = min_size
        if max_size is None:
            max_size = min_size
        self.max_size = max_size

    def __call__(self, image, target):
        size = random.randint(self.min_size, self.max_size)
        # 这里size传入的是int类型,所以是将图像的最小边长缩放到size大小
        image = F.resize(image, size)
        target = F.resize(target, size, interpolation=T.InterpolationMode.NEAREST)
        return image, target

3.2 随机水平翻转 RandomHorizontalFlip

flip_prob 就是翻转的概率

class RandomHorizontalFlip(object):
    def __init__(self, flip_prob):
        self.flip_prob = flip_prob

    def __call__(self, image, target):
        if random.random() < self.flip_prob:
            image = F.hflip(image)
            target = F.hflip(target)
        return image, target

3.3 随机竖直翻转 RandomVerticalFlip

和水平翻转的一样

class RandomVerticalFlip(object):
    def __init__(self, flip_prob):
        self.flip_prob = flip_prob

    def __call__(self, image, target):
        if random.random() < self.flip_prob:
            image = F.vflip(image)
            target = F.vflip(target)
        return image, target

3.4 中心裁剪 RandomCrop

中心裁剪的代码如下,需要注意的是,因为图像很可能不足裁剪的大小,所以需要填充

class RandomCrop(object):
    def __init__(self, size):
        self.size = size

    def __call__(self, image, target):
        image = pad_if_smaller(image, self.size)
        target = pad_if_smaller(target, self.size, fill=255)
        crop_params = T.RandomCrop.get_params(image, (self.size, self.size))
        image = F.crop(image, *crop_params)
        target = F.crop(target, *crop_params)
        return image, target

填充的代码,这里填充255代表不敢兴趣的区域

def pad_if_smaller(img, size, fill=0):
    # 如果图像最小边长小于给定size,则用数值fill进行padding
    min_size = min(img.size)
    if min_size < size:
        ow, oh = img.size
        padh = size - oh if oh < size else 0
        padw = size - ow if ow < size else 0
        img = F.pad(img, (0, 0, padw, padh), fill=fill)
    return img

3.5 ToTensor

这里label不能进行官方实现的totensor方法,因为归一化,前景像素的灰度值就会被改变

dtype 是因为要使用交叉熵损失,需要为整型,且label的维度中不能有channel

class ToTensor(object):
    def __call__(self, image, target):
        image = F.to_tensor(image)
        target = torch.as_tensor(np.array(target), dtype=torch.int64)
        return image, target

3.6 normalization

normalization 的实现也很简单

class Normalize(object):
    def __init__(self, mean, std):
        self.mean = mean
        self.std = std

    def __call__(self, image, target):
        image = F.normalize(image, mean=self.mean, std=self.std)
        return image, target

3.7 Compose

将transform 逐个实现就行了

class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, image, target):
        for t in self.transforms:
            image, target = t(image, target)
        return image, target

4. 预处理结果可视化

dataset里面改成这样就行了

加载完数据这样调用即可

 

测试代码:

label 中灰度值只有0 1 255

label 中没有 channel

# 可视化数据
def plot(data_loader):
    plt.figure(figsize=(12,8))
    imgs,labels = data_loader
    for i,(x,y) in enumerate(zip(imgs,labels)):
        x = np.transpose(x.numpy(),(1,2,0))
        x[:,:,0] = x[:,:,0]*0.127 + 0.709       # 去 normalization
        x[:,:,1] = x[:,:,1]*0.079 + 0.381
        x[:,:,2] = x[:,:,2]*0.043 + 0.224
        y = y.numpy()

        # print(np.unique(y))   # 0 1 255
        # print(x.shape)      # 480*480*3
        # print(y.shape)      # 480*480

        plt.subplot(2,4,i+1)
        plt.imshow(x)

        plt.subplot(2,4,i+5)
        plt.imshow(y)
    plt.show()

显示结果:

在dataset 里面,将前景像素改成120,就可以看到label的细节

 

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

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

相关文章

WPF mvvm框架Stylet使用教程-基础用法

Stylet框架基础用法 安装Nuget包 在“管理Nuget程序包”中搜索Stylet&#xff0c;查看Stylet包支持的net版本&#xff0c;然后选择第二个Stylet.Start包进行安装&#xff0c;该包会自动安装stylet并且生成基本的配置 注意事项&#xff1a;安装时要把需要安装的程序设为启动项…

第06章_面向对象编程(基础)

第06章_面向对象编程&#xff08;基础&#xff09; 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 学习面向对象内容的三条主线 Java类及类的成员&#xff1a;&#xff08;重点&…

《QT+CGAL网格处理——网格重建》

QT+CGAL网格处理——网格重建 一、重建效果二、代码分析显示代码格式转换彩色网格显示三、后续一、重建效果 二、代码分析 显示 1、依旧采取VTK显示,参照《QT+PCL》; 2、点数据、网格数据依旧采用pcl数据结构,cgal处理完成后转换格式即可 界面参照:

微服务学习-SpringCloud -Nacos (心跳机制及健康检查源码学习)

文章目录心跳机制与健康检查流程图心跳机制与健康检查总结详细源码说明当多个服务进行注册时&#xff0c;如何解决注册表并发冲突问题?心跳机制与健康检查流程图 心跳机制与健康检查总结 微服务在启动注册Nacos时&#xff0c;会创建一个定时任务&#xff0c;定时向服务端发生…

基于文心一言的底层视觉理解,百度网盘把「猫」换成了「黄色的猫」

随着移动互联网的一路狂飙&#xff0c;手机已经成为人们的新器官。出门不带钥匙可以&#xff0c;不带手机却是万万不可以的。而手机上&#xff0c;小小的摄像头也越来越成为各位「vlogger」的口袋魔方。每天有超过数亿的照片和视频被上传到百度网盘中&#xff0c;这些照片和视频…

Nginx 实战-负载均衡

一、负载均衡今天学习一下Nginx的负载均衡。由于传统软件建构的局限性&#xff0c;加上一台服务器处理能里的有限性&#xff0c;在如今高并发、业务复杂的场景下很难达到咱们的要求。但是若将很多台这样的服务器通过某种方式组成一个整体&#xff0c;并且将所有的请求平均的分配…

Kafka的命令行操作

一、topic命令 下面Windows命令需要把cmd路径切换到bin/windows下。 而Linux命令只需要在控制台切换到bin目录下即可。 下面都以Windows下的操作为例&#xff0c;在Linux下也是一样的。 1.1 查看主题命令的参数 kafka-topics.bat # Windows kafka-topics.sh # Linux输…

机器学习中的数学——学习曲线如何区别欠拟合与过拟合

通过这篇博客&#xff0c;你将清晰的明白什么是如何区别欠拟合与过拟合。这个专栏名为白话机器学习中数学学习笔记&#xff0c;主要是用来分享一下我在 机器学习中的学习笔记及一些感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎私信或者评论区留言&…

关于人工智能前沿信息获取的精品课程

通过观看在线课程可以很方便掌握获取人工智能前沿信息的方法&#xff0c;本文将介绍一些相关课程。 1. 武汉大学黄如花教授的信息检索中文课程知识面广泛&#xff0c;内容详尽&#xff0c;讲解清晰&#xff0c;课程的视频见课程 56。 ​ 课程 56 武汉大学黄如花教授的《信息检…

图神经网络GNN介绍

目录标题图神经网络基础图基本模块定义图的邻接矩阵点特征的更新&#xff08;重构&#xff09;多层GNN图卷积GCN模型GCN基本思想网络层数&#xff1a;基本计算图注意力机制graph attention networkT-GCN序列图神经网络图相似度图神经网络基础 图基本模块定义 三个特征&#x…

C++ 模板初阶

目录 一、函数模板 1.函数模板的概念 2.函数模板的定义 3.函数模板的原理 4.函数模板的实例化 ①隐式实例化 ②显式实例化 5.非模板函数与同名的函数模板同时存在 6.模板参数的匹配原则 二、类模板 1.类模板的定义格式 2.采用类模板的类外函数的定义格式 3.类模板…

【Linux-计算机网络】-TCP协议通信流程

1.TCP协议通信流程图 1.1TCP协议的通讯流程可以分为以下步骤&#xff1a; 应用层&#xff1a;应用程序通过系统调用API&#xff08;如socket&#xff09;创建一个TCP套接字&#xff08;socket&#xff09;&#xff0c;并设置好相关的选项。 传输层&#xff1a;当应用程序调用c…

机器学习中的数学原理——过拟合、正则化与惩罚函数

通过这篇博客&#xff0c;你将清晰的明白什么是过拟合、正则化、惩罚函数。这个专栏名为白话机器学习中数学学习笔记&#xff0c;主要是用来分享一下我在 机器学习中的学习笔记及一些感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎私信或者评论区留言…

153.网络安全渗透测试—[Cobalt Strike系列]—[生成hta/exe/宏后门]

我认为&#xff0c;无论是学习安全还是从事安全的人多多少少都会有些许的情怀和使命感&#xff01;&#xff01;&#xff01; 文章目录一、后门简介1、hta后门2、exe后门3、宏病毒后门二、生成后门并测试0、测试环境1、生成hta后门并测试2、生成exe后门并测试3、生成宏病毒后门…

分布式监控平台-Zabbix

分布监控平台-Zabbix一、Zabbix概述1、Zabbix是什么&#xff1f;2、Zabbix监控原理二、部署Zabbix服务端&#xff08;端口&#xff1a;10051&#xff09;1、关闭防火墙 修改主机名2、获取Zabbix下载资源3、安装SCL(Software Collections)&#xff0c;修改 Zabbix-front 前端源4…

SQL Server的子查询

SQL Server的子查询一、子查询基础知识二、子查询规则三、限定子查询中的列名四、子查询的多层嵌套五、相关子查询六、子查询类型总结一、子查询基础知识 子查询是嵌套在SELECT、INSERT、UPDATE、DELETE语句中或另一个子查询中的查询。 可以在允许表达式的任何位置使用子查询。…

【MySQL】联合查询

目录 1、前言 2、联合查询 3、内连接和外连接 4、案例演示 4.1 查询篮球哥每科的成绩 4.2 查询所有同学的总成绩及邮箱 5、自连接 5.1 显示所有计算机原理成绩比java成绩高的同学 6、子查询 6.1 查询出篮球哥的同班同学 6.2 多行子查询 7、合并查询 1、前言 在实际…

macOS Monterey 12.6.5 (21G531) 正式版发布,ISO、IPSW、PKG 下载

本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Linux 中创建可引导介质。 2023 年 4 月 10 日&#xff08;北京…

如何使用Midjourney辅助建筑平面设计和室内设计,常用的建筑平面效果图提示和使用效果展示(内附Midjourney提示词网站)

文章目录一、室内建筑平面设计1.AutoCAD图纸&#xff08;别墅图为例&#xff09;2.平面效果图3.三维平面透视图二、建筑室内设计1.现代简约2.波西米亚风格3.工业风格4.沿海风格5.法国风格6.现代风格7.提示增加颜色倾向8.提示中增加设计师9.其它一些尝试三、好用的Midjourney提示…

unity 全局光照

全局光照由两部分组成&#xff1a;直接光照和间接光照。 直接光照由直接光照射到物体上以后直接弹射到人眼接收到的光照。 间接光照为直接光照照射到物体上又弹射到其它物体上面以后多次弹射才被人眼接收的光照&#xff08;两次及以上的光照统称为间接光照&#xff09; 材质光…