图像处理:U-Net中的重叠-切片(Overlap-tile)

article/2025/10/26 5:59:00

深蓝学院是专注于人工智能的在线教育平台,已有数万名伙伴在深蓝学院平台学习,很多都来自于国内外知名院校,比如清华、北大等。

最开始接触 U-Net 的时候并不知道原作使用了 Overlap-tile 这种策略,因此当时不太理解为何网络结构要设计成非对称形式,即上采样得到的特征图尺寸与对应层在下采样时的尺寸不一致。

另外发现,这种策略可用于许多场景,特别是当 数据量较少 或者 不适合对原图进行缩放时尤其适用(缩放通常使用插值算法,主流的插值算法如双线性插值具有低通滤波的性质,会使得图像的高频分量受损,从而造成图像轮廓和边缘等细节损失,可能对模型学习有一定影响),同时它还能起到为目标区域提供上下文信息的作用。

本文先对这种策略的原理以及在U-Net中的使用进行说明,然后结合源码对该策略的实现进行解析,内容包括随机切片镜像填充后按序切片以及将切片重构成图像。

Overlap-tile在U-Net中的使用

先来对Overlap-tile策略的原理及其在U-Net中的使用做个介绍,让大家对其有个初步印象和基本理解。

熟悉U-Net结构的炼丹者们肯定清楚,它并不是一个完全对称的结构。也就是说,某一层特征图下采样后再上采样回来到对应层时,其尺寸会发生变化,比原来的小,原因在于U-Net使用的是不带padding的3x3卷积(valid卷积),每次经过这样的一个卷积就会使得特征图尺寸减小2x2。

(U-Net)

显然,如果直接输入原图,那么最后输出的尺寸会比原图小。如果我们希望得到和输入一致的尺寸,会怎么做?

最直接的是对输出结果再进行一次上采样,可以使用插值或者转置卷积的方法,若使用插值,由于其是不可学习的,会带来一定的误差;而使用转置卷积的话,又会增加参数量,并且模型也不一定能学习得好。

另外一种方法就是将U-Net中的valid卷积改为same卷积,即使用padding,这样每次3x3卷积就不会改变特征图的尺寸了,最终上采样回来的尺寸就能够和输入一致了。但是,padding是会引入误差的,而且模型越深层得到的feature map抽象程度越高,受到padding的影响会呈累积效应。

上述方法都体现出明显的不足之处,那么有没有更好的方法呢?我们来看看U-Net中的Overlap-tile是怎么做的。

做法其实很简单,就是在输入网络前对图像进行padding,使得最终的输出尺寸与原图一致。特别的是,这个padding是镜像padding,这样,在预测边界区域的时候就提供了上下文信息

(Overlap-tile)

上图左边是对原图进行镜像padding后的效果,黄框是原图的左上角部分,padding后其四周也获得了上下文信息,与图像内部的其它区域有类似效果。

Overlap-tile策略可搭配 patch(图像分块)一起使用。当内存资源有限从而无法对整张大图进行预测时,可以对图像先进行镜像padding,然后按序将padding后的图像分割成固定大小的patch。这样,能够实现对任意大的图像进行无缝分割,同时每个图像块也获得了相应的上下文信息。

另外,在数据量较少的情况下,每张图像都被分割成多个patch,相当于起到了扩充数据量的作用。更重要的是,这种策略不需要对原图进行缩放,每个位置的像素值与原图保持一致,不会因为缩放而带来误差。

随机切片

随机切片是在图像内部随机选取patch中心,然后将图像切成固定数量的patch。

以下示例是对单张图像及对应的掩膜(mask)做随机切片。

(随机切片 i)

patch中心位置根据其尺寸在图像内部随机选取,确定中心位置后,再根据各边长就可以确定patch的左上和右下两个顶点坐标。

(随机切片 ii)

最后从原图中取出对应位置的区域即可。

(随机切片 iii)

随机切片效果

(左:切片得到的图像块;右:原图对应区域)

镜像填充

对原图进行镜像填充,能够使模型对边界区域进行预测时获得上下文信息。下图蓝框部分是原图的左上角部分,镜像填充后,得到红框部分。

(镜像填充效果)

镜像填充后会进行按序切片,在切片时,各patch之间可以设定一个固定的间隔,这样能够避免过份重叠。至于各边需要填充多少长度,可以基于以下两种方式来决定:

i). 填充后,各边都能恰好切出整数个patch(最后不会剩余一点长度不足一个patch);

