导航:首页 > 源码编译 > 目标检测算法opencv

目标检测算法opencv

发布时间:2023-01-12 23:56:54

Ⅰ 目标检测算法是什么

目标检测算法是先通过训练集学习一个分类器,然后在测试图像中以不同scale的窗口滑动扫描整个图像;每次扫描做一下分类,判断一下当前的这个窗口是否为要检测的目标。检测算法的核心是分类,分类的核心一个是用什么特征,一个是用哪种分类器。

(1)目标检测算法opencv扩展阅读:

目标检测算法可以分为:

1、背景建模法,包含时间平均模型、混合高斯模型、动态纹理背景、PCA模型、时一空联合分布背景模型

2、点检测法,包含Moravec检测器、Harris检测器 、仿射不变点检测、S IFT

3、图像分割法,包含Mean Shift方法 、Graph-cut方法、Active Contours方法

4、聚类分析法,包含支持向量机、神经网络、Adaptive Boosting

5、运动矢量场法,包含基于运动矢量场的方法

Ⅱ 目标检测中使用的opencv函数boundingRect、minAreaRect和boxPoints

最近在做基于分割的文本检测算法实现,在得到连通域的轮廓后,要框出轮廓的最小矩阵,如果文本没有角度,使用cv::boundingRect是没有问题的,因为cv::boundingRect得到的结果是包覆此轮廓的最小正矩阵,但当文本存在角度时,使用cv::minAreaRect才是正解,因为它得到的结果时包覆轮廓的最小斜矩阵。

Ⅲ 运动目标检测——光流法与opencv代码实现

运动目标的检测的其主要目的是 获取目标对象的运动参数(位置、速度、加速度等)及运动轨迹 ,通过进一步分析处理,实现对目标行为更高层级上的理解。
运动目标检测技术目的是 从序列图像中将变化区域从背景图像中提取出来 ,常用于视频监视、图像压缩、三维重构、异常检测等。

运动目标检测主流方法有帧差法、背景差法、光流法等。光流法源于 仿生学 思想,更贴近于直觉,大量昆虫的视觉机理便是基于光流法。
二十世纪五十年代心理学家Gibson在他的着作“The Perception of Visual World”中首次提出了以心理学实验为基础的光流法基本概念,而直到八十年代才由Horn、Kanade、Lucash和Schunck创造性地将灰度与二维速度场相联系,引入光流约束方程的算法,对光流计算做了奠基性的工作。

光流(optical flow):由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动。

小球在连续五帧运动构成的光流 小球在连续五帧运动构成的光流

通俗说,对于一个图片序列,把每张图像每个像素在连续帧之间的运动速度和方向( 某像素点在连续两帧上的位移矢量 )找出来就是光流场。

第t帧的时A点的位置是(x1, y1),第t+1帧时A点位置是(x2,y2),则像素点A的位移矢量:(ux, vy) = (x2, y2) - (x1,y1)

如何知道第t+1帧的时候A点的位置涉及到不同的光流计算方法,主要有四种:基于梯度的方法、基于匹配的方法、基于能量的方法、基于相位的方法。

光流法依赖于三个假设:

根据所形成的光流场中 二维矢量的疏密程度 ,光流法可分为稠密光流与稀疏光流。

基于区域匹配生成的稠密光流场 基于区域匹配生成的稠密光流场

稀疏光流只对有 明显特征的组点 (如角点)进行跟踪,计算开销小。

基于特征匹配发生成的稀疏光流场 基于特征匹配发生成的稀疏光流场

http://www.opencv.org.cn/opencvdoc/2.3.2/html/moles/video/doc/motion_analysis_and_object_tracking.html#calcopticalflowfarneback
(1)calcOpticalFlowPyrLK
基于金字塔LK光流算法,计算某些点集的稀疏光流。
参考论文《Pyramidal Implementation of the Lucas Kanade Feature TrackerDescription of the algorithm》
(2)calcOpticalFlowFarneback
基于Gunnar Farneback 的算法计算稠密光流。
参考论文《Two-Frame Motion Estimation Based on PolynomialExpansion》
(3)CalcOpticalFlowBM
通过块匹配的方法来计算光流
(4)CalcOpticalFlowHS
基于Horn-Schunck 的算法计算稠密光流。
参考论文《Determining Optical Flow》
(5)calcOpticalFlowSF
论文《SimpleFlow: A Non-iterative, Sublinear Optical FlowAlgo》的实现

LK光流法效果 LK光流法效果

Ⅳ 目标检测算法的分步介绍(第 1 部分)

英文原文: https://www.analyticsvidhya.com/blog/2018/10/a-step-by-step-introction-to-the-basic-object-detection-algorithms-part-1/
对原文的表达有部分改动

在本文中,我们将更深入地研究可用于目标检测的各种算法。我们将从 RCNN 家族的算法开始,即 RCNN、Fast RCNN 和 Faster RCNN。在本系列即将发布的文章中,我们将介绍更高级的算法,如 YOLO、SSD 等。

下图是说明目标检测算法如何工作的一个流行示例。图像中的每个物体,从一个人到一只风筝,都以一定的精度被定位和识别。

让我们从最简单的深度学习方法开始,也是一种广泛使用的方法,用于检测图像中的目标——卷积神经网络( CNN)。CNN 的内部工作原理如下:

我们将图像传递给网络,然后通过各种卷积和池化层处理,发送给全连接层。最后,我们以目标类别的形式获得输出。这相当简单,不是吗?对于每个输入图像,我们得到一个相应的类作为输出。我们可以使用这种技术来检测图像中的各种目标吗?让我们看看如何使用 CNN 解决一般的目标检测问题。

