为你,千千万万遍
计算机视觉边界处理论文阅读记录(COB+HED)

课程要求阅读边界处理论文并记录,就在网上寻找了有github开源的古早边界处理论文,很可惜的是由于对caffe这个架构不太熟悉,导致COB的复现并没有成功实现,但是在寻找资料的时候发现了更广泛使用的HED,并且成功使用Python的opencv包完成复现。

Convolutional Oriented Boundaries

image-20240330123925259

一、摘要

​ 面向卷积边界(COB),是一种通用的CNN架构,允许多尺度面向轮廓的端到端学习。可以将性能出色的基础CNN网络转化为高质量的轮廓,将基础CNN架构的未来改进带入语义分组中。并且通过稀疏边界表示方法,有效构建层次化的轮廓信号,实现高效构建轮廓的层次结构。

​ 该技术的特点在于能够高效且精确的进行边界检测和图像分割,同时在看不见的类别和数据集上面也有很强的泛化能力。以及在下游的识别应用方面,也有很大的应用潜力。

二、相关工作对比

​ Xie和Tu提出了一个端到端的深度框架,利用卷积特征图和新颖的损失函数来提高轮廓检测的效率和准确性。本文的COB与先前的工作不同之处在于,在单次网络传递整个图像时获取多尺度信息,将像素级分类与轮廓方向估计相结合,其输出比不同尺度上的线性组合更丰富。并且展示了使用VGGNet和ResNet的结果,表明COB是模块化的,并且可以结合并受益于基础CNN的未来改进。

​ 最近的工作还探索了弱监督或无监督学习轮廓的方法。研究者们利用通用轮廓检测器和目标检测器的结果进行学习,或者从视频序列获取的运动边界训练轮廓检测器。还有一些方法利用条件随机场来修正PASCAL数据集中轮廓边界的定位不准确的问题。与这些方法不同,COB利用轮廓检测和分割层次之间的对偶性,通过稀疏边界表示实现了高效的分割,同时利用CNN的高级知识来估计轮廓强度和方向,自然地受益于全局信息,避免了计算成本较高的全局化步骤。 此外,COB的方法还利用了由Najman和Schmitt最初研究的轮廓检测和分割层次之间的关系。先前的研究已经证明了这种方法在同时优化轮廓和区域时的有效性,并且利用多分辨率轮廓检测对对象提案的生成也非常有帮助。与这些方法不同的是,COB的稀疏边界表示能够实现干净高效的分割实现,而且通过利用CNN在轮廓强度和方向估计中的高级知识,自然地受益于全局信息,避免了计算成本高的全局化步骤的瓶颈问题

三、具体实现

1.深度多尺度定向轮廓(Deep Multiscale Oriented contour)

​ CNN由于其卷积和空间池化层的构造,天然具备多尺度特征提取的能力。随着网络层次的加深,特征图对于全局信息的获取能力增强,同时精细尺度的轮廓信息在浅层网络中被捕捉到,而深层网络能够获取到更粗糙的空间分辨率和更大的感受野,从而获取更全局的信息以用于预测边界的强度和方向。

image-20240330131442311

​ 提出了基于CNN的深度学习架构,用于在多个尺度上检测轮廓和其方向。不同组的特征图包含了不同尺度的信息,这些信息被组合起来构建一个多尺度的有向轮廓检测器。介绍深度学习的轮廓检测方法,以及使用CNN在图像级别进行轮廓检测的架构和边界方向估计方法。训练过程中使用了多个损失函数来监督不同尺度和方向的轮廓检测。

本文使用多尺度轮廓检测的基本CNN架构。作者对50层的ResNet进行了微调,移除了用于分类的全连接层和批量归一化层。网络主要由卷积层和ReLU激活函数组成,分为5个阶段,每个阶段处理不同的尺度。通过监督每个阶段的输出,获取不同分辨率的中间结果。作者在这个基本CNN的基础上,使用可训练权重将四个最精细和四个最粗糙尺度的中间结果进行线性组合,得到精细尺度和粗糙尺度的输出,用于训练多尺度的轮廓检测。 此外,作者还介绍了通过连接到基本网络的K个分支网络来估计轮廓的方向。这些分支网络在不同尺度的中间卷积层上进行操作,每个分支网络与一个方向角相关联,并且对该方向下的轮廓像素进行分类。最终,通过将不同方向的反应进行后处理,得到轮廓的方向估计。

image-20240330132047259

image-20240330132124828

2、快速分层区域

这里主要是介绍如何利用多尺度轮廓和方向构建高效的图像分割算法。

​ 首先引入超度量等高线图的概念,它将轮廓检测概率图转换成了一个分层边界图,当在不同的轮廓强度阈值下进行分割时,得到了不同粒度的分区。然后,介绍了一种替代的图像分区表示方法,可以将多尺度UCM的计算时间降低一个数量级,减少到不到一秒钟。

