当前位置:   article > 正文

目标检测与目标跟踪算法技术汇总_目标检测 目标跟踪

目标检测 目标跟踪

现如今chatgpt的爆火,我也使用了一段时间,问了许多关于人工智能技术的问题,基本是它能够回答了大部分的原理的,至于其人工智能涉及到的算法以及网络,考虑到也没有图,可能在给出这类回答上,是不太容易理解的。

本章旨在介绍当前热门的目标检测、目标跟踪算法和方法,我选择使用chatgpt给出答案辅助我完成这篇文章

文章后面会给出算法的github链接

1 传统方法

目标检测已经存在了相当长一段时间;传统的计算机视觉方法来进行物体检测出现在90年代后期。这些方法使用经典的功能检测,结合KNN或SVM等机器学习算法进行分类,或与FLAN等描述匹配器进行对象检测。

最值得注意的特征检测算法可以说是SIFT和SURFas特征描述符,以及用于角检测的FAST。特征描述符使用一系列数学近似来学习缩放不变的图像表示。其中一些古老的学校方法有时可以完成这项工作,但我们还有很多事情要做。

在这里插入图片描述
在这里插入图片描述
至于目标跟踪,传统方法似乎比目标检测方法更经得起时间的考验。卡尔曼滤波、稀疏和致密的光流等想法仍然被广泛使用。当卡尔曼滤波在阿波罗PGNCS中使用它根据过去的位置测量和新数据为航天器提供最佳位置估计时,它进入了名人堂。今天,它的影响仍然可以在许多算法中看到,例如简单在线和实时跟踪(SORT),它使用匈牙利算法和卡尔曼滤波器的组合来实现体面的对象跟踪。

在这里插入图片描述

2 目标检测进展

2.1 R-CNN

早在2014年,具有CNN特征的区域(R-CNN)就是一种用于目标检测和语义分割的新鲜空气,因为之前最先进的方法被认为是与SIFT相同的旧算法,仅包含在复杂的集成中,需要大量的计算能力,并且主要依赖于边缘、渐变和角等低级特征。

R-CNN系统由三个主要模块组成。最重要的模块使用称为选择性搜索的分割算法提取了大约2000个区域提案,以找出图像的哪些部分最有可能包含对象。选择性搜索应用各种不同的策略,因此它可以处理尽可能多的图像条件。该算法使用各种比例的窗口扫描图像,并查找共享颜色和纹理的相邻像素,同时考虑闪电条件。

第二个模块是一个大型卷积神经网络,从选择性搜索返回的每个提案中提取固定长度的特征向量。无论大小或宽高比如何,候选区域都会进行图像翘曲,以达到所需的输入大小。最后,最后一个模块用特定类别的线性支持向量机对每个区域进行分类。

在这里插入图片描述

R-CNN的训练和测试非常缓慢,按照今天的标准,也不是很准确。尽管如此,这是为Fast R-CNN以及当前最先进的Faster R-CNN和Mask R-CNN铺平道路的基本方法

ChatGPT实现R-CNN

R-CNN模型是一种经典的目标检测模型,其基本思想是在图像中选取一些候选框,然后对每个候选框进行特征提取和分类,从而得到图像中的目标位置和类别。下面是使用PyTorch实现R-CNN模型的一些基本步骤:

  1. 数据预处理:首先需要将训练数据和测试数据转换为PyTorch中的Dataset和DataLoader对象,然后对数据进行预处理,如缩放、裁剪、归一化等。
  2. 候选框提取:使用selective search等方法从输入图像中提取候选框,得到一个候选框列表。
  3. 特征提取:将每个候选框中的图像块输入到CNN中进行特征提取,得到一个特征向量。
  4. 目标分类:将每个特征向量输入到分类器中进行目标分类,得到每个候选框中目标的概率分布。
  5. 边界框回归:对于每个候选框,使用回归器预测其准确的边界框位置。
  6. 非极大值抑制:根据目标概率分布和边界框位置,使用非极大值抑制方法剔除重复的目标检测结果。