使用这种方法的问题在于图像中的目标可能具有不同的纵横比和空间位置。例如,在某些情况下,目标可能覆盖图像的大部分,而在某些情况下,目标可能仅覆盖图像的一小部分。目标的形状也可能不同(在现实生活中经常发生)。由于这些因素,我们将需要大量的区域,从而导致大量的计算时间。因此,为了解决这个问题并减少区域数量,我们可以使用基于区域的 CNN,它使用提案法选择区域。让我们了解这个基于区域的 CNN 可以为我们做什么。

与在大量区域上工作不同的是,RCNN 算法是在图像中选取一堆框并检查这些框中是否有任何一个包含任何目标。 RCNN 使用 selective search 从图像中提取这些框(这些框称为 regions)。

让我们首先了解什么是 selective search 以及它如何识别不同的 regions。基本上四个模式可以构成一个物体:不同的尺度、颜色、纹理和外壳。selective search 识别图像中的这些模式,并在此基础上提出各种regions。以下是selective search 工作原理的简要概述:

举个例子:

到目前为止,我们已经看到了 RCNN 如何实现目标检测。但是这种技术有其自身的局限性。由于以下步骤,训练 RCNN 模型既昂贵又缓慢:

所有这些过程结合起来使 RCNN 非常慢。对每张新图像进行预测大约需要 40-50 秒,这实质上使得模型在面对庞大的数据集时变得笨重且几乎无法构建。

好消息是——我们有另一种目标检测技术,它修复了我们在 RCNN 中看到的大部分问题。

我们还能做些什么来减少 RCNN 算法通常需要的计算时间?我们是否可以每张图像只运行一次并获取所有感兴趣的区域(包含某个目标的区域)。

RCNN 的作者 Ross Girshick 提出了这个想法,即每张图像只运行一次 CNN,然后找到一种方法在 2,000 个区域之间共享该计算。在 Fast RCNN 中,我们将输入图像提供给 CNN,后者反过来生成卷积特征图。使用这些地图,提取提议的区域。然后我们使用 RoI 池化层将所有提议的区域重塑为固定大小,以便可以将其馈入全连接网络。

让我们将其分解为简化概念的步骤:

因此,Fast RCNN 不是使用三个不同的模型(如 RCNN),而是使用单个模型从区域中提取特征,将它们分成不同的类,并同时返回识别类的边界框。

为了进一步分解,我将对每个步骤进行可视化。

这就是 Fast RCNN 如何解决 RCNN 的两个主要问题,1. 将每个图像的一个而不是 2,000 个区域传递给 ConvNet。2. 使用一个而不是三个不同的模型来提取特征、分类和生成边界框。

但即使是 Fast RCNN 也存在某些问题。它还使用 selective search 作为寻找感兴趣区域的建议方法,这是一个缓慢且耗时的过程。每张图像检测目标大约需要 2 秒,这与 RCNN 相比要好得多。但是当我们考虑大型现实生活数据集时,即使是 Fast RCNN 看起来也不那么快了。

Faster RCNN 是 Fast RCNN 的修改版本。它们之间的主要区别在于 Fast RCNN 使用 selective search 来生成感兴趣的区域,而 Faster RCNN 使用 Region Proposal Network ,又名 RPN。 RPN 将图像特征图作为输入并生成一组目标提议,每个提议的目标以分数作为输出。

Faster RCNN 方法通常遵循以下步骤:

让我简要解释一下这个区域提议网络(RPN)实际上是如何工作的。

首先,Faster RCNN 从 CNN 获取特征图并将它们传递给区域提议网络。 RPN 在这些特征图上使用一个滑动窗口,在每个窗口,它生成 k 个不同形状和大小的 Anchor 框:

Anchor 框是固定大小的边界框,它们放置在整个图像中,具有不同的形状和大小。对于每个 Anchor,RPN 预测两件事:

我们现在有不同形状和大小的边界框,它们被传递到 RoI 池化层。在 RPN 步骤之后,有可能存在没有分配给它们的类别提议。我们可以获取每个建议并对其进行裁剪,以便每个建议都包含一个目标。这就是 RoI 池化层所做的。它为每个锚点提取固定大小的特征图:

然后将这些特征图传递到具有 softmax 和线性回归层的全连接层。它最终对目标进行分类并预测已识别目标的边界框。

到目前为止,我们讨论的所有目标检测算法都使用区域来识别目标。网络不会一次性查看完整图像,而是依次关注图像的各个部分。这会造成两个并发症:

Ⅳ 目标跟踪检测算法(一)——传统方法

姓名:刘帆;学号:20021210609;学院:电子工程学院

https://blog.csdn.net/qq_34919792/article/details/89893214

【嵌牛导读】目标跟踪算法研究难点与挑战在于实际复杂的应用环境 、背景相似干扰、光照条件的变化、遮挡等外界因素以及目标姿态变化,外观变形,尺度变化、平面外旋转、平面内旋转、出视野、快速运动和运动模糊等。而且当目标跟踪算法投入实际应用时,不可避免的一个问题——实时性问题也是非常的重要。正是有了这些问题,才使得算法研究充满着难点和挑战。

【嵌牛鼻子】目标跟踪算法,传统算法

【嵌牛提问】利用目标跟踪检测算法要达到何目的?第一阶段的单目标追踪算法包括什么?具体步骤有哪些?它们有何特点?

【嵌牛正文】

第一阶段

目标跟踪分为两个部分,一个是对指定目标寻找可以跟踪的特征,常用的有颜色,轮廓,特征点,轨迹等,另一个是对目标特征进行跟踪。

1、静态背景

1)背景差: 对背景的光照变化、噪声干扰以及周期性运动等进行建模。通过当前帧减去背景图来捕获运动物体的过程。