image-20240330132734237

​ 图像分区的一种常见表示方法是使用标签矩阵,将像素集合划分为不同的区域。图中显示了一个示例,大小为2×3,共有三个区域。分区的边界是具有不同标签的像素之间的边界元素(用红色突出显示)。这些边界可以具有不同的强度(红线的粗细),表示该边界是否为真实边界的置信度。通过按照递增强度的顺序迭代地擦除这些边界,可以得到不同的分区,即区域层次结构或超度量等高线图。

​ 边界通常存储在边界网格中,边界网格是图像大小的两倍(减一)的矩阵。奇数坐标表示像素(灰色区域),而中间位置表示边界(红色数字)和连接点(交叉位置)。 UCMs使用这种表示方法来存储边界的强度值,即每个边界位置存储着超过该阈值时消失的边缘和邻近的两个区域合并的阈值。因此,通过对UCM进行二值化,可以得到以边界网格表示的分区。

​ 然而,在运行时,这种表示方法在激活边界的百分比非常稀疏时效率非常低。存储这些空边界会浪费内存,并导致在边界网格上进行操作时效率低下,因为需要在整个矩阵上扫描以修改单个边界。于是提出了稀疏边界表示方法。它存储了一张查找表,记录了相邻区域对、它们的边界强度和边界的坐标列表。除了在内存方面更紧凑外,这种表示方法还可以对边界的特定部分进行高效操作,只需要在查找表中搜索并扫描激活的坐标,而不需要整个边界网格。

​ 接下来 从多尺度方向轮廓中快速构建层次结构,最直接的方法是对各个层级进行线性组合,得到一个单一的轮廓信号。本文的方法是将从每个层上提取的区域层次结构组合起来,而不是直接使用轮廓。从不同图像尺度上计算的轮廓中得到UCM,并将其组合成一个单一的层次结构。

四、实验性能

image-20240330133508509

​ 该方法在PASCAL Context和BSDS500数据集上进行轮廓检测和通用图像分割的结果。在VOC训练集上训练后,并在VOC验证集上进行了超参数选择。在使用先前调整过的超参数的情况下,在未见过的VOC测试集上的最终结果。

image-20240330133707010

​ 边界测量(Fb)和区域测量(Fop)的精确度-召回曲线,以及ODS、OIS和AP等汇总指标的结果。根据这些结果显示,COB模型在BSDS500数据集上表现出色,接近甚至达到了人类的表现水平。

image-20240330133852657

四、结论

​ 这篇论文开发了一种在单次前向传递的卷积神经网络中检测多尺度轮廓及其方向的方法。他们提出了一种快速生成区域层次结构的框架,通过高效地组合多尺度定向轮廓检测来实现,这得益于一种新的稀疏边界表示方法。

五、后续

​ 因为想要尝试把这篇论文的成果复现出来,论文也把项目发到了github上面,但是由于对caffe了解并不深入,复现过程还有很多环境没有配置好,教程也比较少,就放弃了COB的复现。但是在复现工作中,看见了另一种边界处理方法HED的介绍,这种方法教程也比较多,github上面也发了相关的项目。于是就做了HED的复现,同时也再阅读了一下HED的论文。

image-20240407173800663

一、摘要

​ 提出整体嵌套的边缘检测(HED):通过一个利用完全卷积神经网络和深度监督网络的深度学习模型来执行图像到图像的预测。

  • 整体图像训练和预测
  • 多尺度、多层次的特征学习

二、文献综述

image-20240407204340991

(a)显示了BSD500数据集的一个示例测试图像;(b)显示了其对应的由人体主题注释的边缘(c)显示HED结果。在第二行: (d)、(e)和(f)分别显示了我们卷积神经网络的第2、3和第4层的侧边响应。在第三行: (g)、(h)和(i)分别显示了来自Canny检测器[4]在= 2.0、= 4.0和= 8.0尺度上的边缘响应。

HED在一致性上比精明有明显的优势。

三、实现方法