ii). 提前计算输入输出之间的尺寸差,使得padding后输出与输入尺寸保持一致。

下面就第i)种方式进行源码解析。若有多张不同尺寸的图片,那么就一张张独立处理;否则,可以组成一个批次进行处理。

(镜像填充 i)

先在竖直方向上进行填充,填充后,将原图置于中间,顶部和底部使用原图的镜像进行填充。

(镜像填充 ii )

然后在水平方向上进行填充,同样地,将填充前的图像置于中间,左右两边剩余部分使用填充前图像的镜像进行填充。

(镜像填充 iii)

按序切片

按序切片就是从图像的左上方开始,按照一定间隔依次将图像切成一个个小的图像块,直至图像的右下方。

(按序切片 i)

注意,各切片之间的间隔是可以小于切片边长的,这就代表各切片可能存在重叠部分

(按序切片 ii)

每张图切出相同数量相同大小的切片,计算出各个切片的位置,从图中取出对应的部分就得到各切片。

(按序切片 iii)

将切片重构成图像

将图像切片后,模型是对切片进行预测的,那么通常我们需要将这些切片的预测结果重新组合成整张图像对应的预测结果以方便评估和展示。

预测结果的重组与切片重组成图像的原理类似,这里就切片重组进行源码解析。

(切片重组 i)

在上一节提到,切片之间可能存在重叠部分,而重叠部分的像素值,我们通常取平均值。对于切片重构图像来说,取平均后的像素值与原图相同;而对于切片预测结果重组成整图预测结果来说,求平均相当于对多次预测所得的概率求均值作为最终预测结果。

(切片重组 ii)

注意,并不是将切片直接放入图像对应位置,而是使用求和(下图中 img +=、weights +=),就是因为切片之间可能存在重叠的部分,我们需要对这些部分求均值。

(切片重组 iii)

如果切片前做了padding,那么重构后的图像尺寸对应的是padding后的尺寸,因此我们还要裁出原图。我们在padding的时候,原图是放中间的,那么记下之前padding的长度就很容易计算出原图位置了。

(裁剪出原图)

End

如本文所述,Overlap-tile带来的好处有许多:不需要对图像进行缩放从而避免图像细节损失、能够为边界区域提供上下文信息、在数据量较少时充当数据扩充的手段。但是,在炼丹的世界里,实际效果如何还得“炼一炼”才知道,感兴趣的炼丹师可以在训练中尝试下这种策略。

✤✤✤

本文来自作者CW的原创投稿,如有任问题请及时留言,我们会第一时间处理。


http://chatgpt.dhexx.cn/article/fU8HN9Hp.shtml

相关文章

图像分割之(二)Graph Cut(图割)

图像分割之(二)Graph Cut(图割) zouxy09qq.com http://blog.csdn.net/zouxy09 上一文对主要的分割方法做了一个概述。那下面我们对其中几个比较感兴趣的算法做个学习。下面主要是Graph Cut,下一个博文我们再学习下Gr…

【前端必学】PS切图详细教程3种方法(图层切图,切片,切图神器cutterman)

PSD图像格式是Photoshop的专用格式,里面可以存放图层、通道、遮置等多种设计稿,对我们前端人员来说,最大的优点,我们可以直接从上面复制文字,获得图片,还可以测量大小和距离,我们开发需要的是一…

vue中的.passive修饰符的作用以及应用场景

passive这个修饰符会执行默认方法。你们可能会问,明明默认执行为什么会设置这样一个修饰符。这就要说一下这个修饰符的本意了。 浏览器只有等内核线程执行到事件监听器对应的JavaScript代码时,才能知道内部是否会调用preventDefault函数来阻止事件的默认…

burp插件系列1 passive-scan-client

阅读目录 插件介绍插件使用 插件介绍 被动扫描流量转发插件 项目地址: https://github.com/c0ny1/passive-scan-client这个项目其实主要功能和目前版本burp的Upstream Proxy Server功能基本重复,但是其也有自己的优势 不用每次新打开burp都要去配置U…

vue中的事件修饰符.self、.capture和.passive

vue中的事件修饰符有6种&#xff1a; .stop.prevent.capture.once.self.passive .stop是stopPropagation停止冒泡&#xff0c; .prevent是preventDefault阻止默认事件&#xff0c; .once是点击事件将只会触发一次 <!-- 点击事件将只会触发一次 --> <a v-on:click.o…

FileZilla客户端连接腾讯云FTP服务器时出现“227 Entering Passive Mode”