2)帧差: 由于场景中的目标在运动,目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧或三帧图像进行差分运算,不同帧对应的像素点相减,判断灰度差的绝对值,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。

与二帧差分法不同的是,三帧差分法(交并运算)去除了重影现象,可以检测出较为完整的物体。帧间差分法的原理简单,计算量小,能够快速检测出场景中的运动目标。但帧间差分法检测的目标不完整,内部含有“空洞”,这是因为运动目标在相邻帧之间的位置变化缓慢,目标内部在不同帧图像中相重叠的部分很难检测出来。帧间差分法通常不单独用在目标检测中,往往与其它的检测算法结合使用。

3)Codebook

算法为图像中每一个像素点建立一个码本,每个码本可以包括多个码元(对应阈值范围),在学习阶段,对当前像素点进行匹配,如果该像素值在某个码元的学习阈值内,也就是说与之前出现过的某种历史情况偏离不大,则认为该像素点符合背景特征,需要更新对应点的学习阈值和检测阈值。

如果新来的像素值与每个码元都不匹配,则可能是由于动态背景导致,这种情况下,我们需要为其建立一个新的码元。每个像素点通过对应多个码元,来适应复杂的动态背景。

在应用时,每隔一段时间选择K帧通过更新算法建立CodeBook背景模型,并且删除超过一段时间未使用的码元。

4)GMM

混合高斯模型(Gaussian of Micture Models,GMM)是较常用的背景去除方法之一(其他的还有均值法、中值法、滑动平均滤波等)。

首先我们需要了解单核高斯滤波的算法步骤:

混合高斯建模GMM(Gaussian Mixture Model)作为单核高斯背景建模的扩展,是目前使用最广泛的一种方法,GMM将背景模型描述为多个分布,每个像素的R、G、B三个通道像素值的变化分别由一个混合高斯模型分布来刻画,符合其中一个分布模型的像素即为背景像素。作为最常用的一种背景建模方法,GMM有很多改进版本,比如利用纹理复杂度来更新差分阈值,通过像素变化的剧烈程度来动态调整学习率等。

5)ViBe(2011)

ViBe算法主要特点是随机背景更新策略,这和GMM有很大不同。其步骤和GMM类似。具体的思想就是为每个像素点存储了一个样本集,样本集中采样值就是该像素点过去的像素值和其邻居点的像素值,然后将每一个新的像素值和样本集进行比较来判断是否属于背景点。

其中pt(x)为新帧的像素值,R为设定值,p1、p2、p3….为样本集中的像素值,以pt(x)为圆心R为半径的圆被认为成一个集,当样本集与此集的交集大于设定的阈值#min时,可认为此为背景像素点(交集越大,表示新像素点与样本集越相关)。我们可以通过改变#min的值与R的值来改变模型的灵敏度。

Step1:初始化单帧图像中每个像素点的背景模型。假设每一个像素和其邻域像素的像素值在空域上有相似的分布。基于这种假设,每一个像素模型都可以用其邻域中的像素来表示。为了保证背景模型符合统计学规律,邻域的范围要足够大。当输入第一帧图像时,即t=0时,像素的背景模型。其中,NG(x,y)表示空域上相邻的像素值,f(xi,yi)表示当前点的像素值。在N次的初始化的过程中,NG(x,y)中的像素点(xi,yi)被选中的可能次数为L=1,2,3,…,N。

Step2:对后续的图像序列进行前景目标分割操作。当t=k时,像素点(x,y)的背景模型为BKm(x,y),像素值为fk(x,y)。按照下面判断该像素值是否为前景。这里上标r是随机选的;T是预先设置好的阈值。当fk(x,y)满足符合背景#N次时,我们认为像素点fk(x,y)为背景,否则为前景。

Step3:ViBe算法的更新在时间和空间上都具有随机性。每一个背景点有1/ φ的概率去更新自己的模型样本值,同时也有1/ φ的概率去更新它的邻居点的模型样本值。更新邻居的样本值利用了像素值的空间传播特性,背景模型逐渐向外扩散,这也有利于Ghost区域的更快的识别。同时当前景点计数达到临界值时将其变为背景,并有1/ φ的概率去更新自己的模型样本值(为了减少缓慢移动物体的影响和摄像机的抖动)。

可以有如下总结,ViBe中的每一个像素点在更新的时候都有一个时间和空间上随机影响的范围,这个范围很小,大概3x3的样子,这个是考虑到摄像头抖动时会有坐标的轻微来回变化,这样虽然由于ViBe的判别方式仍认为是背景点,但是也会对后面的判别产生影响,为了保证空间的连续性,随机更新减少了这个影响。而在样本值保留在样本集中的概率随着时间的增大而变小,这就保证了像素模型在时间上面的延续特性。

6)光流

光流是由物体或相机的运动引起的图像对象在两个连续帧之间的视在运动模式。它是2D矢量场,其中每个矢量是一个位移矢量,显示点从第一帧到第二帧的移动。

光流实际上是一种特征点跟踪方法,其计算的为向量,基于三点假设:

1、场景中目标的像素在帧间运动时亮度(像素值或其衍生值)不发生变化;2、帧间位移不能太大;3、同一表面上的邻近点都在做相同的运动;

光流跟踪过程:1)对一个连续视频帧序列进行处理;2)对每一帧进行前景目标检测;3)对某一帧出现的前景目标,找出具有代表性的特征点(Harris角点);4)对于前后帧做像素值比较,寻找上一帧在当前帧中的最佳位置,从而得到前景目标在当前帧中的位置信息;5)重复上述步骤,即可实现目标跟踪

2、运动场(分为相机固定,但是视角变化和相机是运动的)