image-20240407210057062

  • (a)Multi-stream learning 示意图,可以看到图中的平行的网络下,每个网络通过不同参数与receptive field大小的不同,获得多尺度的结果。输入影像是同时进入多个网络处理,得到的特征结果直接反应多尺度,再连接到一个global out layer得到输出。

  • (b)Skip-layer network learning 示意图,该方法主要连接各个单的初始网络流得到特征响应,并将响应结合在一起输出(特点:只有一路network,从不同层提取信息连接到输出)

  • (c)Single model on multiple inputs 示意图(就是不同尺寸的图片输入),单一网络,图像resize方法得到多尺度进行输入,该方法在训练和test过程均可加入。同时在非深度学习中也有广泛应用。

  • (d)Training independent networks ,从(a)演化来,通过多个独立网络分别对不同深度输出loss进行多尺度预测,该方法下训练样本量较大(训练多个不同的网络(深度不同且loss也不同),得到多个不同的输出,缺点显然是资源消耗太大。

  • (e)Holistically-nested networks,本文提出的算法结构,从(d)演化来,类似地是一个相互独立多网络多尺度预测系统,但是将multiple side outputs组合成一个单一深度网络。

image-20240407210453152

将side output layer 与每个stage(理解为每一组卷积池化)的最后一层卷积层相连,也就是conv1 2, conv2 2, conv3 3, conv4 3, conv5 3.这些卷积层的感知野尺寸与对应的side-output layer完全相同。(作者在conv1_2, conv2_2, conv3_3, conv4_3,conv5_3后面分别引出,然后接入sigmoid_cross_entropy_loss,并且在最后一层,对上面的5层的输出做了concat,同时也接入sigmoid_cross_entropy_loss,这样所有的Loss都等概率的同时训练,从而使得最终得到比较好的模型。)
在卷积层后面侧边插入一个输出层 side-output 层,在side-output层上进行deep supervision,使得结果向着边缘检测方向进行。同时随着side-output层越向后大小的变小,将receptive field变大,最后通过一个weighted-fusion layer得到多尺度下的输出。
总结:

可以看到的是整个过程只有一个卷积+池化的过程,Unet还有上采样的过程,这是不同点;图中的有5个马的图片,从大到小,从浅到深,纹理越来越少,这分别是经过了maxpool和卷积得到的不同尺寸的输出。从图中可以看到,这些输出叫做side-output 1到side-output 5。图中这五个特征图经过虚线,得到了一个Y,这个Y是经过“weighted-fusion”得到了,简单的说就是,五个图经过一个可以训练的权重参数,融合成了最终的输出。

四、复现效果

image-20240408144537944

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import cv2 as cv
import argparse

parser = argparse.ArgumentParser(
description='复现示例')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera', default='001.JPG')
parser.add_argument('--prototxt', help='Path to deploy.prototxt', default='deploy.prototxt')
parser.add_argument('--caffemodel', help='Path to hed_pretrained_bsds.caffemodel',
default='hed_pretrained_bsds.caffemodel')
parser.add_argument('--width', help='Resize input image to a specific width', default=500, type=int)
parser.add_argument('--height', help='Resize input image to a specific height', default=500, type=int)

args = parser.parse_args()

class CropLayer(object):
def __init__(self, params, blobs):
self.xstart = 0
self.xend = 0
self.ystart = 0
self.yend = 0

def getMemoryShapes(self, inputs):
inputShape, targetShape = inputs[0], inputs[1]
batchSize, numChannels = inputShape[0], inputShape[1]
height, width = targetShape[2], targetShape[3]
# self.ystart = (inputShape[2] - targetShape[2]) / 2
# self.xstart = (inputShape[3] - targetShape[3]) / 2
self.ystart = int((inputShape[2] - targetShape[2]) / 2)
self.xstart = int((inputShape[3] - targetShape[3]) / 2)
self.yend = self.ystart + height
self.xend = self.xstart + width
return [[batchSize, numChannels, height, width]]

def forward(self, inputs):
return [inputs[0][:, :, self.ystart:self.yend, self.xstart:self.xend]]
# ! [CropLayer]
# ! [Register]
cv.dnn_registerLayer('Crop', CropLayer)
# ! [Register]
# Load the model.
net = cv.dnn.readNet(cv.samples.findFile(args.prototxt), cv.samples.findFile(args.caffemodel))
kWinName = 'Holistically-Nested Edge Detection'
cv.namedWindow('Input', cv.WINDOW_NORMAL)
cv.namedWindow(kWinName, cv.WINDOW_NORMAL)
frame = cv.imread('001.JPG')
cv.imshow('Input', frame)
# cv.waitKey(0)
inp = cv.dnn.blobFromImage(frame, scalefactor=1.0, size=(args.width, args.height),
mean=(104.00698793, 116.66876762, 122.67891434),
swapRB=False, crop=False)
net.setInput(inp)
out = net.forward()
out = out[0, 0]
out = cv.resize(out, (frame.shape[1], frame.shape[0]))
cv.imshow(kWinName, out)
cv.imwrite('result.png', out)
cv.waitKey(0)



加载的模型大概50M。

cv 图片边界检测 HED COB
Carvana ImageMasking Challenge [基于UNET的kaggle图像遮蔽挑战]
基于ID3算法和后剪枝的决策树实验
© 2020 Gina
Powered by hexo | Theme is blank
Title - Artist
0:00