下面是一个使用PyTorch实现R-CNN模型的基本代码框架

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.models as models
import torchvision.transforms as transforms

# 定义CNN模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        # 使用预训练的VGG16模型作为特征提取器
        self.cnn = models.vgg16(pretrained=True).features[:30]

    def forward(self, x):
        x = self.cnn(x)
        return x

# 定义R-CNN模型
class RCNN(nn.Module):
    def __init__(self):
        super(RCNN, self).__init__()
        self.cnn = CNN()
        self.fc1 = nn.Linear(512*7*7, 4096)
        self.fc2 = nn.Linear(4096, 4096)
        self.fc3 = nn.Linear(4096, 21) # 用于分类的全连接层,输出21维向量,表示21个类别的概率
        self.fc4 = nn.Linear(4096, 4) # 用于回归的全连接层,输出4维向量,表示边界框的坐标

    def forward(self, x):
        x = self.cnn(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        x = self.fc2(x)
        cls = self.fc3(x)
        bbox = self.fc4(x)
        return cls, bbox

# 训练模型
model = RCNN()
criterion = nn.CrossEntropyLoss() # 交叉熵损失函数
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9) # 随机梯度下降优化器

for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        cls, bbox = model(images)
        loss_cls = criterion(cls, labels)
        loss_bbox = criterion(bbox, targets) # 回归损失函数
        loss = loss_cls + loss_bbox # 总损失函数
        loss.backward()
        optimizer.step()

        if (i+1) % 100 == 0:
            print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'
                  .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