1)运动建模(如视觉里程计运动模型、速度运动模型等)

运动学是对进行刚性位移的相机进行构型,一般通过6个变量来描述,3个直角坐标,3个欧拉角(横滚、俯仰、偏航)。

Ⅰ、对相机的运动建模

由于这个不是我们本次所要讨论的重点,但是在《概率机器人》一书中提出了很多很好的方法,相机的运动需要对图像内的像素做位移矩阵和旋转矩阵的坐标换算。除了对相机建立传统的速度运动模型外,也可以用视觉里程计等通关过置信度的更新来得到概率最大位置。

Ⅱ、对于跟踪目标的运动建模

该方法需要提前通过先验知识知道所跟踪的目标对象是什么,比如车辆、行人、人脸等。通过对要跟踪的目标进行建模,然后再利用该模型来进行实际的跟踪。该方法必须提前知道要跟踪的目标对象是什么,然后再去跟踪指定的目标,这是它的局限性,因而其推广性相对比较差。(比如已知跟踪的物体是羽毛球,那很容易通过前几帧的取点,来建立整个羽毛球运动的抛物线模型)

2)核心搜索算法(常见的预测算法有Kalman(卡尔曼)滤波、扩展卡尔曼滤波、粒子滤波)

Ⅰ、Kalman 滤波

Kalman滤波器是通过前一状态预测当前状态,并使用当前观测状态进行校正,从而保证输出状态平稳变化,可有效抵抗观测误差。因此在运动目标跟踪中也被广泛使用。

在视频处理的运动目标跟踪里,每个目标的状态可表示为(x,y,w,h),x和y表示目标位置,w和h表示目标宽高。一般地认为目标的宽高是不变的,而其运动速度是匀速,那么目标的状态向量就应该扩展为(x,y,w,h,dx,dy),其中dx和dy是目标当前时刻的速度。通过kalman滤波器来估计每个时刻目标状态的大致过程为:

对视频进行运动目标检测,通过简单匹配方法来给出目标的第一个和第二个状态,从第三个状态开始,就先使用kalman滤波器预测出当前状态,再用当前帧图像的检测结果作为观测值输入给kalman滤波器,得到的校正结果就被认为是目标在当前帧的真实状态。(其中,Zt为测量值,为预测值,ut为控制量,Kt为增益。)

Ⅱ、扩展卡尔曼滤波(EKF)和无迹卡尔曼滤波(UKF)

由于卡尔曼滤波的假设为线性问题,无法直接用在非线性问题上,EKF和UKF解决了这个问题(这个线性问题体现在用测量量来计算预测量的过程中)。EKF是通过构建线性函数g(x),与非线性函数相切,并对每一时刻所求得的g(x)做KF,如下图所示。

UKF与EKF去求解雅可比矩阵拟合线性方程的方法不同,通过对那个先验分布中的采集点,来线性化随机变量的非线性函数。与EKF所用的方法不同,UKF产生的高斯分布和实际高斯分布更加接近,其引起的近似误差也更小。

Ⅲ、粒子滤波

1、初始状态:基于粒子滤波的目标追踪方法是一种生成式跟踪方法,所以要有一个初始化的阶段。对于第一帧图像,人工标定出待检测的目标,对该目标区域提出特征;

2、搜索阶段:现在已经知道了目标的特征,然后就在目标的周围撒点(particle), 如:a)均匀的撒点;b)按高斯分布撒点,就是近的地方撒得多,远的地方撒的少。论文里使用的是后一种方法。每一个粒子都计算所在区域内的颜色直方图,如初始化提取特征一样,然后对所有的相似度进行归一化。文中相似性使用的是巴氏距离;

3、重采样:根据粒子权重对粒子进行筛选,筛选过程中,既要大量保留权重大的粒子,又要有一小部分权重小的粒子;

4、状态转移:将重采样后的粒子带入状态转移方程得到新的预测粒子;

5、测量及更新:对目标点特征化,并计算各个粒子和目标间的巴氏距离,更新粒子的权重;

6、决策阶段:每个粒子都获得一个和目标的相似度,相似度越高,目标在该范围出现的可能性越高,将保留的所有粒子通过相似度加权后的结果作为目标可能的位置。

3)Meanshift算法

MeanShift算法属于核密度估计法,它不需要任何先验知识而完全依靠特征空间中样本点的计算其密度函数值。对于一组采样数据,直方图法通常把数据的值域分成若干相等的区间,数据按区间分成若干组,每组数据的个数与总参数个数的比率就是每个单元的概率值;核密度估计法的原理相似于直方图法,只是多了一个用于平滑数据的核函数。采用核函数估计法,在采样充分的情况下,能够渐进地收敛于任意的密度函数,即可以对服从任何分布的数据进行密度估计。

Meanshift算法步骤

1、通过对初始点(或者上一帧的目标点)为圆心,绘制一个半径为R的圆心,寻找特征和该点相似的点所构成的向量;

2、所有向量相加,可以获得一个向量叠加,这个向量指向特征点多的方向;

3、取步骤二的向量终点为初始点重复步骤一、二,直到得到的向量小于一定的阈值,也就是说明当前位置是特征点密度最密集的地方,停止迭代,认为该点为当前帧的目标点;

4)Camshift算法

Camshift算法是MeanShift算法的改进,称为连续自适应的MeanShift算法。Camshift 是由Meanshift 推导而来 Meanshift主要是用在单张影像上,但是独立一张影像分析对追踪而言并无意义,Camshift 就是利用MeanShift的方法,对影像串行进行分析。

1、首先在影像串行中选择目标区域。

2、计算此区域的颜色直方图(特征提取)。