FTP的主动模式(PORT Mode)及被动模式(Passive Mode) FTP的特殊性&#xff1a; 大多数的TCP服务是使用单个的连接&#xff0c;一般是客户向服务器的一个周知端口发起连接&#xff0c;然后使用这个连接进行通讯。但是&#xff0c;FTP协议却有所不同&#xff0c;它使用双向的多个连…

FTP Entering Extended Passive Mode

目录 原因 两种方法解决,哪个行用哪种 方法一 方法二 原因 FTP的连接建立有两种模式PORT

ftp的passive模式

昨天调试了半天的ftp passive模式&#xff0c;记录一下 今天在一台测试服务器上搭建ftp&#xff0c;折腾了许久。 主要是不了解ftp的passive模式和port模式的区别。这里记录一下。 和passive模式对应的叫做port模式&#xff0c;也叫做standard模式&#xff0c;也叫主动模式。 每…

一篇文章彻底掌握 FTP 服务器的 ACTIVE 与 PASSIVE 工作模式

1 背景 某客户现场&#xff0c;每天都会批量生成大量 CSV 文件存放到 FTP 系统&#xff0c;这些 CSV 文件需要导入到大数据平台 HIVE 数仓中做后续离线分析&#xff0c;且 HIVE 数仓中的离线分析作业目前是使用 JENKINS 来调度的。 由于这些 CSV 文件是每天都会生成&#xff0c…

passive 的事件监听器

很久以前&#xff0c;addEventListener() 的参数约定是这样的&#xff1a; addEventListener(type, listener, useCapture) 后来&#xff0c;最后一个参数&#xff0c;也就是控制监听器是在捕获阶段执行还是在冒泡阶段执行的 useCapture 参数&#xff0c;变成了可选参数&…

强化学习之Passive learning求解 (1)

在MDP系列博客中&#xff0c;我们以一个Agent在4*3网格中寻找终点最优的路径策略为例&#xff0c;论述了MDP问题的原理和求解。有了MDP讲解作为基础之后&#xff0c;我们就可以正式的切入到“强化学习”的学习中来了。强化学习的目的是通过观测到的reward来为当前环境学习一个&…

【重要!!】passive优化页面性能

在js中给dom元素添加监听事件&#xff1a; let dom1document.getElementById("box1"); function box(that){console.log(that); } dom1.addEventListener("click",function(){box(1)});一般都是这样&#xff0c;但是还是有第三个参数&#xff0c;Boolean类…

Passive Event Listener

起源 最近打开项目随便点点&#xff0c;控制台就开始报警&#xff1a; Added non-passive event listener to a scroll-blocking ‘mousewheel’ event. Consider marking event handler as ‘passive’ to make the page more responsive 可以看到警告信息是element-ui和echa…

passive的作用和原理

passived到底有什么用&#xff1f; passived主要用于优化浏览器页面滚动的性能&#xff0c;让页面滚动更顺滑~~BetterScroll&#xff1a;可能是目前最好用的移动端滚动插件 passived产生的历史时间线 addEventListener()&#xff1a;大家都是认识的&#xff0c;为dom添加触发…

Java并发编程—CompletableFuture的介绍和使用

在博主上一篇博客介绍中&#xff0c;Java并发编程—java异步Future的迭代过程_小魏快起床的博客-CSDN博客&#xff0c;这里面给大家分析了Future的使用过程和一些存在的问题&#xff0c;那么针对里面出现的阻塞问题&#xff0c;博主将在这一篇文章给大家介绍清楚 &#x1f34f…

Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

一般的 Executors 的 execute以及submit 并发包下 Executors 创建的线程存在 一个 execute()&#xff0c;以及三个 submit() 不同的是使用 execute() 执行的任务是没有返回值的&#xff0c;使用 submit() 则是存在返回值的&#xff0c;这与接下里要说的 CompletableFuture.run…

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码&#xff0c;多线程编程用的比较多&#xff0c;其中有对CompletableFuture的使用&#xff0c;所以想写篇文章总结下 在日常的Java8项目开发中&#xff0c;CompletableFuture是很强大的并行开发工具&#xff0c;其语法贴近java8的语法风格&#xff0c;与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果&#xff0c;无论异步任务是通过线程池 ThreadPoolExecutor 执行的&#xff0c;还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化&#xff0c;从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包&#xff0c;是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务&#xff0c;让开发者利用这个包进行的多线程开发时&#xff0c;可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一&#xff1a;线程 1.初始化线程的四种方式 1&#xff09;、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…