目标检测
资讯
【2023-10-27】大模型时代目标检测任务会走向何方?
经典目标检测一般指闭集固定类别检测。新类型
Open Set
/Open World
/OOD
- 检测任何前景物体但有些不需要预测类别,unknown 标记
Open Vocabulary
- 开放词汇目标检测:给定任意词汇都可以检测出来
- 开放集任务,相比 open set,识别训练集类别外的新类别
- 这类模型需要接入文本作为一个模态输入。训练集和测试集的类别不能重复,但图片重复可以重复
- OVD 任务更加贴合实际应用,文本的描述不会有很大限制,同一个物体你可以采用多种词汇描述都可以检测出来
Phrase Grounding
, 也做phrase localization
。- 给定名词短语,输出对应的单个或多个物体检测框。
- Phrase Grounding 任务包括 OVD 任务。
- 常见的评估数据集是 Flickr30k Entities
- 如果是输入一句话,那么就是定位这句话中包括的所有名词短语。在 GLIP 得到了深入的研究。
Referring Expression Comprehension
简称REC
, 也称为 visual grounding。- 给定图片和一句话,输出对应的物体坐标,通常就是单个检测框。
- 常用的是 RefCOCO/RefCOCO+/RefCOCOg 三个数据集。是相对比较简单的数据集。这个任务侧重理解。
Description Object Detection
- 描述性目标检测也称 广义 Referring Expression Comprehension。
- 为何叫做广义,目前常用的 REC 问题:当前数据集只指代1个物体、没有负样本、正向描述
- Described Object Detection 论文提出新的数据集,命名为
DOD
。类似还有 gRefCOCO
Caption with Grounding
- 给定图片,要求模型输出图片描述,同时对于其中的短语都要给出对应的 bbox
- 像 Phrase Grounding 的反向过程。
- 这个任务可以方便将输出的名称和 bbox 联系起来,方便后续任务的进行。
Reasoning Intention-Oriented Object Detection
- 意图导向的目标检测,和之前的 DetGPT 提出的推理式检测非常类似。
- DetGPT 中的推理式检测含义是:给定文本描述,模型要能够进行推理,得到用户真实意图。
- 示例: 我想喝冷饮,LLM 会自动进行推理解析输出 冰箱 这个单词,从而可以通过 Grounding 目标检测算法把冰箱检测出来。模型具备推理功能。
- 论文 RIO: A Benchmark for Reasoning Intention-Oriented Objects in Open Environments
基于区域输入的理解和 Grounding
- 非常宽泛的任务,表示不仅可以输入图文模态,还可以输入其他任意模态,然后进行理解或者定位相关任务。
- 最经典的任务是 Referring expression generation:给定图片和单个区域,对该区域进行描述。常用的评估数据集是 RefCOCOg
- 现在也有很多新的做法,典型的如 Shikra 里面提到的 Referential dialogue,包括 REC,REG,PointQA,Image Caption 以及 VQA 5 个任务
背景
计算机视觉领域的典型任务就是目标检测
- 目标检测最新趋势:deep_learning_object_detection
- 发展历史:
- 【2020-4-23】技术总结
类型
- 目标检测(Object Detection),在计算机视觉领域的任务就是给定一张图片,将图片中的物体识别并且框定出来。
- object detection的算法主要可以分为两大类:two-stage detector和one-stage detector。
- One-Stage检测算法是指类似Faster RCNN,RFCN这样需要region proposal的检测算法,这类算法可以达到很高的准确率,但是速度较慢。虽然可以通过减少proposal的数量或降低输入图像的分辨率等方式达到提速,但是速度并没有质的提升。
- Two-Stage检测算法是指类似YOLO,SSD这样不需要region proposal,直接回归的检测算法,这类算法速度很快,但是准确率不如前者。
- PS:Multi-Stage检测算法的Selective Search、Feature extraction、Location regression、Class SVM等环节都是分开训练,操作繁杂而且效果不好,所以这里默认忽视。
- focal loss的出发点也是希望one-stage detector可以达到two-stage detector的准确率,同时不影响原有的速度。
- 参考:目标检测算法综述
- One-Stage检测算法的初衷是提升速度,而Two-Stage中比较耗时就是proposal建议区域生成,所以索性One-Stage方法就是直接从图像建议区域提取特征进行分类和定位回归。
- 图像建议区域是直接从backbone的特征层中进行密集选取,所以一些one-stage算法也称为密集检测器。同时可以看出,one-stage主要处理的问题是:特征提取、分类和定位回归。即关键点全部在特征提取这一块上。
- Two-Stage检测算法可以通过ROI pooling layer(以Faster R-CNN为例)进行结构划分,前部分提出可能存在目标的区域,后部分即目标分类和定位回归。结构如下
- two-stage主要处理的几个问题是:backbone进行特征提取、proposal建议区域的生成、分类和定位回归。
算法综述
- 【2018-4-7】从RCNN到SSD,这应该是最全的一份目标检测算法盘点
目标检测进行了整体回顾
- 第一部分从 RCNN 开始介绍基于候选区域的目标检测器,包括 Fast R-CNN、Faster R-CNN 和 FPN 等。
- 第二部分则重点讨论了包括 YOLO、SSD 和 RetinaNet 等在内的单次检测器,它们都是目前最为优秀的方法。
排行榜
- huggingface 榜单:object_detection_leaderboard
数据集
大白智能数据集汇总
基于候选区域的目标检测器
滑动窗口检测器
自从 AlexNet 获得 ILSVRC 2012 挑战赛冠军后,用 CNN 进行分类成为主流。一种用于目标检测的暴力方法是从左到右、从上到下滑动窗口,利用分类识别目标。为了在不同观察距离处检测不同的目标类型,我们使用不同大小和宽高比的窗口。
滑动窗口(从右到左,从上到下)
我们根据滑动窗口从图像中剪切图像块。由于很多分类器只取固定大小的图像,因此这些图像块是经过变形转换的。但是,这不影响分类准确率,因为分类器可以处理变形后的图像。
将图像变形转换成固定大小的图像
变形图像块被输入 CNN 分类器中,提取出 4096 个特征。之后,我们使用 SVM 分类器识别类别和该边界框的另一个线性回归器。
滑动窗口检测器的系统工作流程图。
下面是伪代码。我们创建很多窗口来检测不同位置的不同目标。要提升性能,一个显而易见的办法就是减少窗口数量。
for window in windows
patch = get_patch(image, window)
results = detector(patch)
选择性搜索
我们不使用暴力方法,而是用候选区域方法(region proposal method)创建目标检测的感兴趣区域(ROI)。在选择性搜索(selective search,SS)中,我们首先将每个像素作为一组。然后,计算每一组的纹理,并将两个最接近的组结合起来。但是为了避免单个区域吞噬其他区域,我们首先对较小的组进行分组。我们继续合并区域,直到所有区域都结合在一起。下图第一行展示了如何使区域增长,第二行中的蓝色矩形代表合并过程中所有可能的 ROI。
图源:van de Sande et al. ICCV’11
R-CNN
R-CNN 利用候选区域方法创建了约 2000 个 ROI。这些区域被转换为固定大小的图像,并分别馈送到卷积神经网络中。该网络架构后面会跟几个全连接层,以实现目标分类并提炼边界框。
使用候选区域、CNN、仿射层来定位目标。
以下是 R-CNN 整个系统的流程图:
通过使用更少且更高质量的 ROI,R-CNN 要比滑动窗口方法更快速、更准确。
ROIs = region_proposal(image)
for ROI in ROIs
patch = get_patch(image, ROI)
results = detector(patch)
边界框回归器
候选区域方法有非常高的计算复杂度。为了加速这个过程,我们通常会使用计算量较少的候选区域选择方法构建 ROI,并在后面使用线性回归器(使用全连接层)进一步提炼边界框。
使用回归方法将蓝色的原始边界框提炼为红色的。
Fast R-CNN
R-CNN 需要非常多的候选区域以提升准确度,但其实有很多区域是彼此重叠的,因此 R-CNN 的训练和推断速度非常慢。如果我们有 2000 个候选区域,且每一个都需要独立地馈送到 CNN 中,那么对于不同的 ROI,我们需要重复提取 2000 次特征。
此外,CNN 中的特征图以一种密集的方式表征空间特征,那么我们能直接使用特征图代替原图来检测目标吗?
直接利用特征图计算 ROI。
Fast R-CNN 使用特征提取器(CNN)先提取整个图像的特征,而不是从头开始对每个图像块提取多次。然后,我们可以将创建候选区域的方法直接应用到提取到的特征图上。例如,Fast R-CNN 选择了 VGG16 中的卷积层 conv5 来生成 ROI,这些关注区域随后会结合对应的特征图以裁剪为特征图块,并用于目标检测任务中。我们使用 ROI 池化将特征图块转换为固定的大小,并馈送到全连接层进行分类和定位。因为 Fast-RCNN 不会重复提取特征,因此它能显著地减少处理时间。
将候选区域直接应用于特征图,并使用 ROI 池化将其转化为固定大小的特征图块。
以下是 Fast R-CNN 的流程图:
在下面的伪代码中,计算量巨大的特征提取过程从 For 循环中移出来了,因此速度得到显著提升。Fast R-CNN 的训练速度是 R-CNN 的 10 倍,推断速度是后者的 150 倍。
feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
patch = roi_pooling(feature_maps, ROI)
results = detector2(patch)
Fast R-CNN 最重要的一点就是包含特征提取器、分类器和边界框回归器在内的整个网络能通过多任务损失函数进行端到端的训练,这种多任务损失即结合了分类损失和定位损失的方法,大大提升了模型准确度。
ROI 池化
因为 Fast R-CNN 使用全连接层,所以我们应用 ROI 池化将不同大小的 ROI 转换为固定大小。
为简洁起见,我们先将 8×8 特征图转换为预定义的 2×2 大小。
- 下图左上角:特征图。
- 右上角:将 ROI(蓝色区域)与特征图重叠。
- 左下角:将 ROI 拆分为目标维度。例如,对于 2×2 目标,我们将 ROI 分割为 4 个大小相似或相等的部分。
- 右下角:找到每个部分的最大值,得到变换后的特征图。
输入特征图(左上),输出特征图(右下),ROI (右上,蓝色框)。
按上述步骤得到一个 2×2 的特征图块,可以馈送至分类器和边界框回归器中。
Faster R-CNN
Fast R-CNN 依赖于外部候选区域方法,如选择性搜索。但这些算法在 CPU 上运行且速度很慢。在测试中,Fast R-CNN 需要 2.3 秒来进行预测,其中 2 秒用于生成 2000 个 ROI。
feature_maps = process(image)
ROIs = region_proposal(feature_maps) # Expensive!
for ROI in ROIs
patch = roi_pooling(feature_maps, ROI)
results = detector2(patch)
Faster R-CNN 采用与 Fast R-CNN 相同的设计,只是它用内部深层网络代替了候选区域方法。新的候选区域网络(RPN)在生成 ROI 时效率更高,并且以每幅图像 10 毫秒的速度运行。
Faster R-CNN 的流程图与 Fast R-CNN 相同。
外部候选区域方法代替了内部深层网络。
候选区域网络
候选区域网络(RPN)将第一个卷积网络的输出特征图作为输入。它在特征图上滑动一个 3×3 的卷积核,以使用卷积网络(如下所示的 ZF 网络)构建与类别无关的候选区域。其他深度网络(如 VGG 或 ResNet)可用于更全面的特征提取,但这需要以速度为代价。ZF 网络最后会输出 256 个值,它们将馈送到两个独立的全连接层,以预测边界框和两个 objectness 分数,这两个 objectness 分数度量了边界框是否包含目标。我们其实可以使用回归器计算单个 objectness 分数,但为简洁起见,Faster R-CNN 使用只有两个类别的分类器:即带有目标的类别和不带有目标的类别。
对于特征图中的每一个位置,RPN 会做 k 次预测。因此,RPN 将输出 4×k 个坐标和每个位置上 2×k 个得分。下图展示了 8×8 的特征图,且有一个 3×3 的卷积核执行运算,它最后输出 8×8×3 个 ROI(其中 k=3)。下图(右)展示了单个位置的 3 个候选区域。
此处有 3 种猜想,稍后我们将予以完善。由于只需要一个正确猜想,因此我们最初的猜想最好涵盖不同的形状和大小。因此,Faster R-CNN 不会创建随机边界框。相反,它会预测一些与左上角名为「锚点」的参考框相关的偏移量(如𝛿x、𝛿y)。我们限制这些偏移量的值,因此我们的猜想仍然类似于锚点。
要对每个位置进行 k 个预测,我们需要以每个位置为中心的 k 个锚点。每个预测与特定锚点相关联,但不同位置共享相同形状的锚点。
这些锚点是精心挑选的,因此它们是多样的,且覆盖具有不同比例和宽高比的现实目标。这使得我们可以以更好的猜想来指导初始训练,并允许每个预测专门用于特定的形状。该策略使早期训练更加稳定和简便。
Faster R-CNN 使用更多的锚点。它部署 9 个锚点框:3 个不同宽高比的 3 个不同大小的锚点框。每一个位置使用 9 个锚点,每个位置会生成 2×9 个 objectness 分数和 4×9 个坐标。
图源:https://arxiv.org/pdf/1506.01497.pdf
R-CNN 方法的性能
如下图所示,Faster R-CNN 的速度要快得多。
基于区域的全卷积神经网络(R-FCN)
假设我们只有一个特征图用来检测右眼。那么我们可以使用它定位人脸吗?应该可以。因为右眼应该在人脸图像的左上角,所以我们可以利用这一点定位整个人脸。
如果我们还有其他用来检测左眼、鼻子或嘴巴的特征图,那么我们可以将检测结果结合起来,更好地定位人脸。
现在我们回顾一下所有问题。在 Faster R-CNN 中,检测器使用了多个全连接层进行预测。如果有 2000 个 ROI,那么成本非常高。
feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
patch = roi_pooling(feature_maps, ROI)
class_scores, box = detector(patch) # Expensive!
class_probabilities = softmax(class_scores)
R-FCN 通过减少每个 ROI 所需的工作量实现加速。上面基于区域的特征图与 ROI 是独立的,可以在每个 ROI 之外单独计算。剩下的工作就比较简单了,因此 R-FCN 的速度比 Faster R-CNN 快。
feature_maps = process(image)
ROIs = region_proposal(feature_maps)
score_maps = compute_score_map(feature_maps)
for ROI in ROIs
V = region_roi_pool(score_maps, ROI)
class_scores, box = average(V) # Much simpler!
class_probabilities = softmax(class_scores)
现在我们来看一下 5 × 5 的特征图 M,内部包含一个蓝色方块。我们将方块平均分成 3 × 3 个区域。现在,我们在 M 中创建了一个新的特征图,来检测方块的左上角(TL)。这个新的特征图如下图(右)所示。只有黄色的网格单元 [2, 2] 处于激活状态。
在左侧创建一个新的特征图,用于检测目标的左上角。
我们将方块分成 9 个部分,由此创建了 9 个特征图,每个用来检测对应的目标区域。这些特征图叫作位置敏感得分图(position-sensitive score map),因为每个图检测目标的子区域(计算其得分)。
生成 9 个得分图
下图中红色虚线矩形是建议的 ROI。我们将其分割成 3 × 3 个区域,并询问每个区域包含目标对应部分的概率是多少。例如,左上角 ROI 区域包含左眼的概率。我们将结果存储成 3 × 3 vote 数组,如下图(右)所示。例如,vote_array[0][0] 包含左上角区域是否包含目标对应部分的得分。
将 ROI 应用到特征图上,输出一个 3 x 3 数组。
将得分图和 ROI 映射到 vote 数组的过程叫作位置敏感 ROI 池化(position-sensitive ROI-pool)。该过程与前面讨论过的 ROI 池化非常接近。
将 ROI 的一部分叠加到对应的得分图上,计算 V[i][j]。
在计算出位置敏感 ROI 池化的所有值后,类别得分是其所有元素得分的平均值。
ROI 池化
假如我们有 C 个类别要检测。我们将其扩展为 C + 1 个类别,这样就为背景(非目标)增加了一个新的类别。每个类别有 3 × 3 个得分图,因此一共有 (C+1) × 3 × 3 个得分图。使用每个类别的得分图可以预测出该类别的类别得分。然后我们对这些得分应用 softmax 函数,计算出每个类别的概率。
以下是数据流图,在我们的案例中,k=3。
总结
首先了解了基础的滑动窗口算法:
for window in windows
patch = get_patch(image, window)
results = detector(patch)
然后尝试减少窗口数量,尽可能减少 for 循环中的工作量。
ROIs = region_proposal(image)
for ROI in ROIs
patch = get_patch(image, ROI)
results = detector(patch)
单次目标检测器
第二部分,我们将对单次目标检测器(包括 SSD、YOLO、YOLOv2、YOLOv3)进行综述。我们将分析 FPN 以理解多尺度特征图如何提高准确率,特别是小目标的检测,其在单次检测器中的检测效果通常很差。然后我们将分析 Focal loss 和 RetinaNet,看看它们是如何解决训练过程中的类别不平衡问题的。
单次检测器
Faster R-CNN 中,在分类器之后有一个专用的候选区域网络。
Faster R-CNN 工作流
基于区域的检测器是很准确的,但需要付出代价。Faster R-CNN 在 PASCAL VOC 2007 测试集上每秒处理 7 帧的图像(7 FPS)。和 R-FCN 类似,研究者通过减少每个 ROI 的工作量来精简流程。
feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
patch = roi_align(feature_maps, ROI)
results = detector2(patch) # Reduce the amount of work here!
作为替代,我们是否需要一个分离的候选区域步骤?我们可以直接在一个步骤内得到边界框和类别吗?
feature_maps = process(image)
results = detector3(feature_maps) # No more separate step for ROIs
让我们再看一下滑动窗口检测器。我们可以通过在特征图上滑动窗口来检测目标。对于不同的目标类型,我们使用不同的窗口类型。以前的滑动窗口方法的致命错误在于使用窗口作为最终的边界框,这就需要非常多的形状来覆盖大部分目标。更有效的方法是将窗口当做初始猜想,这样我们就得到了从当前滑动窗口同时预测类别和边界框的检测器。
基于滑动窗口进行预测
这个概念和 Faster R-CNN 中的锚点很相似。然而,单次检测器会同时预测边界框和类别。例如,我们有一个 8 × 8 特征图,并在每个位置做出 k 个预测,即总共有 8 × 8 × k 个预测结果。
64 个位置
在每个位置,我们有 k 个锚点(锚点是固定的初始边界框猜想),一个锚点对应一个特定位置。我们使用相同的 锚点形状仔细地选择锚点和每个位置。
使用 4 个锚点在每个位置做出 4 个预测。
以下是 4 个锚点(绿色)和 4 个对应预测(蓝色),每个预测对应一个特定锚点。
4 个预测,每个预测对应一个锚点。
在 Faster R-CNN 中,我们使用卷积核来做 5 个参数的预测:4 个参数对应某个锚点的预测边框,1 个参数对应 objectness 置信度得分。因此 3× 3× D × 5 卷积核将特征图从 8 × 8 × D 转换为 8 × 8 × 5。
使用 3x3 卷积核计算预测。
在单次检测器中,卷积核还预测 C 个类别概率以执行分类(每个概率对应一个类别)。因此我们应用一个 3× 3× D × 25 卷积核将特征图从 8 × 8 × D 转换为 8 × 8 × 25(C=20)。
每个位置做出 k 个预测,每个预测有 25 个参数。
单次检测器通常需要在准确率和实时处理速度之间进行权衡。它们在检测太近距离或太小的目标时容易出现问题。在下图中,左下角有 9 个圣诞老人,但某个单次检测器只检测出了 5 个。
SSD
SSD 是使用 VGG19 网络作为特征提取器(和 Faster R-CNN 中使用的 CNN 一样)的单次检测器。我们在该网络之后添加自定义卷积层(蓝色),并使用卷积核(绿色)执行预测。
同时对类别和位置执行单次预测。
然而,卷积层降低了空间维度和分辨率。因此上述模型仅可以检测较大的目标。为了解决该问题,我们从多个特征图上执行独立的目标检测。
使用多尺度特征图用于检测。
以下是特征图图示。
图源:https://arxiv.org/pdf/1512.02325.pdf
SSD 使用卷积网络中较深的层来检测目标。如果我们按接近真实的比例重绘上图,我们会发现图像的空间分辨率已经被显著降低,且可能已无法定位在低分辨率中难以检测的小目标。如果出现了这样的问题,我们需要增加输入图像的分辨率。
YOLO
YOLO 全称 You Only Look Once(你只需看一次)
- 从名称上也能看出这种算法速度快的优势,因此在许多边缘设备上,YOLO算法的使用十分广泛。
与另一种著名的目标检测算法 Fast R-CNN
不同的是,YOLO
采用“一步”的策略,同时生成目标物体的类别和位置。
YOLO算法相比Fast R-CNN具有两大优势:
- 1、速度快:每秒45帧的检测速率,可用在实时视频检测中,在更小的模型上甚至达到155帧;
- 2、通用性好:在真实图像数据上训练的网络,可以用在虚构的绘画作品上。
但是YOLO也存在着一定的局限性:
- 正确率不如Fast R-CNN,每个方格中只能检测一个物体,对于边缘不规则的物体,将会影响到周围物体的识别。
作者Redmon后来又在原始的YOLO技术上,发展出了YOLO9000、YOLOv3等算法,扩展了检测物体的种类、提高了模型的准确率。
YOLO 资讯
【2020-2-22】YOLO之父退出CV界表达抗议,拒绝AI算法用于军事和隐私窥探
- Jeseph Redmon毕业于美国米德尔伯里学院计算机科学专业,辅修数学。2013年进入华盛顿大学计算机专业攻读硕士学位,继而攻读博士学位,直到2019年。
- 在此期间,他和导师Ali Farhadi共同提出并改进了YOLO算法。主要研究范围是目标检测、图像分类和模型压缩。
- Joseph Redmon曾凭借该算法获得过2016年CVPR群众选择奖(People’s Choice Award)、2017年CVPR最佳论文荣誉奖(Best Paper Honorable Mention)。
- YOLO及其改进算法在学术圈被广泛引用,Redmon三篇一作相关论文总引用量已经超过1万。
YOLO算法作者Joseph Redmon在个人Twitter上宣布,将停止一切CV研究,原因是自己的开源算法已经用在军事和隐私问题上。这对他的道德造成了巨大的考验。
YOLO 发展史
YOLO: A Brief History
【2023-11-14】ultralytics 官方文档
YOLO (You Only Look Once), a popular object detection and image segmentation model, was developed by Joseph Redmon and Ali Farhadi at the University of Washington.
- Launched in 2015, YOLO quickly gained popularity for its high speed and accuracy.
- YOLOv2, released in 2016, improved the original model by incorporating batch normalization, anchor boxes, and dimension clusters.
- YOLOv3, launched in 2018, further enhanced the model’s performance using a more efficient backbone network, multiple anchors and spatial pyramid pooling.
- YOLOv4 was released in 2020, introducing innovations like Mosaic data augmentation, a new anchor-free detection head, and a new loss function.
- YOLOv5 further improved the model’s performance and added new features such as hyperparameter optimization, integrated experiment tracking and automatic export to popular export formats.
- YOLOv6 was open-sourced by Meituan in 2022 and is in use in many of the company’s autonomous delivery robots.
- YOLOv7 added additional tasks such as pose estimation on the COCO keypoints dataset.
- YOLOv8 is the latest version of YOLO by Ultralytics. As a cutting-edge, state-of-the-art (SOTA) model, YOLOv8 builds on the success of previous versions, introducing new features and improvements for enhanced performance, flexibility, and efficiency. YOLOv8 supports a full range of vision AI tasks, including detection, segmentation, pose estimation, tracking, and classification. This versatility allows users to leverage YOLOv8’s capabilities across diverse applications and domains.
YOLO:简史
YOLO (You Only Look Once),由华盛顿大学的Joseph Redmon和Ali Farhadi开发的流行目标检测和图像分割模型,于2015年推出,由于其高速和准确性而迅速流行。
- YOLOv2 在2016年发布,通过引入批量归一化、锚框和维度聚类来改进了原始模型。
- YOLOv3 在2018年推出,进一步增强了模型的性能,使用了更高效的主干网络、多个锚点和空间金字塔池化。
- YOLOv4 在2020年发布,引入了Mosaic数据增强、新的无锚检测头和新的损失函数等创新功能。
- YOLOv5 进一步改进了模型的性能,并增加了新功能,如超参数优化、集成实验跟踪和自动导出到常用的导出格式。
- YOLOv6 在2022年由美团开源,现在正在该公司的许多自动送货机器人中使用。
- YOLOv7 在COCO关键点数据集上添加了额外的任务,如姿态估计。
- YOLOv8 是Ultralytics的YOLO的最新版本。作为一种前沿、最先进(SOTA)的模型,YOLOv8在之前版本的成功基础上引入了新功能和改进,以提高性能、灵活性和效率。YOLOv8支持全范围的视觉AI任务,包括检测, 分割, 姿态估计, 跟踪, 和分类。这种多功能性使用户能够利用YOLOv8的功能应对多种应用和领域的需求。
从v1到v8
【2023-1-16】YOLO家族系列模型的演变:从v1到v8
时间 | 版本 | 功能 | 备注 |
---|---|---|---|
2015 | v1 | ||
2016 | v2 | ||
2018 | v3 | ||
2019 | v4 | ||
2020 | v5 | ||
2021.5 | R | 结合显性和隐性知识,多任务 检测精度和检出率高于竞争对手 |
You Only Learn One Representation: Unified Network for Multiple Tasks |
2022 | v6 | 美团,三个改进点: backbone 和 neck部分对硬件进行了优化设计 forked head 更准确 更有效的训练策略 与YOLOv6-nano模型相比,YOLOv6-nano模型的速度提高了21%,精度提高了3.6% |
YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications 博客地址 |
2022.7 | v7 | sota,E-ELAN(扩展高效层聚合网络), pytorch 检测精度和检出率高于竞争对手 |
YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors |
2023.1 | v8 | Ultralytics发布,无锚点模型 YOLOv8领先于YOLOv7和YOLOv6等 |
论文尚未发表 |
yolo迭代到了v8版本
- 2017年在mac上试过v2,实时目标检测,挺灵敏;
- 后面几个版本迭代到手机部署,v5在手机上识别速度几十ms,手机识别
- YOLOv3之前的所有YOLO对象检测模型都是用C语言编写的,并使用了Darknet框架,Ultralytics发布了第一个使用PyTorch框架实现的YOLO (YOLOv3),YOLOv3发布后不久,Joseph Redmon就离开了计算机视觉研究社区。
- Ultralytics发布了YOLOv5
- 在2023年1月,Ultralytics发布了YOLOv8。
- YOLOv8包含五个模型,用于检测、分割和分类。YOLOv8 Nano是其中最快和最小的,而YOLOv8 Extra Large (YOLOv8x)是其中最准确但最慢的,具体模型见后续的图。
YOLOv8附带以下预训练模型:
- 目标检测在图像分辨率为640的COCO检测数据集上进行训练。
- 实例分割在图像分辨率为640的COCO分割数据集上训练。
- 图像分类模型在ImageNet数据集上预训练,图像分辨率为224。
图解
YOLO 原理
YOLO 是另一种单次目标检测器。
YOLO 在卷积层之后使用了 DarkNet 来做特征检测。
然而,它并没有使用多尺度特征图来做独立的检测。相反,它将特征图部分平滑化,并将其和另一个较低分辨率的特征图拼接。例如,YOLO 将一个 28 × 28 × 512 的层重塑为 14 × 14 × 2048,然后将它和 14 × 14 ×1024 的特征图拼接。之后,YOLO 在新的 14 × 14 × 3072 层上应用卷积核进行预测。
YOLO(v2)做出了很多实现上的改进,将 mAP 值从第一次发布时的 63.4 提高到了 78.6。YOLO9000 可以检测 9000 种不同类别的目标。
以下是 YOLO 论文中不同检测器的 mAP 和 FPS 对比。YOLOv2 可以处理不同分辨率的输入图像。低分辨率的图像可以得到更高的 FPS,但 mAP 值更低。
YOLOv3
YOLOv3 使用了更加复杂的骨干网络来提取特征。DarkNet-53 主要由 3 × 3 和 1× 1 的卷积核以及类似 ResNet 中的跳过连接构成。相比 ResNet-152,DarkNet 有更低的 BFLOP(十亿次浮点数运算),但能以 2 倍的速度得到相同的分类准确率。
图源:https://pjreddie.com/media/files/papers/YOLOv3.pdf
YOLOv3 还添加了特征金字塔,以更好地检测小目标。以下是不同检测器的准确率和速度的权衡。
图源:https://pjreddie.com/media/files/papers/YOLOv3.pdf
特征金字塔网络(FPN)
检测不同尺度的目标很有挑战性,尤其是小目标的检测。特征金字塔网络(FPN)是一种旨在提高准确率和速度的特征提取器。它取代了检测器(如 Faster R-CNN)中的特征提取器,并生成更高质量的特征图金字塔。
数据流
FPN(图源:https://arxiv.org/pdf/1612.03144.pdf)
FPN 由自下而上和自上而下路径组成。其中自下而上的路径是用于特征提取的常用卷积网络。空间分辨率自下而上地下降。当检测到更高层的结构,每层的语义值增加。
FPN 中的特征提取(编辑自原论文)
SSD 通过多个特征图完成检测。但是,最底层不会被选择执行目标检测。它们的分辨率高但是语义值不够,导致速度显著下降而不能被使用。SSD 只使用较上层执行目标检测,因此对于小的物体的检测性能较差。
图像修改自论文 https://arxiv.org/pdf/1612.03144.pdf
FPN 提供了一条自上而下的路径,从语义丰富的层构建高分辨率的层。
自上而下重建空间分辨率(编辑自原论文)
虽然该重建层的语义较强,但在经过所有的上采样和下采样之后,目标的位置不精确。在重建层和相应的特征图之间添加横向连接可以使位置侦测更加准确。
增加跳过连接(引自原论文)
下图详细说明了自下而上和自上而下的路径。其中 P2、P3、P4 和 P5 是用于目标检测的特征图金字塔。
FPN 结合 RPN
FPN 不单纯是目标检测器,还是一个目标检测器和协同工作的特征检测器。分别传递到各个特征图(P2 到 P5)来完成目标检测。
FPN 结合 Fast R-CNN 或 Faster R-CNN
在 FPN 中,我们生成了一个特征图的金字塔。用 RPN(详见上文)来生成 ROI。基于 ROI 的大小,我们选择最合适尺寸的特征图层来提取特征块。
困难案例
对于如 SSD 和 YOLO 的大多数检测算法来说,我们做了比实际的目标数量要多得多的预测。所以错误的预测比正确的预测要更多。这产生了一个对训练不利的类别不平衡。训练更多的是在学习背景,而不是检测目标。但是,我们需要负采样来学习什么是较差的预测。所以,我们计算置信度损失来把训练样本分类。选取最好的那些来确保负样本和正样本的比例最多不超过 3:1。这使训练更加快速和稳定。
推断过程中的非极大值抑制
检测器对于同一个目标会做出重复的检测。我们利用非极大值抑制来移除置信度低的重复检测。将预测按照置信度从高到低排列。如果任何预测和当前预测的类别相同并且两者 IoU 大于 0.5,我们就把它从这个序列中剔除。
Focal Loss(RetinaNet)
类别不平衡会损害性能。SSD 在训练期间重新采样目标类和背景类的比率,这样它就不会被图像背景淹没。Focal loss(FL)采用另一种方法来减少训练良好的类的损失。因此,只要该模型能够很好地检测背景,就可以减少其损失并重新增强对目标类的训练。我们从交叉熵损失 CE 开始,并添加一个权重来降低高可信度类的 CE。
例如,令 γ = 0.5, 经良好分类的样本的 Focal loss 趋近于 0。
编辑自原论文
这是基于 FPN、ResNet 以及利用 Focal loss 构建的 RetianNet。
RetinaNet
YOLOX
【2021-10-8】2021年旷视科技推出yolox,YOLOX: Exceeding YOLO Series in 2021, 手把手教你使用YOLOX进行物体检测
YOLOX 是旷视开源的高性能检测器。旷视的研究者将解耦头、数据增强、无锚点以及标签分类等目标检测领域的优秀进展与 YOLO 进行了巧妙的集成组合,提出了 YOLOX,不仅实现了超越 YOLOv3、YOLOv4 和 YOLOv5 的 AP,而且取得了极具竞争力的推理速度。YOLOX-L版本以 68.9 FPS 的速度在 COCO 上实现了 50.0% AP,比 YOLOv5-L 高出 1.8% AP!还提供了支持 ONNX、TensorRT、NCNN 和 Openvino 的部署版本
部署实践
(1)环境准备
- 环境确认
- 先判断Windows系统是32位还是64位,再选择对应的工具包
- x86-64是64位版本,x86是32位版本
- 所有客户端软件都需要注意32还是64位
- 简洁方法: 右键 → 计算机 → 属性 → 系统类型
- 详细方法见微软官方文档
- 先判断Windows系统是32位还是64位,再选择对应的工具包
- Git工具安装
- windows安装git bash,参考地址
- 注意:
- Python环境安装
- windows安装Python3,下载地址
(2)yolox下载部署
- 使用git下载代码到本地计算机
- 进入目录 YOLOX,本地安装
git clone git@github.com:Megvii-BaseDetection/YOLOX.git
cd YOLOX
pip3 install -v -e . # or python3 setup.py develop
(3)数据准备
- 准备测试视频
- 可以从pixbay下载高速免费视频
(4)下载模型
从GitHub下载模型文件到本地model目录
- 以下是shell脚本,windows下需要手工下载、操作
mkdir model
cd model
wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l.pth
(5)启动
# ==== image demo =====
#python tools/demo.py image -f exps/default/yolox_s.py -c /path/to/your/yolox_s.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device [cpu/gpu]
#python tools/demo.py image -n yolox-s -c $model_file --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device cpu # gpu
# 更换模型时,需要同步更新3个参数
model_name='yolox-l'
model_file='model/yolox_l.pth'
tsize=640
python tools/demo.py image -n $model_name -c $model_file --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize $tsize --save_result --device cpu
# ==== video demo =====
# python tools/demo.py video -n yolox-s -c /path/to/your/yolox_s.pth --path /path/to/your/video --conf 0.25 --nms 0.45 --tsize 640 --save_result --device [cpu/gpu]
python tools/demo.py video -n $model_name -c $model_file --path /path/to/your/video --conf 0.25 --nms 0.45 --tsize $tsize --save_result --device cpu
【2023-11-8】实践通过
cur_dir='YOLOX'
#python tools/demo.py image -n yolox-l -c model/yolox_l.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device cpu
model_name='yolox-l'
model_file="${cur_dir}/model/yolox_l.pth"
tsize=640
# ==== image demo =====
data_file="${cur_dir}/assets/dog.jpg"
cmd="python ${cur_dir}/tools/demo.py image -n $model_name -c $model_file --path $data_file --conf 0.25 --nms 0.45 --tsize $tsize --save_result --device cpu"
echo "$cmd" && eval $cmd
# ==== video demo =====
data_file='../data/road_human.mp4'
# python tools/demo.py video -n yolox-s -c /path/to/your/yolox_s.pth --path /path/to/your/video --conf 0.25 --nms 0.45 --tsize 640 --save_result --device [cpu/gpu]
cmd="python tools/demo.py video -n $model_name -c $model_file --path $data_file --conf 0.25 --nms 0.45 --tsize $tsize --save_result --device cpu"
echo "$cmd" && eval $cmd
YOLO V5
2020年5月发布YOLOv5,最大的特点就是模型小,速度快,所以能很好的应用在移动端。
【2021-12-7】用安卓手机解锁目标检测模型YOLOv5,识别速度不过几十毫秒
- YOLO最新:v5版本,可在手机上玩儿了!只需要区区几十毫秒,桌上的东西就全被检测出来了
- yolov5s_android
YOLO v8
【2023-9-12】用YOLOv8一站式解决图像分类、检测、分割,淡化YOLO版本,主打Ultralytics平台。YOLO原本是一种公开的目标检测算法。优势是速度快,准确率还高.
yolov8 功能
v8版本不局限于目标检测,更像是一个AI视觉处理平台,不但可以做检测,还可以做分类、分割、跟踪,甚至姿态估计。
功能
- Detection (COCO) 检测
- Detection (Open Image V7)
- Segmentation (COCO) 分割
- Pose (COCO) 姿态估计
- Classification (ImageNet) 分类
yolov8 模型
YOLOv8针对COCO数据集(一个很好的计算机视觉数据集)训练生成的。
- 可以自行使用labelImg进行图片标记,扩充数据集
名称 | 模型文件 | 家族 |
---|---|---|
检测 | yolov8n.pt | 8n、8s、8m、8l、8x |
分割 | yolov8n-seg.pt | 8n、8s、8m、8l、8x |
分类 | yolov8n-cls.pt | 8n、8s、8m、8l、8x |
姿态 | yolov8n-pose.pt | 8n、8s、8m、8l、8x |
每一类模型包含一个家族。好比是同一款衣服的不同尺码
类型 | 准确度 | 耗时长 | 运算次数/秒 |
---|---|---|---|
YOLOv8n | 37.3 | 80.4 | 8.7 |
YOLOv8s | 44.9 | 128.4 | 28.6 |
YOLOv8m | 50.2 | 234.7 | 78.9 |
YOLOv8l | 52.9 | 375.2 | 165.2 |
YOLOv8x | 53.9 | 479.1 | 257.8 |
yolov8 实践
安装
# 安装
pip install ultralytics
# 测试, 模型文件才 7m !
#yolo predict model=yolov8n.pt source=bus.jpg
yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg'
目标检测
代码调用
# 从平台库导入YOLO类
from ultralytics import YOLO
# 从模型文件构建model
model = YOLO("xx.pt")
# 对某张图片进行预测
results = model("bus.jpg")
# 打印识别结果
print(results)
# -----------
from ultralytics import YOLO
from PIL import Image
model = YOLO('yolov8n-seg.pt')
image = Image.open("bus.jpg")
results = model.predict(source=image, save=True, save_txt=True)
# 识别来自文件夹的图像
results = model.predict(source="test/pics", ……)
# 识别来自摄像头的图像
results = model.predict(source="0", ……)
# 查看结果
results[0].boxes
results[0].masks
# -------------
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8n.yaml") # build a new model from scratch
model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training)
# Use the model
model.train(data="coco128.yaml", epochs=3) # train the model
metrics = model.val() # evaluate model performance on the validation set
results = model("https://ultralytics.com/images/bus.jpg") # predict on an image
path = model.export(format="onnx") # export the model to ONNX format
results 类
- boxes: 检测出来物体的矩形框,就是目标检测的框。
- masks: 检测出来的遮罩层,调用图像分割时,这项有数据。
- keypoints: 检测出来的关键点,人体姿势估计时,身体的点就是这项。
- names: 分类数据的名称,比如{0: 人,1: 狗}这类索引。
目标跟踪
from ultralytics import YOLO
# Load an official or custom model
model = YOLO('yolov8n.pt') # Load an official Detect model
model = YOLO('yolov8n-seg.pt') # Load an official Segment model
model = YOLO('yolov8n-pose.pt') # Load an official Pose model
# model = YOLO('path/to/best.pt') # Load a custom trained model
# Perform tracking with the model
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True) # Tracking with default tracker
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml") # Tracking with ByteTrack tracker
端侧 目标检测
YOLO-NAS
YOLO-NAS 是一款基于YOLO系列的全新对象检测模型,采用NAS技术进行预训练,并在COCO、Objects365和Roboflow 100等数据集上进行了验证,实现了前所未有的精度-速度性能。
mediapipe
【2023-10-26】Google发布移动终端对象检测模型 —— mediapipe,无GPU依然飞快
而Google的mediapipe系列则成功将对象检测模型运行在移动终端上,实现了ms级别的延时。对于没有GPU的情况,可以使用MediaPipe对象检测模型,其int8模型只有29.31ms的延时,最大模型也只有198.77ms的延时
实践
- 【2021-5-18】4种YOLO目标检测的C++和Python两种版本实现
- 2020年,新出了几个新版本的YOLO目标检测,最多的有YOLOv4,Yolo-Fastest,YOLObile以及百度提出的PP-YOLO。C++编写一套基于OpenCV的YOLO目标检测,这个程序里包含了经典的YOLOv3,YOLOv4,Yolo-Fastest和YOLObile这4种YOLO目标检测的实现
- Yolo-Fastest运行速度最快,YOLObile号称是实时的,但是从结果看并不如此。并且查看它们的模型文件,可以看到Yolo-Fastest的是最小的。
- opencv实现yolov5目标检测,程序依然是包含了C++和Python两种版本的实现,地址: python, C++
应用案例
无人机
大疆航拍巡查
无人机航空航拍技术应用,环境监测、水利巡检、交通巡查、线路巡检
河道巡查
全球领先的低空无人机遥感网运营商: 广州中科云图
- 公众号: GEOAI中科云图
无人机高效巡检河道违法捕捞和周围篷房违建
-
AI 识别船只、漂浮物和垃圾堆放
- 一巢三机
- 首创“一巢三机”智能化无人机飞行控制平台,机动性更强,作业能力覆盖更广。
- 5G+微波
- 超低延时图传,多重控制保障,飞行全程可控。
- 全局掌控
- 丰富感知负载,多源信息采集;低空飞行,提供720°全局视野。
- 机载AI
- 首创“无人机”智能负载,集成21T超强算力AI芯片,实现物体识别与目标跟踪。
实时检测
实时人物分割
- 【2019-04-11】浏览器上跑:TensorFlow发布实时人物分割模型,秒速25帧24个部位
- TensorFlow开源了一个实时人物分割模型,叫BodyPix。这个模型,在浏览器上用TensorFlow.js就能跑。而且,帧率还很可观,在默认设定下:
- 用2018版15吋MacBook Pro跑,每秒25帧。用iPhone X跑,每秒21帧。
- 如果不和其他模型搭配的话,BodyPix只适用于单人影像。
- TensorFlow开源了一个实时人物分割模型,叫BodyPix。这个模型,在浏览器上用TensorFlow.js就能跑。而且,帧率还很可观,在默认设定下:
OpenPose
【2024-1-12】实时多人关键点AI检测开源!
OpenPose 是一个开源的实时多人关键点检测库,由卡内基梅隆大学的感知计算实验室(Perceptual Computing Lab)开发。它旨在通过深度学习技术实现高效的人体姿态估计,并可以同时检测多个人的身体、面部、手部和脚部的关键点。
OpenPose 的出现为人体姿态估计领域带来了重要的突破,特别是在实时性和多人检测方面。img
核心特点
- 实时性:OpenPose 设计用于实时处理,可以在接近实时的时间内完成关键点检测。
- 多人检测:OpenPose 能够在单张图像中同时检测多个人的姿态,这对于多人交互场景尤为重要。
- 关键点检测:它可以识别和定位人体、面部、手部和脚部的关键点,总共超过 135 个关键点。
- 灵活性:OpenPose 支持多种编程语言和框架,包括 Python、C++ 和 MATLAB,以及 TensorFlow、Caffe 和 PyTorch 等。
- 开源:OpenPose 是开源的,这意味着任何人都可以自由使用和修改代码,以适应不同的应用需求。
应用场景
- 增强现实和虚拟现实:在 AR/VR 应用中,OpenPose 可以用来跟踪用户的身体和手部动作,提供更自然的交互体验。
- 人机交互:OpenPose 可以用于智能助手和机器人,帮助它们更好地理解和响应用户的需求。
- 体育分析:在体育比赛中,OpenPose 可以用来分析运动员的姿态和动作,提供战术和训练建议。
- 安全监控:在安全监控领域,OpenPose 可以用来识别异常行为或特定姿态,提高监控系统的有效性。
基于tensorflow.js的实时检测Demo
实时检测Demo
站内demo
代码
- detect.js内容
class App extends React.Component {
// reference to both the video and canvas
videoRef = React.createRef();
canvasRef = React.createRef();
// we are gonna use inline style
styles = {
position: 'fixed',
top: 150,
left: 150,
};
detectFromVideoFrame = (model, video) => {
model.detect(video).then(predictions => {
this.showDetections(predictions);
requestAnimationFrame(() => {
this.detectFromVideoFrame(model, video);
});
}, (error) => {
console.log("Couldn't start the webcam")
console.error(error)
});
};
showDetections = predictions => {
const ctx = this.canvasRef.current.getContext("2d");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const font = "24px helvetica";
ctx.font = font;
ctx.textBaseline = "top";
predictions.forEach(prediction => {
const x = prediction.bbox[0];
const y = prediction.bbox[1];
const width = prediction.bbox[2];
const height = prediction.bbox[3];
// Draw the bounding box.
ctx.strokeStyle = "#2fff00";
ctx.lineWidth = 1;
ctx.strokeRect(x, y, width, height);
// Draw the label background.
ctx.fillStyle = "#2fff00";
const textWidth = ctx.measureText(prediction.class).width;
const textHeight = parseInt(font, 10);
// draw top left rectangle
ctx.fillRect(x, y, textWidth + 10, textHeight + 10);
// draw bottom left rectangle
ctx.fillRect(x, y + height - textHeight, textWidth + 15, textHeight + 10);
// Draw the text last to ensure it's on top.
ctx.fillStyle = "#000000";
ctx.fillText(prediction.class, x, y);
ctx.fillText(prediction.score.toFixed(2), x, y + height - textHeight);
});
};
componentDidMount() {
if (navigator.mediaDevices.getUserMedia || navigator.mediaDevices.webkitGetUserMedia) {
// define a Promise that'll be used to load the webcam and read its frames
const webcamPromise = navigator.mediaDevices
.getUserMedia({
video: true,
audio: false,
})
.then(stream => {
// pass the current frame to the window.stream
window.stream = stream;
// pass the stream to the videoRef
this.videoRef.current.srcObject = stream;
return new Promise(resolve => {
this.videoRef.current.onloadedmetadata = () => {
resolve();
};
});
}, (error) => {
console.log("Couldn't start the webcam")
console.error(error)
});
// define a Promise that'll be used to load the model
const loadlModelPromise = cocoSsd.load();
// resolve all the Promises
Promise.all([loadlModelPromise, webcamPromise])
.then(values => {
this.detectFromVideoFrame(values[0], this.videoRef.current);
})
.catch(error => {
console.error(error);
});
}
}
// here we are returning the video frame and canvas to draw,
// so we are in someway drawing our video "on the go"
render() {
return (
<div>
<video
style={this.styles}
autoPlay
muted
ref={this.videoRef}
width="720"
height="600"
/>
<canvas style={this.styles} ref={this.canvasRef} width="720" height="650" />
</div>
);
}
}
const domContainer = document.querySelector('#root');
ReactDOM.render(React.createElement(App), domContainer);
- 更多Demo地址
事件检测
视频事件检测
【2022-11-8】AI视频事件检测系统—JXVA8000系列
捷迅技术“JXVA”系列产品基于AI人工智能的深度学习算法以及GPU技术,对视频图像事件进行分析识别。利用视频大数据开展视频智能化应用服务实现对高速公路的交通事件和交通态势进行实时、精准检测
对交通道路正常交通秩序的事件进行实时检测,及时发现行人、车辆、物品等异常行为,并进行全客户端实时告警。实现对高速公路的交通事件和交通态势进行实时、精准检测,事件检测精准度达99%。对接高速公路车道监控摄像机的视频流,获取瞬间截面车流信息,为管理者提供实时的车流信息,为后续交通大数据的统计和预测做数据储备。
核心功能
- 交通事件分析
- 交通态势分析
- 路面智能养护
- 路网事件分析
优点
- ◆ 识别准确率高:识别准确率高达96%以上
- ◆ 自学习、自优化、越用越智能
- 具备在线自动学习能力,模型上线使用之后识别准确率不断提高
- ◆ 识别事件类型多
- 对道路行人、违停、拥堵、逆行、压线、超速、慢行、抛洒物等多种交通事件进行检测
交通事件检测功能点
- 停车
- 行人
- 遗留物
- 事故
- 拥堵
- 非机动车
- 变道检测
- 违规逆行
交通态势分析
- 交通流量检测
- 平均车速检测
- 排队长度检测
- 车道空间占有率
摄像头智能巡检
- 视频缺失
- 视频遮挡
- 视频卡顿
- 视频模糊
- 色彩失真
- 异常抖动
卡尔曼滤波
【2022-8-25】图说卡尔曼滤波,一份通俗易懂的教程
卡尔曼滤波
(Kalman filter)是一种高效的自回归滤波器,它能在存在诸多不确定性情况的组合信息中估计动态系统的状态,是一种强大的、通用性极强的工具。它的提出者 鲁道夫.E.卡尔曼,在一次访问NASA埃姆斯研究中心时,发现这种方法能帮助解决阿波罗计划的轨道预测问题,后来NASA在阿波罗飞船的导航系统中确实也用到了这个滤波器。最终,飞船正确驶向月球,完成了人类历史上的第一次登月。
滤波器
【2022-8-25】滤波器(Filter)
- 对特定频率进行有效提取,并对提取部分进行特定的处理(增益,衰减,滤除)的动作被叫做滤波。
- 在混音领域中,最常用的滤波器类型有三种:
通过式
(Pass),搁架式
(Shelving)和参量式
(Parametric)。滤波器都有一个叫参考频率
(Reference Frequency)的东西,在不同类型的滤波器中,具体的叫法会有所不同。
通过式滤波器可以让参考频率一侧的频率成分完全通过该滤波器,同时对另一侧的频率成分做线性的衰减,用白话讲就是,一边让通过,一边逐渐被滤除。在信号学中,通过的区域被称为通带,滤除的区域被叫做阻带(图1)。另外,在通过式滤波器中,参考频率通常被称为截止频率。
- 高通滤波器(high-pass filters):顾名思义,让截止频率后的高频区域通过,另一侧滤除,通常被简称为HPF(参考图1)。
- 低通滤波器(low-pass filters):让截止频率前的低频区域通过,另一侧滤除,通常被简称为LPF(参考图1)。
滤波器
- 只要是存在不确定信息的动态系统,卡尔曼滤波就可以对系统下一步要做什么做出有根据的推测。即便有噪声信息干扰,卡尔曼滤波通常也能很好的弄清楚究竟发生了什么,找出现象间不易察觉的相关性。
- 卡尔曼滤波非常适合不断变化的系统,它的优点还有内存占用较小(只需保留前一个状态)、速度快,是实时问题和嵌入式系统的理想选择。
示例:机器人导航
一个树林里四处溜达的小机器人,为了让它实现导航,机器人需要知道自己所处的位置。即机器人有一个包含位置信息和速度信息的状态
- 小机器人装有GPS传感器,定位精度10米
- 这个示例中的状态是位置和速度,其他问题里可以是水箱里的液体体积、汽车引擎温度、触摸板上指尖的位置,或者其他任何数据。
如何预测机器人移动?把指令发送给控制轮子的马达
- 如果这一刻它始终朝一个方向前进,没有遇到任何障碍物,那么下一刻它可能会继续坚持这个路线。
- 但是机器人对自己的状态不是全知的:可能会逆风行驶,轮子打滑,滚落颠簸地形…… 所以车轮转动次数并不能完全代表实际行驶距离,基于这个距离的预测也不完美。
这个问题下,GPS为提供了一些关于状态的信息是间接的、不准确的;预测提供了关于机器人轨迹的信息,但那也是间接的、不准确的。
但以上就是能够获得的全部信息,在此基础上能否给出一个完整预测,让它的准确度比机器人搜集的单次预测汇总更高?卡尔曼滤波,这个问题可以迎刃而解。
卡尔曼滤波假设两个变量(位置和速度)都是随机且符合高斯分布。每个变量都有一个均值 u,它是随机分布的中心;有一个方差 δ,它衡量组合的不确定性。
- 左图里,位置和速度是不相关的,这意味着不能从一个变量推测另一个变量
- 右图里,相关
如果基于旧位置估计新位置,会产生这两个结论:
- 如果速度很快,机器人可能移动得更远,所以得到的位置会更远;
- 如果速度很慢,机器人就走不了那么远。
这种关系对目标跟踪
来说非常重要,因为它提供了更多信息:一个可以衡量可能性的标准。这就是卡尔曼滤波的目标:从不确定信息中挤出尽可能多的信息!
为了捕获这种相关性,用协方差矩阵
。矩阵的每个值是第i个变量和第j个变量之间的相关程度(由于矩阵是对称的,i和j的位置可以随便交换)。用 Σ 表示协方差矩阵,在这个例子中,就是Σij。
YOLO + SAM
【2024-5-23】YOLO 和 SAM 强强联合能干什么大事
两种开创性模型之间的动态协同:YOLO
(You Only Look Once)和 SAM
(Segment Anything Model)
- YOLO 因其在目标检测方面的革命性进展而备受赞誉
- SAM(Segment Anything Model)是 Meta 在 2023 年推出,一种革命性的图像分割模型。以其卓越的性能而著称,SAM 已巩固了其作为最先进的分割模型之一的地位。
- SAM 在图像分割技术方面代表了一项突破性的进展,提供了前所未有的精确性和多功能性。与传统的受特定对象类型或环境限制的分割模型不同,SAM 凭借先进的神经网络架构和在大型数据集上进行的广泛训练,能够以无与伦比的准确性分割图像中的几乎任何对象。
- SAM 的架构采用多阶段的图像分割方法。其核心是一系列互联的神经网络模块,每个模块都针对分割过程的不同方面进行处理。
将 YOLO(You Only Look Once)与 SAM(Segment Anything Model)结合起来,提供了一个强大的协同效应,增强了两个模型的能力。 YOLO 在快速识别图像中的对象方面表现出色,而 SAM 在高精度分割对象方面具有优势。
- 通过将 YOLO 与 SAM 嵌入在一起,可以利用这两个模型的优势,实现更全面和准确的图像分析。
- 这种集成不仅可以检测对象,还可以精确地描绘它们的边界,为下游任务提供更丰富的上下文信息。
- 此外,将 YOLO 与 SAM 嵌入在一起,可以更稳健和高效地处理复杂的视觉数据,在自动驾驶、医学成像和监控系统等应用中具有不可估量的价值。
应用:
- 自动驾驶车辆:增强目标检测和分割能力,确保自动驾驶汽车的安全导航和决策。
- 医学成像:通过精确识别和分割医学图像中的异常,提高诊断准确性,如 X 光片、MRI 和 CT 扫描。
- 监控系统:通过精确检测和分割感兴趣的对象,提高公共场所的安全监控。
- 工业自动化:通过检测和分割装配线上制造产品中的缺陷,优化质量控制过程。
- 农业:通过精确识别和分割农业图像中的植物和害虫,协助作物监测和害虫检测。
- 环境监测:通过检测和分割卫星图像中的树木、水体和野生动物,帮助监测和分析环境变化。
- 增强现实:通过精确检测和分割现实世界中的物体,提升 AR 应用的沉浸式用户体验。
- 零售分析:通过精确检测和分割零售环境中的产品,改善客户分析和库存管理。
总之,SAM(Segment Anything Model)和 YOLO(You Only Look Once)的融合代表了图像分析领域的重大进步,在各个领域具有深远的影响。这一整合结合了 YOLO 在目标检测方面的敏锐性和 SAM 在分割方面的精确性,使我们能够从视觉数据中获得更深入的见解。从优化自动驾驶车辆的感知系统到帮助医学专家诊断疾病,SAM+YOLO 的协同潜力远远超越了传统边界。
代码实践见原文
姿态识别
数据集
【2024-4-22】人体姿态识别这9个数据集,
(1)HiEve数据集
数据集图片:原文
•在以人为中心的分析和了解复杂事件中,鼓励并加快新技术的开发。
•在“复杂事件中的大型以人为中心的视觉分析”方面培养新的思想和方向。
数据集内容:HiEve数据集,主要包括在各种人群和复杂事件(包括地铁上下车,碰撞,战斗
和地震逃生)中,以人为中心的非常具有挑战性和现实性的任务。
数据集数量:HiEve数据集包括当前最大的姿势数(> 1M),最大的复杂事件动作标签的数量(> 56k),并且是具有最长期限的轨迹的最大数量之一(平均轨迹长度> 480)。
数据集功能:人体检测、姿态识别、目标追踪、动作识别
下载链接:点击查看
(2)MPII Human Pose数据集
数据集图片:原文
数据集内容:MPII Human Pose数据集,是用于评估人体姿势识别的数据集。
数据集涵盖了410种人类活动,并且每个图像都带有活动标签。每个图像都是从YouTube视频中提取的,并提供了之前和之后的未注释帧。
此外,对于测试集,我们标注了丰富的注释,包括身体部位遮挡以及3D躯干和头部方向。
数据集数量:该数据集包含约 25K图像,其中对超过4万名人体进行关节标注。
数据集功能:姿态识别
下载链接:点击查看
(3)CrowdPose数据集
数据集图片:原文
数据集内容:CrowdPose数据集是一个用于拥挤场景姿势估计的新基准数据集,可用于拥挤场景下姿势估计问题。
数据集功能:姿态识别
下载链接:点击查看
(4)Human3.6M
数据集图片:原文
数据集内容:Human3.6M数据集是一个3D人体姿态识别的数据集,通过4个经过校准的摄像机拍摄获得,对于3D人体的24个部位位置和关节角度都有标注。
数据集数量:Human3.6M数据集包含360万个3D人体姿势图像,11名专业演员(男6名,女5名),17个场景(讨论,吸烟,拍照,通电话…)。
数据集功能:姿态识别、3维重建
下载链接:点击查看
(5)PedX数据集
数据集图片:原文
数据集内容:PedX 数据集是一个在复杂的城市交叉路口,对于行人进行采集的大规模多模式数据集。
该数据集提供高分辨率的立体图像,和具有手动2D和自动3D注释的LiDAR数据。此外,数据是使用两对立体相机和四个Velodyne LiDAR传感器进行的采集。
数据集功能:人体分割、姿态识别、人体检测
下载链接:点击查看
(6)SURREAL数据集
数据集图片:原文
数据集内容:SURREAL数据集是一个大规模人造姿态识别数据集,对于RGB视频,对多种状态进行标注:深度信息,身体部位,光流,2D / 3D姿势等。这些图像是在形状,纹理,视点和姿势有很大变化的情况下,对人物的真实渲染。
数据集数量:数据集包含600万帧合成人体数据
数据集功能:姿态识别、人体分割
下载链接:点击查看
(7)Mo2Cap2数据集
数据集图片:原文
数据集内容:硬件设置的移动性,在各种无限制的日常活动中,对3D人体姿势估计的稳定性会有影响。
因此,在Mo2Cap2数据集中,将头部的棒球帽,安装上一个鱼眼镜头类型的,高质量姿势估计设备。
除了新颖的硬件设置,该数据集主要贡献是:
(1)大型的自顶向下的鱼眼图像地面,实况训练数据集;
(2)一种新颖的3D姿态估计方法,该方法考虑了以自我为中心的独特属性。与现有算法基准相比,可以实现了更低的3D关节误差以及更好的2D覆盖。
数据集功能:姿态估计
下载链接:点击查看
(8)DensePose数据集
数据集图片:原文
数据集内容:DensePose数据集是户外的密集人体姿势估计数据集,目的在于建立从2D图像到人体表面的多关键点密集对应关系。标注过程主要分为两个阶段:
- 第一阶段:标注人员会标注出身体部位,可见的对应区域。当然对于后面的身体部位,标注人员会进行估算标注。
- 第二阶段:使用一组大致等距的关键点,对每个零件区域进行采样,并要求标注人员将这些点与表面相对应,从而得到最终的标注信息。
数据集数量:DensePose数据集,对5万个人进行了标注,超过500万个标注信息。
数据集功能:姿态识别、人体分割
下载链接:点击查看
(9)PoseTrack 数据集
数据集图片:原文
数据集内容:PoseTrack 数据集是用于人体姿势估计和视频中的关节跟踪的大型数据集,主要应用于两种挑战:“多人姿势估计”和“多人姿势跟踪”。
数据集数量:数据集中包含1356个视频序列,46000张标注的视频帧,276000个人体姿势标注信息。
数据集功能:姿态估计、姿态跟踪
下载链接:点击查看
目标跟踪
目标跟踪是计算机视觉领域的一个重要问题,目前广泛应用在体育赛事转播、安防监控和无人机、无人车、机器人等领域。
目标跟踪应用
应用领域 | 内容 | 示意 |
---|---|---|
体育赛事 | 比赛转播 | |
无人车 | 车辆跟踪 |
目标跟踪分类
目标跟踪任务分类
目标跟踪可以分为以下几种任务
- 单目标跟踪 - 给定一个目标,追踪这个目标的位置。
- 多目标跟踪 - 追踪多个目标的位置
- Person Re-ID - 行人重识别,是利用计算机视觉技术判断图像或者视频序列中是否存在特定行人的技术。广泛被认为是一个图像检索的子问题。给定一个监控行人图像,检索跨设备下的该行人图像。旨在弥补固定的摄像头的视觉局限,并可与行人检测/行人跟踪技术相结合。
- MTMCT - 多目标多摄像头跟踪(Multi-target Multi-camera Tracking),跟踪多个摄像头拍摄的多个人
- 姿态跟踪 - 追踪人的姿态
按照任务计算类型又可以分为以下2类。
- 在线跟踪 - 在线跟踪需要实时处理任务,通过过去和现在帧来跟踪未来帧中物体的位置。
- 离线跟踪 - 离线跟踪是离线处理任务,可以通过过去、现在和未来的帧来推断物体的位置,因此准确率会在线跟踪高。
单目标跟踪(SOT)
单目标跟踪是在有噪声的传感器测量时间序列中确定单个目标的状态,状态包括:
- 位置Position
- 描述目标运动的状态量(eg:vel,heading)
- 一些其他感兴趣的特征(eg:shape,class)
Introduction of SOT
本质上单目标跟踪就是一个滤波问题。img
单目标追踪的任务:追踪博尔特任务, 在下图视频中
- 第一帧中框定追踪目标(不局限于类别)作为人为先验信息(如博尔特),来确定追踪的目的
- 最终在视频后续的所有帧中都能跟踪出在第一帧中框定的目标,达到长时间跟踪的目的,可能在第一帧场景变化小,但是如果切换到视频的一百帧甚至三百帧,场景变化大,此时能够根据在第一帧的认为先验性息来跟踪所有帧中乃至于不同视频中的目标是一个非常具有挑战性的任务。
How to realize SOT(怎么追踪)
按图索骥(找到与模板最相似的区域)
- 人脸追踪示意
以第一帧的先验信息为主,在后续帧中只需要在画面中找出最为相似的部分即可,如图1.2人脸追踪,在第一帧框定出人脸,在后续帧中只需要在周围区域进行锁定,找出相似区域即可。再回到我们的运动员博尔特追踪任务中,图1.3中白色框就是我们的候选区域,通过计算候选框与第一帧先验信息的相似性就可以判断出是否是我们需要跟踪的目标。
问题:
- 把整张图都纳入跟踪范围时,首先,以第一帧的先验信息为主与后续的目标逐一对比时,后续目标的选取怎么确定?是任意选还是整张图片构建?长宽比例该怎么确定?另外,当先验目标与候选框一个一个比较会带来巨大的运算资源消耗,效率低。
按图索骥模型简单介绍
在16年之后兴起的深度学习的按图索骥模型如图,首先将第一帧框定的人为先验信息(Template)通过ResNet等网络提取出视觉特征z,作为对比的模板(卷积核),在后续帧中,不再是全图找候选框,而是在上一帧的周围进行跟踪(减少运算量), 抽取出图像x,将特征z和提取出来的图像x进行卷积操作得到Channel为1的的二维的得分图,作为相似度对比的结果,大小为17x17x1的得分图中的一个像素点代表原图中15x15得到区域。
- 按图索骥网路结构图
SOT可研究方向
- 构建更好的特征提取器来表达视觉区域特征
- 更好相似度匹配算法
- 更精确的边界框标注
- 长时间的目标追踪(第一帧模板是否适用于后续所有帧)
单目标追踪模型发展
-
- More Precise BBox Annotation
- Anchor-based (Anchor Box)
- 引入Anchor-based思想的SOT模型: SiamRPN, SiamCAR
- Anchor-free
- Anchor-based (Anchor Box)
- More Precise BBox Annotation
-
- Stronger Feature Extractor(更好的特征表征):对于单目标追踪来说,使用更深的网络比如ResNet,性能不增反降。
- 如果一个像素的感受野太大,填充会导致移位(分数图与目标位置不匹配)
- 其次,Padding可能会给模板匹配带来一些偏差
- 怎么做?
- 裁剪掉多余的padding: 在论文《Deeper and Wider Siamese Networks for Real-Time Visual Tracking》中,作者提出裁剪掉多余padding的思想。
- 将目标的标注向周围偏移: 当没有padding时,得分计算时,卷积操作之后得到的特征图非常抽象,如下图,矩阵中的21,映射到原图中就是矩阵后两列
- Stronger Feature Extractor(更好的特征表征):对于单目标追踪来说,使用更深的网络比如ResNet,性能不增反降。
-
- More Fine-grained Matching(更细粒度的模板匹配)
- 细粒度提升方式一——分组卷积
- 细粒度提升方式二——transformer
- More Fine-grained Matching(更细粒度的模板匹配)
-
- Traditional Methods(传统方法)
- Old but Strong Correlation Filter(19年之前)
- Older Motion Model(上世纪)
- LK Optical Flow(LP流光法)
- Traditional Methods(传统方法)
多目标跟踪(MOT)
真实场景中,不可能仅追踪一个目标。
- 如下图, 一个典型自动驾驶场景示例,通过传感器可感知到行人、车、自行车等目标,运动状态可能包括静止、横穿、转弯、对向行驶等。问题已变得复杂。
多目标跟踪是在有噪声的传感器测量时间序列中确定多个目标的如下特性:
- 动态目标的个数
- 每个动态目标的状态(和单目标跟踪相同)
对比SOT与MOT后发现,其处理问题多了一个确定动态目标个数。
多目标跟踪基于传感器的检测。
- 一般自动驾驶车上会配备一些传感器,比如
camera
、radar
和Lidar
。 - 这些传感器在车辆行驶过程中,会采集大量原始数据送入
检测
(detector)模块camera
摄像头 可获得bounding boxradar
雷达 可获得极坐标下的方位以及多普勒测量Lidar
激光 可获得点云,而后将这些信号将送入多目标跟踪模块。
- 多目标跟踪模块则根据这些连续的单帧的信号以获得目标state的后验分布。如下图所示。
一般情况下,detector处理的是单帧数据,而MOT需要处理多帧数据,有时序的。
以相机举个例子
- sensor为
camera
,detector则就是深度学习算法,输出给MOT的测量是bounding box以及吐出的深度估计。 - MOT模块则拿着这些单帧的测量进行目标跟踪
- 最后获得目标相对车体坐标系的 position(x,y) 以及 velocity(Vx,Vy)。
下图椭圆表示的为不确定度。
多目标跟踪的类型
由于每个目标可能产生不同数量的测量,这个对应的测量数目取决于传感器的分辨率,也取决于detector,同时也取决于跟踪对象的类型。根据每个目标对应测量的多少等标准将目标跟踪可分为以下类型:
① 点目标跟踪(point object tracking)
这是最传统的多目标跟踪类型,基于“small object”的假设,即:
- 每个目标都是独立的。
- 每个目标均被建模为点,而没有任何扩展。
- 在一个时间周期内,每个目标至多产生一个对应的测量。
点目标跟踪的例子:
- camera的检测
- 航天用于监视的雷达
② 扩展目标跟踪(extended object tracking)
此跟踪类型目标一般有不止一个测量,其目标的shape一般是未知的,可动态发生变化。通过递归滤波更新可以确定目标的shape。此种目标使得跟踪系统变得复杂,非线性程度上升。注意其与CV领域的轮廓跟踪是不同的。
扩展目标跟踪的例子:
- Lidar
- 汽车radar
③ 目标群跟踪(group object tracking)
几个目标被看做一个group,当然单一目标也可以看做一个group。
④ 其他(多径,merged measurement)
多径问题多发生于雷达,在自动驾驶领域就是雷达被路面反射,打到了车辆的地盘造成检测的目标点不是车辆的最近点。如下图所示。
merged measurement问题就是如果两个车辆在自车前方并行,二者有相同速度的话,radar检测的点被合并,目标出现在二者中间,如下图所示。
多目标跟踪的挑战
第一部分的挑战如下,以下图举例能说明问题,图中扇形部分为车载传感器可观测范围:
- FOV范围内多少个目标不知道;每个目标的state不知道。
- 目标在FOV内到处移动。
- 存在旧目标离开FOV或新目标进入FOV,涉及到目标的出现与消失,术语叫track birth与track death,需要进行航迹管理。
- 遮挡问题:某一帧一个目标把另外目标遮挡,传感器检测不到 。
下一部分的挑战就是由于传感器的缺陷导致的:
- (1) 传感器的漏捡:
- 在车辆行驶过程中,若前方某行人过马路,传感器漏捡,则可能出现自动驾驶的功能性fail,此时需要后面模块进行兜底,也就是MOT。
- 漏捡产生可能原因如下: * 环境问题:比如poor light。 * 目标本身特性。比如行人不是很容易被radar检测到。 * 遮挡原因
- (2) 传感器的虚警:
- 在车辆行驶过程中,若前方空空如也,但传感器上报存在目标,这就可能造成车辆自动减速刹车,此时也需要后面模块进行兜底,也就是MOT。
- 虚警产生可能原因: * 其他地方反射了radar。 * 被误认为目标。 * 环境问题。
最后一部分挑战就是数据关联:
- 数据关联是多目标跟踪中最重要的问题之一。说的通俗点就是,在k-1时刻感知若干个目标,在k时刻感知若干个目标,MOT模块需要把这些目标对应起来,确认哪些属于同一个目标,这其中不能关联错误,否则会引入错误信息,拉飞目标。
数据关联是挑战的原因:
- 首先就是因为没有先验信息,不知道哪些检测是之前有的目标,哪些是新生成的目标亦或是虚警。
- 其次就是传感器噪声影响,可能导致目标状态估计不准确,脱离算法限制,导致关联上错误目标。
- 再有就是目标彼此之间很近,也容易关联错误。试想在交通拥堵场景,车与车之间距离很近,如若传感器噪声较大,测量不准,就很容易关联错误。
举个例子,如下图所示,纵轴1,2,3分别对应三个时刻,灰色部分为虚警或新生成的track,同一目标已用同一种颜色标出。通过图示可以清晰看出哪些目标应该关联在一起。
然而如果把颜色去掉,仅有3个时刻的测量,肉眼就不好分别了。
尤其是对于Lidar与radar,这种目标多,虚警多的传感器,数据关联算法就变得格外重要。那有多重要呢,如下图为3个目标采用不同的数据关联算法进行跟踪,可以看出估计的位置信息(轨迹)差别较大,图一直接失败,图二则没有图三平滑。可见数据关联的重要性。
数据集
目标跟踪的困难点
虽然目标追踪的应用前景非常广泛,但还是有一些问题限制了它的应用,我们看下有哪些问题呢?
- 形态变化 - 姿态变化是目标跟踪中常见的干扰问题。运动目标发生姿态变化时, 会导致它的特征以及外观模型发生改变, 容易导致跟踪失败。例如:体育比赛中的运动员、马路上的行人。
- 尺度变化 - 尺度的自适应也是目标跟踪中的关键问题。当目标尺度缩小时, 由于跟踪框不能自适应跟踪, 会将很多背景信息包含在内, 导致目标模型的更新错误:当目标尺度增大时, 由于跟踪框不能将目标完全包括在内, 跟踪框内目标信息不全, 也会导致目标模型的更新错误。因此, 实现尺度自适应跟踪是十分必要的。
- 遮挡与消失 - 目标在运动过程中可能出现被遮挡或者短暂的消失情况。当这种情况发生时, 跟踪框容易将遮挡物以及背景信息包含在跟踪框内, 会导致后续帧中的跟踪目标漂移到遮挡物上面。若目标被完全遮挡时, 由于找不到目标的对应模型, 会导致跟踪失败。
- 图像模糊 - 光照强度变化, 目标快速运动, 低分辨率等情况会导致图像模型, 尤其是在运动目标与背景相似的情况下更为明显。因此, 选择有效的特征对目标和背景进行区分非常必要。
示例
目标跟踪算法
目标跟踪算法总结
目标跟踪的方法主要分为2大类,一类是相关滤波、一类是深度学习。img
- 相比于光流法、Kalman、Meanshift等传统算法,相关滤波类算法跟踪速度更快,深度学习类方法精度高.
- 具有多特征融合以及深度特征的追踪器在跟踪精度方面的效果更好.
- 使用强大的分类器是实现良好跟踪的基础.
- 尺度的自适应以及模型的更新机制也影响着跟踪的精度.
目标跟踪算法分类
目标跟踪的方法按照模式划分为2类。
生成式
模型 - 早期主要集中于生成式模型跟踪算法的研究, 如光流法
、粒子滤波
、Meanshift
算法、Camshift
算法等.- 此类方法首先建立目标模型或者提取目标特征, 在后续帧中进行相似特征搜索. 逐步迭代实现目标定位.
- 明显缺点:
- 图像的背景信息没有得到全面的利用.
- 目标本身的外观变化有随机性和多样性特点
- 因此, 通过单一数学模型描述待跟踪目标具有很大的局限性. 具体表现为光照变化, 运动模糊, 分辨率低, 目标旋转形变等情况, 模型的建立会受到巨大的影响, 从而影响跟踪的准确性; 模型的建立没有有效地预测机制, 当出现目标遮挡情况时, 不能够很好地解决。
鉴别式
模型 - 鉴别式模型将目标模型和背景信息同时考虑在内, 通过对比目标模型和背景信息的差异, 将目标模型提取出来, 从而得到当前帧中的目标位置.文献在对跟踪算法的评估中发现, 通过将背景信息引入跟踪模型, 可以很好地实现目标跟踪.因此鉴别式模型具有很大的优势.- 2000年以来, 人们逐渐尝试使用经典的机器学习方法训练分类器, 例如MIL、TLD、支持向量机、结构化学习、随机森林、多实例学习、度量学习.
- 2010年, 文献首次将通信领域的相关滤波方法引入到目标跟踪中.作为鉴别式方法的一种, 相关滤波无论在速度上还是准确率上, 都显示出更优越的性能. 然而, 相关滤波器用于目标跟踪是在2014年之后.
- 自2015年以后, 随着深度学习技术的广泛应用, 人们开始将深度学习技术用于目标跟踪。
按照时间顺序,目标跟踪的方法经历了从经典算法到基于核相关滤波算法,再到基于深度学习的跟踪算法的过程。
- 经典跟踪算法
- 基于核相关滤波的跟踪算法
- 基于深度学习的跟踪算法
经典跟踪算法
早期的目标跟踪算法主要是根据目标建模或者对目标特征进行跟踪
- 基于目标模型建模的方法: 通过对目标外观模型进行建模, 然后在之后的帧中找到目标.例如, 区域匹配、特征点跟踪、基于主动轮廓的跟踪算法、光流法等.最常用的是特征匹配法, 首先提取目标特征, 然后在后续的帧中找到最相似的特征进行目标定位, 常用的特征有: SIFT特征、SURF特征、Harris角点等。
- 基于搜索的方法: 随着研究的深入, 人们发现基于目标模型建模的方法对整张图片进行处理, 实时性差.人们将预测算法加入跟踪中, 在预测值附近进行目标搜索, 减少了搜索的范围.常见一类的预测算法有Kalman滤波、粒子滤波方法.另一种减小搜索范围的方法是内核方法:运用最速下降法的原理, 向梯度下降方向对目标模板逐步迭代, 直到迭代到最优位置.诸如, Meanshift、Camshift算法
光流法
光流法
(Lucas-Kanade)的概念首先在1950年提出, 它是针对外观模型对视频序列中的像素进行操作.通过利用视频序列在相邻帧之间的像素关系, 寻找像素的位移变化来判断目标的运动状态, 实现对运动目标的跟踪.但是, 光流法适用的范围较小, 需要满足三种假设:图像的光照强度保持不变; 空间一致性, 即每个像素在不同帧中相邻点的位置不变, 这样便于求得最终的运动矢量; 时间连续.光流法适用于目标运动相对于帧率是缓慢的, 也就是两帧之间的目标位移不能太大.
假设条件:
- 亮度恒定: 像素点的亮度值在不同帧中恒定不变
- 小运动: 像素点位置在相邻帧间不会剧烈变化
- 空间一致: 前一帧中相邻像素点在后一帧中也相邻
主要思想:
- 根据追踪目标特征点(轮廓像素点)在时间域的变化和相邻帧的关联计算每个特征点的瞬时速度和方向,进而预测后续帧特征点位置,比如上图。
Meanshift
Meanshift
方法是一种基于概率密度分布的跟踪方法,使目标的搜索一直沿着概率梯度上升的方向,迭代收敛到概率密度分布的局部峰值上。首先 Meanshift 会对目标进行建模,比如利用目标的颜色分布来描述目标,然后计算目标在下一帧图像上的概率分布,从而迭代得到局部最密集的区域。Meanshift 适用于目标的色彩模型和背景差异比较大的情形,早期也用于人脸跟踪。由于 Meanshift 方法的快速计算,它的很多改进方法也一直适用至今。
粒子滤波
粒子滤波
(Particle Filter)方法是一种基于粒子分布统计的方法。以跟踪为例,首先对跟踪目标进行建模,并定义一种相似度度量确定粒子与目标的匹配程度。在目标搜索的过程中,它会按照一定的分布(比如均匀分布或高斯分布)撒一些粒子,统计这些粒子的相似度,确定目标可能的位置。在这些位置上,下一帧加入更多新的粒子,确保在更大概率上跟踪上目标。Kalman Filter 常被用于描述目标的运动模型,它不对目标的特征建模,而是对目标的运动模型进行了建模,常用于估计目标在下一帧的位置。
优缺点
可以看到,传统的目标跟踪算法存在两个致命缺陷:
- 没有将背景信息考虑在内, 导致在目标遮挡, 光照变化以及运动模糊等干扰下容易出现跟踪失败.
- 跟踪算法执行速度慢(每秒10帧左右), 无法满足实时性的要求.
基于核相关滤波的跟踪算法
接着,人们将通信领域的相关滤波(衡量两个信号的相似程度)引入到了目标跟踪中.
- 一些基于相关滤波的跟踪算法(MOSSE、CSK、KCF、BACF、SAMF)等, 也随之产生, 速度可以达到数百帧每秒, 可以广泛地应用于实时跟踪系统中.
- 其中不乏一些跟踪性能优良的跟踪器, 诸如SAMF、BACF在OTB数据集和VOT2015竞赛中取得优异成绩。
MOSSE
本文提出的相关滤波器(Correlation Filter)通过MOSSE(Minimum Output Sum of Squared Error (MOSSE) filter)算法实现,基本思想:越是相似的两个目标相关值越大,也就是视频帧中与初始化目标越相似,得到的相应也就越大。下图所示通过对比UMACE,ASEF,MOSSE等相关滤波算法,使输出目标中心最大化。
基于深度学习的跟踪算法
随着深度学习方法的广泛应用, 人们开始考虑将其应用到目标跟踪中.人们开始使用深度特征并取得了很好的效果.之后, 人们开始考虑用深度学习建立全新的跟踪框架, 进行目标跟踪.
在大数据背景下,利用深度学习训练网络模型,得到的卷积特征输出表达能力更强。
- 在目标跟踪上,初期的应用方式是把网络学习到的特征,直接应用到相关滤波或 Struck的跟踪框架里面,从而得到更好的跟踪结果,比如前面提到的 DeepSRDCF 方法。本质上卷积输出得到的特征表达,更优于 HOG 或 CN 特征,这也是深度学习的优势之一,但同时也带来了计算量的增加。
目标跟踪前沿
最新方法
Recommendations
:star2: Recommendations :star2:
- Goutam Bhat, Martin Danelljan, Luc Van Gool, Radu Timofte.
“Know Your Surroundings: Exploiting Scene Information for Object Tracking.” Arxiv (2020). [paper]
CVPR2020
-
MAML: Guangting Wang, Chong Luo, Xiaoyan Sun, Zhiwei Xiong, Wenjun Zeng.
“Tracking by Instance Detection: A Meta-Learning Approach.” CVPR (2020 Oral). [paper] -
Siam R-CNN: Paul Voigtlaender, Jonathon Luiten, Philip H.S. Torr, Bastian Leibe.
“Siam R-CNN: Visual Tracking by Re-Detection.” CVPR (2020). [paper] [code] -
D3S: Alan Lukežič, Jiří Matas, Matej Kristan.
“D3S – A Discriminative Single Shot Segmentation Tracker.” CVPR (2020). [paper] [code] -
PrDiMP: Martin Danelljan, Luc Van Gool, Radu Timofte.
“Probabilistic Regression for Visual Tracking.” CVPR (2020). [paper] [code] -
ROAM: Tianyu Yang, Pengfei Xu, Runbo Hu, Hua Chai, Antoni B. Chan.
“ROAM: Recurrently Optimizing Tracking Model.” CVPR (2020). [paper] -
AutoTrack: Yiming Li, Changhong Fu, Fangqiang Ding, Ziyuan Huang, Geng Lu.
“AutoTrack: Towards High-Performance Visual Tracking for UAV with Automatic Spatio-Temporal Regularization.” CVPR (2020). [paper] [code] -
SiamBAN: Zedu Chen, Bineng Zhong, Guorong Li, Shengping Zhang, Rongrong Ji.
“Siamese Box Adaptive Network for Visual Tracking.” CVPR (2020). [paper] [code] -
SiamAttn: Yuechen Yu, Yilei Xiong, Weilin Huang, Matthew R. Scott.
“Deformable Siamese Attention Networks for Visual Object Tracking.” CVPR (2020). [paper] -
CGACD: Fei Du, Peng Liu, Wei Zhao, Xianglong Tang.
“Correlation-Guided Attention for Corner Detection Based Visual Tracking.” CVPR (2020).
AAAI 2020
- SiamFC++: Yinda Xu, Zeyu Wang, Zuoxin Li, Ye Yuan, Gang Yu.
“SiamFC++: Towards Robust and Accurate Visual Tracking with Target Estimation Guidelines.” AAAI (2020). [paper] [code]
ICCV2019
-
DiMP: Goutam Bhat, Martin Danelljan, Luc Van Gool, Radu Timofte.
“Learning Discriminative Model Prediction for Tracking.” ICCV (2019 oral). [paper] [code] -
GradNet: Peixia Li, Boyu Chen, Wanli Ouyang, Dong Wang, Xiaoyun Yang, Huchuan Lu.
“GradNet: Gradient-Guided Network for Visual Object Tracking.” ICCV (2019 oral). [paper] [code] -
MLT: Janghoon Choi, Junseok Kwon, Kyoung Mu Lee.
“Deep Meta Learning for Real-Time Target-Aware Visual Tracking.” ICCV (2019). [paper] -
SPLT: Bin Yan, Haojie Zhao, Dong Wang, Huchuan Lu, Xiaoyun Yang
“‘Skimming-Perusal’ Tracking: A Framework for Real-Time and Robust Long-Term Tracking.” ICCV (2019). [paper] [code] -
ARCF: Ziyuan Huang, Changhong Fu, Yiming Li, Fuling Lin, Peng Lu.
“Learning Aberrance Repressed Correlation Filters for Real-Time UAV Tracking.” ICCV (2019). [paper] [code] -
Lianghua Huang, Xin Zhao, Kaiqi Huang.
“Bridging the Gap Between Detection and Tracking: A Unified Approach.” ICCV (2019). [paper] -
UpdateNet: Lichao Zhang, Abel Gonzalez-Garcia, Joost van de Weijer, Martin Danelljan, Fahad Shahbaz Khan.
“Learning the Model Update for Siamese Trackers.” ICCV (2019). [paper] [code] -
PAT: Rey Reza Wiyatno, Anqi Xu.
“Physical Adversarial Textures That Fool Visual Object Tracking.” ICCV (2019). [paper] -
GFS-DCF: Tianyang Xu, Zhen-Hua Feng, Xiao-Jun Wu, Josef Kittler.
“Joint Group Feature Selection and Discriminative Filter Learning for Robust Visual Object Tracking.” ICCV (2019). [paper] [code] -
CDTB: Alan Lukežič, Ugur Kart, Jani Käpylä, Ahmed Durmush, Joni-Kristian Kämäräinen, Jiří Matas, Matej Kristan.
“CDTB: A Color and Depth Visual Object Tracking Dataset and Benchmark.” ICCV (2019). [paper]
-
VOT2019: Kristan, Matej, et al.
“The Seventh Visual Object Tracking VOT2019 Challenge Results.” ICCV workshops (2019). [paper]
CVPR2019
-
SiamMask: Qiang Wang, Li Zhang, Luca Bertinetto, Weiming Hu, Philip H.S. Torr.
“Fast Online Object Tracking and Segmentation: A Unifying Approach.” CVPR (2019). [paper] [project] [code] -
SiamRPN++: Bo Li, Wei Wu, Qiang Wang, Fangyi Zhang, Junliang Xing, Junjie Yan.
“SiamRPN++: Evolution of Siamese Visual Tracking with Very Deep Networks.” CVPR (2019 oral). [paper] [project] -
ATOM: Martin Danelljan, Goutam Bhat, Fahad Shahbaz Khan, Michael Felsberg.
“ATOM: Accurate Tracking by Overlap Maximization.” CVPR (2019 oral). [paper] [code] -
SiamDW: Zhipeng Zhang, Houwen Peng.
“Deeper and Wider Siamese Networks for Real-Time Visual Tracking.” CVPR (2019 oral). [paper] [code] -
GCT: Junyu Gao, Tianzhu Zhang, Changsheng Xu.
“Graph Convolutional Tracking.” CVPR (2019 oral). [paper] [code] -
ASRCF: Kenan Dai, Dong Wang, Huchuan Lu, Chong Sun, Jianhua Li.
“Visual Tracking via Adaptive Spatially-Regularized Correlation Filters.” CVPR (2019 oral). [paper] [code] -
UDT: Ning Wang, Yibing Song, Chao Ma, Wengang Zhou, Wei Liu, Houqiang Li.
“Unsupervised Deep Tracking.” CVPR (2019). [paper] [code] -
TADT: Xin Li, Chao Ma, Baoyuan Wu, Zhenyu He, Ming-Hsuan Yang.
“Target-Aware Deep Tracking.” CVPR (2019). [paper] [project] [code] -
C-RPN: Heng Fan, Haibin Ling.
“Siamese Cascaded Region Proposal Networks for Real-Time Visual Tracking.” CVPR (2019). [paper] -
SPM: Guangting Wang, Chong Luo, Zhiwei Xiong, Wenjun Zeng.
“SPM-Tracker: Series-Parallel Matching for Real-Time Visual Object Tracking.” CVPR (2019). [paper] -
OTR: Ugur Kart, Alan Lukezic, Matej Kristan, Joni-Kristian Kamarainen, Jiri Matas.
“Object Tracking by Reconstruction with View-Specific Discriminative Correlation Filters.” CVPR (2019). [paper] [code] -
RPCF: Yuxuan Sun, Chong Sun, Dong Wang, Huchuan Lu, You He.
“ROI Pooled Correlation Filters for Visual Tracking.” CVPR (2019). [paper] -
LaSOT: Heng Fan, Liting Lin, Fan Yang, Peng Chu, Ge Deng, Sijia Yu, Hexin Bai, Yong Xu, Chunyuan Liao, Haibin Ling.
“LaSOT: A High-quality Benchmark for Large-scale Single Object Tracking.” CVPR (2019). [paper] [project]
AAAI2019
- LDES: Yang Li, Jianke Zhu, Steven C.H. Hoi, Wenjie Song, Zhefeng Wang, Hantang Liu.
“Robust Estimation of Similarity Transformation for Visual Object Tracking.” AAAI (2019). [paper] [code]
目标跟踪实践
单目标跟踪
通常在目标跟踪有以下方法:
- 1)密集光流:这些算法有助于估计视频帧中每个像素的运动情况。
- 2)稀疏光流:这些算法,如Kanade-Lucas-Tomashi(KLT)特征跟踪器,跟踪图像中几个特征点的位置。
- 3)卡尔曼滤波:一种非常流行的信号处理算法,用于根据先前的运动信息预测运动物体的位置。该算法的早期应用之一是导弹制导!还提到这里,阿波罗11号登月舱的降落到月球车载计算机有一个卡尔曼滤波器。Engineers Look to Kalman Filtering for Guidance。
- 4)均值偏移(Meanshift)和Camshift(Meanshift的改进,连续自适应的MeanShift算法):这些是用于定位密度函数的最大值的算法。它们也用于跟踪。
- 5)单目标跟踪算法:在此类跟踪器中,第一帧使用矩形表示我们要跟踪的对象的位置。然后使用跟踪算法在后续帧中跟踪对象。在大多数实际应用中,这些跟踪器与目标检测算法结合使用。
- 6)多目标跟踪算法:在我们有快速对象检测器的情况下,检测每个帧中的多个对象然后运行跟踪查找算法来识别一个帧中的哪个矩形对应于下一帧中的矩形是很有效的。
OpenCV 3中提供的8种不同的跟踪器BOOSTING,MIL,KCF,TLD,MEDIANFLOW,GOTURN,MOSSE和CSRT。
Python版
Python稍微很简单,先卸载安装的Opencv,然后直接pip/pip3安装contrib库:
pip uninstall opencv-python
pip install opencv-contrib-python
目标跟踪代码
import cv2
import sys
if __name__ == '__main__' :
# Set up tracker.
# Instead of MIL, you can also use
tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT']
tracker_type = tracker_types[4]
if tracker_type == 'BOOSTING':
tracker = cv2.TrackerBoosting_create()
if tracker_type == 'MIL':
tracker = cv2.TrackerMIL_create()
if tracker_type == 'KCF':
tracker = cv2.TrackerKCF_create()
if tracker_type == 'TLD':
tracker = cv2.TrackerTLD_create()
if tracker_type == 'MEDIANFLOW':
tracker = cv2.TrackerMedianFlow_create()
if tracker_type == "CSRT":
tracker = cv2.TrackerCSRT_create()
if tracker_type == "MOSSE":
tracker = cv2.TrackerMOSSE_create()
# Read video
video = cv2.VideoCapture("video/chaplin.mp4")
# Exit if video not opened.
if not video.isOpened():
print("Could not open video")
sys.exit()
# Read first frame.
ok, frame = video.read()
if not ok:
print('Cannot read video file')
sys.exit()
# Define an initial bounding box
bbox = (287, 23, 86, 320)
# Uncomment the line below to select a different bounding box
bbox = cv2.selectROI(frame, False)
# Initialize tracker with first frame and bounding box
ok = tracker.init(frame, bbox)
while True:
# Read a new frame
ok, frame = video.read()
if not ok:
break
# Start timer
timer = cv2.getTickCount()
# Update tracker
ok, bbox = tracker.update(frame)
# Calculate Frames per second (FPS)
fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);
# Draw bounding box
if ok:
# Tracking success
p1 = (int(bbox[0]), int(bbox[1]))
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
cv2.rectangle(frame, p1, p2, (255,0,0), 2, 1)
else :
# Tracking failure
cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)
# Display tracker type on frame
cv2.putText(frame, tracker_type + " Tracker", (100,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50),2);
# Display FPS on frame
cv2.putText(frame, "FPS : " + str(int(fps)), (100,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50), 2);
# Display result
cv2.imshow("Tracking", frame)
# Exit if ESC pressed
k = cv2.waitKey(1) & 0xff
if k == 27 : break
C++版
// Opencv_Tracker.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/core/ocl.hpp>
using namespace cv;
using namespace std;
int main()
{
//跟踪算法类型
string trackerTypes[7] = { "BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "MOSSE", "CSRT" };
// Create a tracker 创建跟踪器
string trackerType = trackerTypes[5];
Ptr<Tracker> tracker;
if (trackerType == "BOOSTING")
tracker = TrackerBoosting::create();
if (trackerType == "MIL")
tracker = TrackerMIL::create();
if (trackerType == "KCF")
tracker = TrackerKCF::create();
if (trackerType == "TLD")
tracker = TrackerTLD::create();
if (trackerType == "MEDIANFLOW")
tracker = TrackerMedianFlow::create();
if (trackerType == "MOSSE")
tracker = TrackerMOSSE::create();
if (trackerType == "CSRT")
tracker = TrackerCSRT::create();
// Read video 读视频
VideoCapture video("video/chaplin.mp4");
// Exit if video is not opened 如果没有视频文件
if (!video.isOpened())
{
cout << "Could not read video file" << endl;
return 1;
}
// Read first frame 读图
Mat frame;
bool ok = video.read(frame);
// Define initial boundibg box 初始检测框
Rect2d bbox(287, 23, 86, 320);
// Uncomment the line below to select a different bounding box 手动在图像上画矩形框
//bbox = selectROI(frame, false);
// Display bounding box 展示画的2边缘框
rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);
imshow("Tracking", frame);
//跟踪器初始化
tracker->init(frame, bbox);
while (video.read(frame))
{
// Start timer 开始计时
double timer = (double)getTickCount();
// Update the tracking result 跟新跟踪器算法
bool ok = tracker->update(frame, bbox);
// Calculate Frames per second (FPS) 计算FPS
float fps = getTickFrequency() / ((double)getTickCount() - timer);
if (ok)
{
// Tracking success : Draw the tracked object 如果跟踪到目标画框
rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);
}
else
{
// Tracking failure detected. 没有就输出跟踪失败
putText(frame, "Tracking failure detected", Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2);
}
// Display tracker type on frame 展示检测算法类型
putText(frame, trackerType + " Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// Display FPS on frame 表示FPS
putText(frame, "FPS : " + to_string(int(fps)), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// Display frame.
imshow("Tracking", frame);
// Exit if ESC pressed.
int k = waitKey(1);
if (k == 27)
{
break;
}
}
return 0;
}
最新案例
CoTracker
【2024-10-4】CoTracker:同时准确跟踪视频中的多个点
- 代码:CoTracker 同时准确跟踪视频中的多个点
- 主页:CoTracker