3、用MeanShift算法来收敛欲追踪的区域。

4、通过目标点的位置和向量信息计算新的窗口大小,并标示之。

5、以此为参数重复步骤三、四。

Camshift 关键就在于当目标的大小发生改变的时候,此算法可以自适应调整目标区域继续跟踪。

3、小结

第一阶段的单目标追踪算法基本上都是传统方法,计算量小,在嵌入式等设备中落地较多,opencv中也预留了大量的接口。通过上面的两节的介绍,我们不难发现,目标检测算法的步骤分为两部分,一部分是对指定目标寻找可以跟踪的特征,常用的有颜色,轮廓,特征点,轨迹等,另一部分是对目标特征进行跟踪,如上文所提及的方法。所以目标检测方法的发展,也可总结为两个方面,一个是如何去获得更加具有区分性的可跟踪的稳定特征,另一个是如何建立帧与帧之间的数据关联,保证跟踪目标是正确的。

随着以概率为基础的卡尔曼滤波、粒子滤波或是以Meanshift为代表向量叠加方法在目标检测的运用,使得目标检测不再需要假设自身的一个状态为静止的,而是可以是运动的,更加符合复杂场景中的目标跟踪。

Ⅵ 目标跟踪(3)MultiTracker : 基于 OpenCV (C++/Python) 的多目标跟踪

在这篇文章中,我们将介绍如何使用通过 MultiTracker 类实现的 OpenCV 的多对象跟踪 API。我们将共享C++ 和 Python 代码。


大多数计算机视觉和机器学习的初学者都学习对象检测。如果您是初学者,您可能会想为什么我们需要对象跟踪。我们不能只检测每一帧中的对象吗?

让我们来探究一下跟踪是有用的几个原因。

首先,当在视频帧中检测到多个对象(例如人)时,跟踪有助于跨帧建立对象的身份。

其次,在某些情况下,对象检测可能会失败,但仍可能跟踪对象,因为跟踪考虑了对象在前一帧中的位置和外观。

第三,一些跟踪算法非常快,因为它们做的是局部搜索,而不是全局搜索。因此,我们可以通过每n帧进行目标检测,并在中间帧中跟踪目标,从而为我们的系统获得很高的帧率。

那么,为什么不在第一次检测后无限期地跟踪对象呢?跟踪算法有时可能会丢失它正在跟踪的对象。例如,当对象的运动太大时,跟踪算法可能跟不上。许多现实世界的应用程序同时使用检测和跟踪。

在本教程中,我们只关注跟踪部分。我们想要跟踪的对象将通过拖动它们周围的包围框来指定。

OpenCV 中的 MultiTracker 类提供了多目标跟踪的实现。它是一个简单的实现,因为它独立处理跟踪对象,而不对跟踪对象进行任何优化。

让我们逐步查看代码,了解如何使用 OpenCV 的多目标跟踪 API。

2.1 第 1 步:创建单一对象跟踪器

多目标跟踪器只是单目标跟踪器的集合。我们首先定义一个函数,该函数接受一个跟踪器类型作为输入,并创建一个跟踪器对象。OpenCV有8种不同的跟踪器类型:BOOSTING, MIL, KCF,TLD, MEDIANFLOW, GOTURN, MOSSE, CSRT。

如果您想使用 GOTURN 跟踪器,请务必阅读这篇文章并下载 caffe 模型。

在下面的代码中,给定跟踪器类的名称,我们返回跟踪器对象。这将在稍后用于多目标跟踪器。

Python


C++


2.2 第 2 步:读取视频的第一帧

多目标跟踪器需要两个输入

给定这些信息,跟踪器在所有后续帧中跟踪这些指定对象的位置。 在下面的代码中,我们首先使用 VideoCapture 类加载视频并读取第一帧。这将在稍后用于初始化 MultiTracker。

Python


C++


2.3 第 3 步:在第一帧中定位对象

接下来,我们需要在第一帧中定位我们想要跟踪的对象。该位置只是一个边界框。 OpenCV 提供了一个名为 selectROI 的函数,该函数会弹出一个 GUI 来选择边界框(也称为感兴趣区域 (ROI))。 在 C++ 版本中,selectROI 允许您获取多个边界框,但在 Python 版本中,它只返回一个边界框。所以,在 Python 版本中,我们需要一个循环来获取多个边界框。 对于每个对象,我们还选择一种随机颜色来显示边界框。 代码如下所示。

Python


C++

getRandomColors 函数相当简单

2.4 第 3 步:初始化 MultiTracker

到目前为止,我们已经读取了第一帧并获得了对象周围的边界框。这就是我们初始化多目标跟踪器所需的所有信息。

我们首先创建一个 MultiTracker 对象,并向其中添加与边界框一样多的单个对象跟踪器。在此示例中,我们使用 CSRT 单对象跟踪器,但您可以通过将下面的 trackerType 变量更改为本文开头提到的 8 个跟踪器之一来尝试其他跟踪器类型。 CSRT 跟踪器不是最快的,但在我们尝试的许多情况下它产生了最好的结果。

您还可以使用包裹在同一个 MultiTracker 中的不同跟踪器,但当然,这没什么意义。

MultiTracker 类只是这些单个对象跟踪器的包装器。正如我们从上一篇文章中知道的那样,单个对象跟踪器是使用第一帧初始化的,并且边界框指示我们想要跟踪的对象的位置。 MultiTracker 将此信息传递给它在内部包装的单个对象跟踪器。

Python


C++


2.5 第 4 步:更新 MultiTracker 并显示结果

最后,我们的 MultiTracker 已准备就绪,我们可以在新帧中跟踪多个对象。我们使用 MultiTracker 类的 update 方法来定位新框架中的对象。每个跟踪对象的每个边界框都使用不同的颜色绘制。