# 测试模型
model.eval()
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)
        cls, bbox = model(images)
        _, predicted = torch.max(cls.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    print('Test Accuracy of the model on the {} test images: {} %'.format(total, 100 * correct / total))
  • 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
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

2.2 Fast R-CNN

Fast R-CNN是由R-CNN的作者之一提出的,作为有价值的继任者。与R-CNN相比,一个很大的改进是,Fast R-CNN没有为每个区域提案进行约2000个前传,而是在网络的单个正向传递中计算整个输入图像的卷积特征图,使其速度要快得多。另一个改进是,该架构经过端到端训练,并导致多任务丢失,从而简化了更简单的训练。

Fast R-CNN的输入是一个图像,以及一组对象提案。首先,它们通过一个完全卷积网络来获取卷积特征映射。接下来,对于每个对象提案,使用感兴趣的区域(RoI)池层从特征映射中提取固定长度的特征向量。快速R-CNN使用完全连接的图层将每个RoI映射到特征向量,最终输出软最大概率和边界框,它们分别是对象的类和位置。

在这里插入图片描述

2.3 Fatster R-CNN

事实证明,Fast R-CNN仍然相当缓慢,这主要是因为CNN受到上述区域提案算法选择性搜索的瓶颈。Fast R-CNN通过放弃传统的区域提案方法,并依靠完全深入的学习方法来解决这个问题。它由两个模块组成:名为区域提案网络(RPN)的CNN和Fast R-CNN探测器。这两个模块合并成一个网络,并进行端到端训练。

Faster R-CNN的作者在设计RPN以强调输入图像中的重要内容时,从注意力机制中汲取了灵感。通过在网络的最后一个共享卷积层上滑动一个小网络来创建区域提案。小网络需要卷积特征映射的(n x n)窗口作为输入。每个滑动窗口都映射到一个较低维度的特征,因此像以前一样,它被输入到两个完全连接的层:盒子分类和盒子回归层。

值得一提的是,边界框相对于被称为锚的手工挑选的参考框是参数化的。换句话说,RPN预测四个校正坐标将锚移动并调整锚的大小,而不是图像上的坐标。默认情况下,更快的R-CNN使用3个刻度和3个宽高比,导致每个滑动窗口有9个锚。

在这里插入图片描述
Faster R-CNN被认为是最先进的,它肯定是目标检测的最佳选择之一。然而,它没有在检测到的物体上提供分割,即它无法找到物体的确切像素,而只能定位物体周围的边界框。在许多情况下,这不需要,但当它需要时,Mask R-CNN应该是第一个想到的。

2.4 Mask R-CNN

Facebook AI Research(FAIR)的Mask R-CNN作者扩展了Faster R-CNN,以执行实例分割,以及类和边界框。实例分割是对象检测和语义分割的组合,这意味着它既可以检测图像中的所有对象,也可以分割每个实例,同时将其与其他实例区分开来。

Mask R-CNN的第一阶段(区域提案)与其前身相同,而在第二阶段,它为每个RoI输出一个与类和边界框平行的二进制掩码。这个二进制掩码表示像素是否是任何对象的一部分,而不考虑类别。像素的类将仅由它们所在的边界框分配,这使得模型更容易训练。

第二阶段的另一个区别是,Fast R-CNN中引入的RoI池层(RoIPool)被RoIAlign取代。使用RoIPool执行实例分割会导致许多像素不准确,即与原始图像相比,特征映射错位。发生这种情况是因为RoIPool对感兴趣的区域进行量化,包括在生成的特征映射中将浮点值四舍五入到十进制值。另一方面,改进的RoIAlign通过完全避免任何量化,而不是使用双线性插值来计算输入特征的确切值,将提取的特征与输入正确对齐。

在这里插入图片描述

2.5 YOLO

我们现在正在将重点从以准确性为导向的解决方案转向以速度为导向的解决方案。你只看一次(YOLO)是当今最受欢迎的物体检测方法,这是有充分理由的。它能够以最小的延迟处理实时视频,同时保持可观的准确性。顾名思义,它只需要一个正向传播来检测图像中的所有对象。

YOLO是在Darknet中设计的,Darknet是一个用C和CUDA编写的开源神经网络框架,由创建YOLO的作者Joseph Redmon开发。上次迭代是YOLOv3,与之前的版本相比,它更大,在小对象上更准确,但在较大的对象上略差。在YOLOv3中,使用Darknet-53(具有剩余连接的53层CNN),这比YOLOv2之前的Darknet-19(19层CNN)大跃。

与之前输出框的边界框、置信度和类的YOLO版本不同,YOLOv3在网络的不同深度上以3个不同比例预测边界框。图像上的最终对象检测使用非最大抑制(NMS)来确定,NMS是一种简单的方法,可以删除相互重叠的边界框,而不是预定义的交叉-联(IoU)阈值。在这种重叠的冲突中,YOLO分配的信心最大的边界框获胜,而其他盒子则被丢弃。
在这里插入图片描述
就像在Faster R-CNN中一样,框值相对于引用锚点。然而,它没有为任何任务拥有相同的精心挑选的锚点,而是使用训练数据集上的k均值聚类来找到任务的最佳锚点。YOLOv3的默认锚点数为9个。令人惊讶的是,softmax不用于类预测,而是用于多个独立的逻辑分类器,训练有二进制交叉熵损失

2.6 SSD

单发多盒探测器(SSD)在YOLO作为有价值的替代品几个月后问世。与YOLO类似,对象检测是在网络的单个正向传播中完成的。这个端到端CNN模型通过一系列卷积层传递输入图像,沿途从不同尺度生成候选边界框。

作为训练的地面真相,SSD将标记对象视为积极示例,而与正值不重叠的任何其他边界框都是负示例。事实证明,以这种方式构建数据集使其非常不平衡。因此,SSD在执行NMS后立即应用了一种称为硬负采矿的方法。硬负采矿是一种仅选择置信度损失最高的负数的方法,因此正负数和负数之间的比率最多为1:3。这导致更快的优化和更稳定的训练阶段。
在这里插入图片描述
在官方文件的上图中,我们可以看到骨干网络是VGG-16。然而,如今,我们经常可以看到带有ResNet、Inception甚至MobileNet主干的SSD。

2.7 RetinaNet

RetinaNet早在2017年就由FAIR的研究人员提出。它也是像YOLO和SSD这样的单阶段框架,它用速度换取比R-CNN变体等两阶段框架更差的准确性。RetinaNet使用ResNet + FPN主干来生成丰富的多尺度卷积特征金字塔。像往常一样,顶部连接着两个子网络,一个用于对锚框进行分类,另一个用于从锚框生成偏移到地面真相对象框。
在这里插入图片描述
如前所述,密集探测器训练期间的班级不平衡压倒了交叉熵损失。创新的焦点丢失提高了对稀疏的硬示例进行集中训练的准确性,同时限制了容易的底片的数量。这是通过重塑损失函数来实现的,使其不像硬示例那样重视简单的示例。
在这里插入图片描述
焦点损失定义,其中α ∈ [0, 1]是解决类失衡的加权因子,γ是聚焦参数

引入加权因子α是解决阶级失衡的常见方法。作者首先尝试了α=0,但这比α平衡形式更准确。您可能还会注意到,当γ=0时,焦距损耗等价于交叉熵损耗。

3 目标跟踪进展

3.1 Recurrent YOLO

首先,我们可以查看Recurrent YOLO(ROLO),这是一种结合对象检测和循环神经网络的单个对象跟踪方法。ROLO是YOLO和LSTM的组合。对象检测模块使用YOLO收集视觉特征以及位置推断先验。在每个时间步(帧)上,LSTM都会收到长度为4096的输入特征向量,并返回跟踪对象的位置。
在这里插入图片描述

3.2 SiamMask

在单个对象跟踪方面,SiamMask是一个绝佳的选择。它基于迷人的暹罗神经网络,该网络在谷歌的Facenet中越来越受欢迎。除了以每秒55帧的速度生产旋转边界框外,它还提供与类无关的对象分割掩码。为了实现这一点,SiamMask需要用单个边界框初始化,以便它能够跟踪所需的对象。然而,这也意味着SiamMask无法使用多个对象跟踪(MOT),并且修改模型以支持,这将给我们留下一个明显缓慢的物体检测器。

在这里插入图片描述
还有其他几个著名的对象跟踪器使用暹罗神经网络,例如DaSiamRPN,它赢得了VOT-18挑战(PyTorch 0.3.1代码)和SiamDW(PyTorch 0.3.1代码)。

3.3 DeepSort

我们之前提到SORT是对象跟踪的算法方法。Deep SORT正在通过用一种新的余弦度量学习取代关联度量来改进SORT,这是一种通过软最大制度的重参数化有效优化余弦相似性的特征空间的方法。

轨道处理和卡尔曼过滤框架与原始SORT几乎相同,但边界框是使用预先训练的卷积神经网络计算的,该网络训练在大规模的人称重新识别数据集上。这种方法是多个对象检测的绝佳起点,因为它易于实现,提供可靠的准确性,但最重要的是实时运行。

3.4 TrackR-CNN

TrackR-CNN只是作为多对象跟踪和分割(MOTS)挑战的基线引入的,但事实证明它实际上是有效的。首先,对象检测模块在ResNet-101主干网上使用掩码R-CNN。跟踪器是通过集成应用于骨干功能的3D卷积来创建的,并结合了视频的时间上下文。作为替代方案,还考虑了卷积LSTM,但与基线相比,后一种方法不会产生任何收益。

TrackR-CNN还通过关联头扩展了掩码R-CNN,以便能够随着时间的推移关联检测。这是一个完全连接的层,接收区域提案,并为每个提案输出一个关联向量。协会负责人的灵感来自暹罗网络和用于个人重新识别的嵌入向量。它使用批量硬三重丢失的视频序列改编进行训练,这是一种比原始三重丢失更有效的方法。为了产生最终结果,系统必须决定报告哪些检测结果。之前的帧检测和当前提案之间的匹配是使用匈牙利算法完成的,同时只允许对小于某个阈值的关联向量进行检测

3.5 Tracktor++

多对象跟踪基准由于其公共排行榜,可以更轻松地找到MOT的最新突破。CVPR 2019跟踪挑战推动了跟踪器准确性和速度的进步。Tracktor++以一种非常简单但有效的方法主导了排行榜。该模型通过计算边界框回归来预测物体在下一帧中的位置,而无需训练或优化任何跟踪数据。Tracktor++的对象检测器是通常具有101层ResNet和FPN的Faster R-CNN,在MOT17Det行人检测数据集上训练。
在这里插入图片描述
Tracktor++的主要想法是使用Faster R-CNN的回归分支进行帧到帧的跟踪,方法是从当前帧中提取功能,然后使用上一个帧的对象位置作为RoI池过程的输入,将其位置返回到当前帧中。它还利用了一些运动模型,例如基于图像注册的相机运动补偿和短期重新识别。重新识别方法缓存固定帧数的已停用轨道,然后将新检测到的轨道与它们进行比较,以便重新识别。轨道之间的距离由暹罗神经网络测量。

3.6 JDE

联合检测和嵌入(JDE)是最近与视网膜网络类似的提案,偏离了两阶段范式。这种单发检测器旨在解决多任务学习问题,即锚分类、边界框回归和嵌入学习。JDE使用Darknet-53作为骨干,以三尺度获取输入的特征映射。之后,使用上采样和残余连接将特征映射融合在一起。最后,预测头附在融合特征图的顶部,该特征图为上述三项任务输出密集的预测图。

在这里插入图片描述
为了实现对象跟踪,除了边界框和类外,JDE模型还在处理帧时输出外观嵌入向量。这些外观嵌入与使用亲和力矩阵对之前检测到的物体的嵌入进行比较。最后,良好的旧匈牙利算法和卡尔曼滤波器用于平滑轨迹并预测当前帧中之前检测到的物体的位置。

4 总结

总的来说在机器,配备GPU一样的情况下,使用同样的实例视频(MOT17测试数据集),不同的算法效果如下:

  • 由于其简单性,Deep SORT是这堆中最快的。它平均产生16FPS,同时仍然保持良好的准确性,这绝对使其成为多个物体检测的可靠选择。
  • Tracktor++相当准确,但一个大缺点是它不适合实时跟踪。我们的实验得出的平均执行率为3FPS。如果实时执行不令人担忧,这是一个很好的竞争者。
  • TrackR-CNN很好,因为它提供细分作为奖励。但与Tracktor++一样,它很难用于实时跟踪,平均执行率为1.6 FPS。
  • JDE平均表现出12FPS的良好表现。需要注意的是,该模型的输入大小为1088x608,因此,如果模型在全高清上训练,我们应该期望JDE达到较低的FPS。尽管如此,它具有很高的准确性,应该是一个很好的选择。

在这里插入图片描述

5 代码

5.1 目标检测代码

Detectron2是FAIR对象检测和分割框架的第二次迭代。它包括许多预训练的模型,可以在Model Zoo找到。如果你喜欢PyTorch,我建议使用Detectron2,它基本上是即插即用!

Detection2:https://github.com/facebookresearch/detectron2
不过,如果您更喜欢TensorFlow,您可以使用官方的TensorFlow对象检测API,在那里您可以找到代码以及预训练的Model Zoo。
TensorFlow API:https://github.com/tensorflow/models/tree/master/research/object_detection

5.1.1 Fast R-CNN

  • PyTorch:Detectron2
  • TensorFlow:TF对象检测API

5.1.2 Mask R-CNN

  • PyTorch:Detectron2
  • TensorFlow:TF对象检测API

5.1.3 YOLO

5.1.4 SSD

5.1.5 RetinaNet

5.2 目标跟踪代码

5.2.1 Recurrent YOLO

5.2.2 SiamMask

5.2.3 Deepsort

5.2.4 Track R-CNN

5.2.5 Tracktor++

5.2.6 JDE

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/346883
推荐阅读
相关标签
  

闽ICP备14008679号