Python


C++


C++


Python


Ⅶ 目标检测算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3)

深度学习目前已经应用到了各个领域,应用场景大体分为三类:物体识别,目标检测,自然语言处理。  目标检测可以理解为是物体识别和物体定位的综合 ,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。

2014年R-CNN算法被提出,基本奠定了two-stage方式在目标检测领域的应用。它的算法结构如下图

算法步骤如下:

R-CNN较传统的目标检测算法获得了50%的性能提升,在使用VGG-16模型作为物体识别模型情况下,在voc2007数据集上可以取得66%的准确率,已经算还不错的一个成绩了。其最大的问题是速度很慢,内存占用量很大,主要原因有两个

针对R-CNN的部分问题,2015年微软提出了Fast R-CNN算法,它主要优化了两个问题。

R-CNN和fast R-CNN均存在一个问题,那就是 由选择性搜索来生成候选框,这个算法很慢 。而且R-CNN中生成的2000个左右的候选框全部需要经过一次卷积神经网络,也就是需要经过2000次左右的CNN网络,这个是十分耗时的(fast R-CNN已经做了改进,只需要对整图经过一次CNN网络)。这也是导致这两个算法检测速度较慢的最主要原因。

faster R-CNN 针对这个问题, 提出了RPN网络来进行候选框的获取,从而摆脱了选择性搜索算法,也只需要一次卷积层操作,从而大大提高了识别速度 。这个算法十分复杂,我们会详细分析。它的基本结构如下图

主要分为四个步骤:

使用VGG-16卷积模型的网络结构:

卷积层采用的VGG-16模型,先将PxQ的原始图片,缩放裁剪为MxN的图片,然后经过13个conv-relu层,其中会穿插4个max-pooling层。所有的卷积的kernel都是3x3的,padding为1,stride为1。pooling层kernel为2x2, padding为0,stride为2。

MxN的图片,经过卷积层后,变为了(M/16) x (N/16)的feature map了。

faster R-CNN抛弃了R-CNN中的选择性搜索(selective search)方法,使用RPN层来生成候选框,能极大的提升候选框的生成速度。RPN层先经过3x3的卷积运算,然后分为两路。一路用来判断候选框是前景还是背景,它先reshape成一维向量,然后softmax来判断是前景还是背景,然后reshape恢复为二维feature map。另一路用来确定候选框的位置,通过bounding box regression实现,后面再详细讲。两路计算结束后,挑选出前景候选框(因为物体在前景中),并利用计算得到的候选框位置,得到我们感兴趣的特征子图proposal。

卷积层提取原始图像信息,得到了256个feature map,经过RPN层的3x3卷积后,仍然为256个feature map。但是每个点融合了周围3x3的空间信息。对每个feature map上的一个点,生成k个anchor(k默认为9)。anchor分为前景和背景两类(我们先不去管它具体是飞机还是汽车,只用区分它是前景还是背景即可)。anchor有[x,y,w,h]四个坐标偏移量,x,y表示中心点坐标,w和h表示宽度和高度。这样,对于feature map上的每个点,就得到了k个大小形状各不相同的选区region。

对于生成的anchors,我们首先要判断它是前景还是背景。由于感兴趣的物体位于前景中,故经过这一步之后,我们就可以舍弃背景anchors了。大部分的anchors都是属于背景,故这一步可以筛选掉很多无用的anchor,从而减少全连接层的计算量。

对于经过了3x3的卷积后得到的256个feature map,先经过1x1的卷积,变换为18个feature map。然后reshape为一维向量,经过softmax判断是前景还是背景。此处reshape的唯一作用就是让数据可以进行softmax计算。然后输出识别得到的前景anchors。

另一路用来确定候选框的位置,也就是anchors的[x,y,w,h]坐标值。如下图所示,红色代表我们当前的选区,绿色代表真实的选区。虽然我们当前的选取能够大概框选出飞机,但离绿色的真实位置和形状还是有很大差别,故需要对生成的anchors进行调整。这个过程我们称为bounding box regression。

假设红色框的坐标为[x,y,w,h], 绿色框,也就是目标框的坐标为[Gx, Gy,Gw,Gh], 我们要建立一个变换,使得[x,y,w,h]能够变为[Gx, Gy,Gw,Gh]。最简单的思路是,先做平移,使得中心点接近,然后进行缩放,使得w和h接近。如下:

我们要学习的就是dx dy dw dh这四个变换。由于是线性变换,我们可以用线性回归来建模。设定loss和优化方法后,就可以利用深度学习进行训练,并得到模型了。对于空间位置loss,我们一般采用均方差算法,而不是交叉熵(交叉熵使用在分类预测中)。优化方法可以采用自适应梯度下降算法Adam。

得到了前景anchors,并确定了他们的位置和形状后,我们就可以输出前景的特征子图proposal了。步骤如下:

1,得到前景anchors和他们的[x y w h]坐标。

2,按照anchors为前景的不同概率,从大到小排序,选取前pre_nms_topN个anchors,比如前6000个

3,剔除非常小的anchors。

4,通过NMS非极大值抑制,从anchors中找出置信度较高的。这个主要是为了解决选取交叠问题。首先计算每一个选区面积,然后根据他们在softmax中的score(也就是是否为前景的概率)进行排序,将score最大的选区放入队列中。接下来,计算其余选区与当前最大score选区的IOU(IOU为两box交集面积除以两box并集面积,它衡量了两个box之间重叠程度)。去除IOU大于设定阈值的选区。这样就解决了选区重叠问题。

5,选取前post_nms_topN个结果作为最终选区proposal进行输出,比如300个。

经过这一步之后,物体定位应该就基本结束了,剩下的就是物体识别了。

和fast R-CNN中类似,这一层主要解决之前得到的proposal大小形状各不相同,导致没法做全连接。全连接计算只能对确定的shape进行运算,故必须使proposal大小形状变为相同。通过裁剪和缩放的手段,可以解决这个问题,但会带来信息丢失和图片形变问题。我们使用ROI pooling可以有效的解决这个问题。

ROI pooling中,如果目标输出为MxN,则在水平和竖直方向上,将输入proposal划分为MxN份,每一份取最大值,从而得到MxN的输出特征图。

ROI Pooling层后的特征图,通过全连接层与softmax,就可以计算属于哪个具体类别,比如人,狗,飞机,并可以得到cls_prob概率向量。同时再次利用bounding box regression精细调整proposal位置,得到bbox_pred,用于回归更加精确的目标检测框。

这样就完成了faster R-CNN的整个过程了。算法还是相当复杂的,对于每个细节需要反复理解。faster R-CNN使用resNet101模型作为卷积层,在voc2012数据集上可以达到83.8%的准确率,超过yolo ssd和yoloV2。其最大的问题是速度偏慢,每秒只能处理5帧,达不到实时性要求。

针对于two-stage目标检测算法普遍存在的运算速度慢的缺点, yolo创造性的提出了one-stage。也就是将物体分类和物体定位在一个步骤中完成。 yolo直接在输出层回归bounding box的位置和bounding box所属类别,从而实现one-stage。通过这种方式, yolo可实现45帧每秒的运算速度,完全能满足实时性要求 (达到24帧每秒,人眼就认为是连续的)。它的网络结构如下图:

主要分为三个部分:卷积层,目标检测层,NMS筛选层。

采用Google inceptionV1网络,对应到上图中的第一个阶段,共20层。这一层主要是进行特征提取,从而提高模型泛化能力。但作者对inceptionV1进行了改造,他没有使用inception mole结构,而是用一个1x1的卷积,并联一个3x3的卷积来替代。(可以认为只使用了inception mole中的一个分支,应该是为了简化网络结构)

先经过4个卷积层和2个全连接层,最后生成7x7x30的输出。先经过4个卷积层的目的是为了提高模型泛化能力。yolo将一副448x448的原图分割成了7x7个网格,每个网格要预测两个bounding box的坐标(x,y,w,h)和box内包含物体的置信度confidence,以及物体属于20类别中每一类的概率(yolo的训练数据为voc2012,它是一个20分类的数据集)。所以一个网格对应的参数为(4x2+2+20) = 30。如下图

其中前一项表示有无人工标记的物体落入了网格内,如果有则为1,否则为0。第二项代表bounding box和真实标记的box之间的重合度。它等于两个box面积交集,除以面积并集。值越大则box越接近真实位置。

分类信息: yolo的目标训练集为voc2012,它是一个20分类的目标检测数据集 。常用目标检测数据集如下表:

| Name | # Images (trainval) | # Classes | Last updated |

| --------------- | ------------------- | --------- | ------------ |

| ImageNet | 450k | 200 | 2015 |

| COCO | 120K | 90 | 2014 |

| Pascal VOC | 12k | 20 | 2012 |

| Oxford-IIIT Pet | 7K | 37 | 2012 |

| KITTI Vision | 7K | 3 | |

每个网格还需要预测它属于20分类中每一个类别的概率。分类信息是针对每个网格的,而不是bounding box。故只需要20个,而不是40个。而confidence则是针对bounding box的,它只表示box内是否有物体,而不需要预测物体是20分类中的哪一个,故只需要2个参数。虽然分类信息和confidence都是概率,但表达含义完全不同。

筛选层是为了在多个结果中(多个bounding box)筛选出最合适的几个,这个方法和faster R-CNN 中基本相同。都是先过滤掉score低于阈值的box,对剩下的box进行NMS非极大值抑制,去除掉重叠度比较高的box(NMS具体算法可以回顾上面faster R-CNN小节)。这样就得到了最终的最合适的几个box和他们的类别。

yolo的损失函数包含三部分,位置误差,confidence误差,分类误差。具体公式如下:

误差均采用了均方差算法,其实我认为,位置误差应该采用均方差算法,而分类误差应该采用交叉熵。由于物体位置只有4个参数,而类别有20个参数,他们的累加和不同。如果赋予相同的权重,显然不合理。故yolo中位置误差权重为5,类别误差权重为1。由于我们不是特别关心不包含物体的bounding box,故赋予不包含物体的box的置信度confidence误差的权重为0.5,包含物体的权重则为1。

Faster R-CNN准确率mAP较高,漏检率recall较低,但速度较慢。而yolo则相反,速度快,但准确率和漏检率不尽人意。SSD综合了他们的优缺点,对输入300x300的图像,在voc2007数据集上test,能够达到58 帧每秒( Titan X 的 GPU ),72.1%的mAP。

SSD网络结构如下图:

和yolo一样,也分为三部分:卷积层,目标检测层和NMS筛选层

SSD论文采用了VGG16的基础网络,其实这也是几乎所有目标检测神经网络的惯用方法。先用一个CNN网络来提取特征,然后再进行后续的目标定位和目标分类识别。

这一层由5个卷积层和一个平均池化层组成。去掉了最后的全连接层。SSD认为目标检测中的物体,只与周围信息相关,它的感受野不是全局的,故没必要也不应该做全连接。SSD的特点如下。

每一个卷积层,都会输出不同大小感受野的feature map。在这些不同尺度的feature map上,进行目标位置和类别的训练和预测,从而达到 多尺度检测 的目的,可以克服yolo对于宽高比不常见的物体,识别准确率较低的问题。而yolo中,只在最后一个卷积层上做目标位置和类别的训练和预测。这是SSD相对于yolo能提高准确率的一个关键所在。

如上所示,在每个卷积层上都会进行目标检测和分类,最后由NMS进行筛选,输出最终的结果。多尺度feature map上做目标检测,就相当于多了很多宽高比例的bounding box,可以大大提高泛化能力。

和faster R-CNN相似,SSD也提出了anchor的概念。卷积输出的feature map,每个点对应为原图的一个区域的中心点。以这个点为中心,构造出6个宽高比例不同,大小不同的anchor(SSD中称为default box)。每个anchor对应4个位置参数(x,y,w,h)和21个类别概率(voc训练集为20分类问题,在加上anchor是否为背景,共21分类)。如下图所示:

另外,在训练阶段,SSD将正负样本比例定位1:3。训练集给定了输入图像以及每个物体的真实区域(ground true box),将default box和真实box最接近的选为正样本。然后在剩下的default box中选择任意一个与真实box IOU大于0.5的,作为正样本。而其他的则作为负样本。由于绝大部分的box为负样本,会导致正负失衡,故根据每个box类别概率排序,使正负比例保持在1:3。SSD认为这个策略提高了4%的准确率

另外,SSD采用了数据增强。生成与目标物体真实box间IOU为0.1 0.3 0.5 0.7 0.9的patch,随机选取这些patch参与训练,并对他们进行随机水平翻转等操作。SSD认为这个策略提高了8.8%的准确率。

和yolo的筛选层基本一致,同样先过滤掉类别概率低于阈值的default box,再采用NMS非极大值抑制,筛掉重叠度较高的。只不过SSD综合了各个不同feature map上的目标检测输出的default box。

SSD基本已经可以满足我们手机端上实时物体检测需求了,TensorFlow在android上的目标检测官方模型ssd_mobilenet_v1_android_export.pb,就是通过SSD算法实现的。它的基础卷积网络采用的是mobileNet,适合在终端上部署和运行。

针对yolo准确率不高,容易漏检,对长宽比不常见物体效果差等问题,结合SSD的特点,提出了yoloV2。它主要还是采用了yolo的网络结构,在其基础上做了一些优化和改进,如下

网络采用DarkNet-19:19层,里面包含了大量3x3卷积,同时借鉴inceptionV1,加入1x1卷积核全局平均池化层。结构如下

yolo和yoloV2只能识别20类物体,为了优化这个问题,提出了yolo9000,可以识别9000类物体。它在yoloV2基础上,进行了imageNet和coco的联合训练。这种方式充分利用imageNet可以识别1000类物体和coco可以进行目标位置检测的优点。当使用imageNet训练时,只更新物体分类相关的参数。而使用coco时,则更新全部所有参数。

YOLOv3可以说出来直接吊打一切图像检测算法。比同期的DSSD(反卷积SSD), FPN(feature pyramid networks)准确率更高或相仿,速度是其1/3.。

YOLOv3的改动主要有如下几点:

不过如果要求更精准的预测边框,采用COCO AP做评估标准的话,YOLO3在精确率上的表现就弱了一些。如下图所示。

当前目标检测模型算法也是层出不穷。在two-stage领域, 2017年Facebook提出了mask R-CNN 。CMU也提出了A-Fast-RCNN 算法,将对抗学习引入到目标检测领域。Face++也提出了Light-Head R-CNN,主要探讨了 R-CNN 如何在物体检测中平衡精确度和速度。

one-stage领域也是百花齐放,2017年首尔大学提出 R-SSD 算法,主要解决小尺寸物体检测效果差的问题。清华大学提出了 RON 算法,结合 two stage 名的方法和 one stage 方法的优势,更加关注多尺度对象定位和负空间样本挖掘问题。

目标检测领域的深度学习算法,需要进行目标定位和物体识别,算法相对来说还是很复杂的。当前各种新算法也是层不出穷,但模型之间有很强的延续性,大部分模型算法都是借鉴了前人的思想,站在巨人的肩膀上。我们需要知道经典模型的特点,这些tricks是为了解决什么问题,以及为什么解决了这些问题。这样才能举一反三,万变不离其宗。综合下来,目标检测领域主要的难点如下:

一文读懂目标检测AI算法:R-CNN,faster R-CNN,yolo,SSD,yoloV2

从YOLOv1到v3的进化之路

SSD-Tensorflow超详细解析【一】:加载模型对图片进行测试  https://blog.csdn.net/k87974/article/details/80606407

YOLO    https://pjreddie.com/darknet/yolo/      https://github.com/pjreddie/darknet   

C#项目参考:https://github.com/AlturosDestinations/Alturos.Yolo

项目实践贴个图。

阅读全文

与目标检测算法opencv相关的资料

热点内容
c语言中编译和运行 浏览:997
画流图找循环编译原理 浏览:129
oppo手机西瓜视频的文件夹 浏览:867
骑手一般用哪个app 浏览:610
程序员老板用什么手机 浏览:848
比心app头像不通过为什么 浏览:105
加密币市值前十走势 浏览:190
单片机学习推荐课程 浏览:473
对数ln的运算法则图片 浏览:735
仿微博app源码 浏览:781
怎么取消调用app 浏览:545
程序员去哪里求助 浏览:834
服务器里的端口是什么 浏览:975
aspnetjavaphp 浏览:399
程序员毕业时间 浏览:286
程序员用户免费软件 浏览:754
51单片机汇编语言指令 浏览:139
女程序员好难 浏览:688
三田压缩机与电装 浏览:710
重生细胞安卓版没键盘怎么玩 浏览:994