AI备忘录 - 目标检测
type: channel
link: http://aiuai.cn/category/detection
items: YOLOV5 vs YOLOv8[译]
items: 计算机视觉之OCR
items: 计算机视觉之目标检测NMS
items: 计算机视觉之目标检测IoU
items: 计算机视觉之目标检测边界框和Anchor
items: 计算机视觉之目标检测综述
items: 目标追踪 - 监控领域必须了解的算法[转]
items: Github 项目 - yolov5 模型推理detect.py理解
items: 一文打尽目标检测NMS-精度提升篇[转]
items: Pytorch - FocalLoss的几种实现

YOLOV5 vs YOLOv8[译]
type: item
date: 2023-03-05T12:38:00+00:00
description: 原文：Comparing YOLOv5 and YOLOv8: Which one should you use?YOLOv5 vs YOLOv8相同点Backbone: 均是CSPDarknet53 Anchor Boxes： 均使用 anchor boxes 提升检测精度Non-Maximum Suppression (NMS)：均使用了NMS来滤除同一类别的多个检测框Post-processing：均采用了 post-processing 技术来提升检测精度Optimizer：均采用 Adam 进行模型训练Activation Function：均采用了 Mish 激活函数精度对比Yolov5 在 COCO 数据集的 AP(average precision) 是 50.5%. Yolov5 对于小目标检测同样表现优良，超过了其之前版本的 Yolo.Yolov5 对于真实世界的应用，同样表现不错，例如，视频流里的行人检测.Yolov8 在精度方面是超过 Yolov5 的，其AP是 51.4%，Yolov8m 的 AP 是 54.2%.Yolov8 对于小目标检测有着更优的表现，而且解决了一些 Yolov5 存在的不足.速度FPS对比总结对于小目标检测，Yolov5和Yolo8 均能处理；但，Yolov5 可能更适用于部署到没有 GPU 的设备. 如果有 GPU 的话，Yolov8 会是更好的选择.

计算机视觉之OCR
type: item
date: 2021-09-10T14:09:00+00:00
description: 出处：Paddle文档平台 - OCR1. OCR综述1.1. 什么是OCROCR(Optical Character Recognition,光学字符识别)是指对图像进行分析识别处理，获取文字和版面信息的过程，是典型的计算机视觉任务，通常由文本检测和文本识别两个子任务构成。文字检测：将图片中的文字区域位置检测出来（如图1(b)所示）；文字识别：对文字区域中的文字进行识别（如图1(c)所示）。1.2. OCR发展历程早在60、70年代，人们就开始对OCR进行研究。在研究的初期，主要以文字识别方法研究为主，而且识别的文字仅为0-9的数字。数字识别主要应用在识别邮件上的邮政编码。在深度学习出现之前，传统算法(如积分投影、腐蚀膨胀、旋转等)在OCR领域占据主导地位。其标准的处理流程包括：图像预处理、文本行检测、单字符分割、单字符识别、后处理。其中：图像预处理主要是对图像的成像问题进行修正，包括几何变换（透视、扭曲、旋转等），去模糊、光线矫正等；文本检测通常使用连通域、滑动窗口两个方向；字符识别算法主要包括图像分类、模版匹配等。受传统算法的局限性，传统OCR仅在比较规整的印刷文档上表现比较好，但在复杂场景(图像模糊、低分辨率、干扰信息)之下，文字检测、识别性能都不够理想。自2012年AlexNet在ImageNet竞赛夺冠以来，深度学习方法开始在图像视频领域大幅超越传统算法，OCR领域也引入了深度学习，包括基于卷积神经网络（Convolutional Neural Network, CNN）来取代传统算法提取特征。深度学习OCR主要分为2步，首先是检测出图像中的文本行、接着进行文本识别。1.3. OCR 常用检测方法OCR文字检测就是将图片中的文字区域检测出来。常用的基于深度学习的文字检测方法一般可以分为基于回归的、基于分割的两大类，当然还有一些将两者进行结合的方法。1.3.1. 基于回归的方法基于回归的方法又分为box回归和像素值回归：[1] - box回归采用box回归的方法主要有CTPN、Textbox系列和EAST优点：对规则形状文本检测效果较好缺点：无法准确检测不规则形状文本。[2] - 像素值回归采用像素值回归的方法主要有CRAFT和SA-Text，这类算法能够检测弯曲文本且对小文本效果优秀但是实时性能不够。1.3.2. 基于分割的算法如PSENet，这类算法不受文本形状的限制，对各种形状的文本都能取得较好的效果，但是往往后处理比较复杂，导致耗时严重。目前也有一些算法专门针对这个问题进行改进，如DB，将二值化进行近似，使其可导，融入训练，从而获取更准确的边界，大大降低了后处理的耗时。1.4. OCR常用识别方法RosettaCRNNSTAR-NetRARESRN1.5. OCR常用评估指标[1] - 检测阶段：先按照检测框和标注框的IOU评估，IOU大于某个阈值判断为检测准确。这里检测框和标注框不同于一般的通用目标检测框，是采用多边形进行表示。检测准确率：正确的检测框个数在全部检测框的占比，主要是判断检测指标。检测召回率：正确的检测框个数在全部标注框的占比，主要是判断漏检的指标。[2] - 识别阶段： 字符识别准确率，即正确识别的文本行占标注的文本行数量的比例，只有整行文本识别对才算正确识别。[3] - 端到端统计： 端对端召回率：准确检测并正确识别文本行在全部标注文本行的占比；端到端准确率：准确检测并正确识别文本行在 检测到的文本行数量 的占比； 准确检测的标准是检测框与标注框的IOU大于某个阈值，正确识别的的检测框中的文本与标注的文本相同。1.6. 应用场景在日常生活中，文字内容无处不在，根据拍摄的内容，自动分析图像中的文字信息已经成为人们的广泛诉求。而通过深度学习技术，可以自动的定位文字区域，并且学习包含丰富语义信息的特征，识别出图像中的文字内容。当前这一技术已经广泛应用于金融、交通等各行各业中。通用场景：办公文档、广告图、表格、手写数字、自然场景图等；卡证：身份证、银行卡、营业执照、名片等；汽车：车牌、驾驶证、合格证等；财务票据：火车票、飞机票、银行支票等；医疗票据：医疗发票、病例首页等；...1.7. OCR面临的挑战对应到OCR技术实现问题上，则一般面临仿射变换、尺度问题、光照不足、拍摄模糊等技术难点； 另外OCR应用常对接海量数据，因此要求数据能够得到实时处理；并且OCR应用常部署在移动端或嵌入式硬件，而端侧的存储空间和计算能力有限，因此对OCR模型的大小和预测速度有很高的要求。2. OCR 检测方法2.1. CTPN2.1.1. 模型介绍CTPN（Connectionist Text Proposal Network，Detecting Text in Natural Image with Connecti…

计算机视觉之目标检测NMS
type: item
date: 2021-09-08T14:07:00+00:00
description: 出处：Paddle文档平台 - 非极大值抑制在实际的目标检测过程中，不管是用什么方式获取候选区域，都会存在一个通用的问题，那就是网络对同一个目标可能会进行多次检测。这也就导致对于同一个物体，会产生多个预测框。因此需要消除重叠较大的冗余预测框。具体的处理方法就是非极大值抑制（NMS）。假设使用模型对图片进行预测，一共输出了11个预测框及其得分，在图上画出预测框如 图1 所示。在每个人像周围，都出现了多个预测框，需要消除冗余的预测框以得到最终的预测结果。图1 预测框示意图输出11个预测框及其得分的代码实现如下：# 画图展示目标物体边界框 import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib.image import imread import math # 定义画矩形框的程序 def draw_rectangle(currentAxis, bbox, edgecolor = 'k', facecolor = 'y', fill=False, linestyle='-'): # currentAxis，坐标轴，通过plt.gca()获取 # bbox，边界框，包含四个数值的list， [x1, y1, x2, y2] # edgecolor，边框线条颜色 # facecolor，填充颜色 # fill, 是否填充 # linestype，边框线型 # patches.Rectangle(xy, width, height,linewidth,edgecolor,facecolor,fill, linestyle) # xy:左下角坐标; width:矩形框的宽; height:矩形框的高; linewidth:线宽; edgecolor:边界颜色; facecolor:填充颜色; fill:是否填充; linestyle:线断类型 rect=patches.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0]+1, bbox[3]-bbox[1]+1, linewidth=1, edgecolor=edgecolor,facecolor=facecolor,fill=fill, linestyle=linestyle) currentAxis.add_patch(rect) plt.figure(figsize=(10, 10)) # 传入图片路径 filename = '/home/aistudio/work/images/section3/000000086956.jpg' im = imread(filename) plt.imshow(im) currentAxis=plt.gca() # 预测框位置，由网络预测得到 boxes = np.array([[4.21716537e+01, 1.28230896e+02, 2.26547668e+02, 6.00434631e+02], [3.18562988e+02, 1.23168472e+02, 4.79000000e+02, 6.05688416e+02], [2.62704697e+01, 1.39430557e+02, 2.20587097e+02, 6.38959656e+02], [4.24965363e+01, 1.42706665e+02, 2.25955185e+02, 6.35671204e+02], [2.37462646e+02, 1.35731537e+02, 4.79000000e+02, 6.31451294e+02], [3.19390472e+02, 1.29295090e+02, 4.79000000e+02, 6.33003845e+02], [3.28933838e+02, 1.22736115e+02, 4.79000000e+02, 6.39000000e+02], [4.44292603e+01, 1.70438187e+02, 2.26841858e+02, 6.39000000e+02], [2.17988785e+02, 3.02472412e+02, 4.06062927e+02, 6.29106628e+02], [2.00241089e+02, 3.23755096e+02, 3.96929321e+02, 6.36386108e+02], [2.14310303e+02, 3.23443665e+02, 4.06732849e+02, 6.35775269e+02]]) # 预测框得分，由网络预测得到 scores = np.a…

计算机视觉之目标检测IoU
type: item
date: 2021-09-08T12:03:00+00:00
description: 出处：Paddle文档平台 - IoU（交并比）在目标检测任务中，通常会使用交并比（Intersection of Union，IoU）作为衡量指标，来衡量两个矩形框之间的关系。例如在基于锚框的目标检测算法中，我们知道当锚框中包含物体时，我们需要预测物体类别并微调锚框的坐标，从而获得最终的预测框。此时，判断锚框中是否包含物体就需要用到交并比，当锚框与真实框交并比足够大时，我们就可以认为锚框中包含了该物体；而锚框与真实框交并比很小时，我们就可以认为锚框中不包含该物体。此外，在后面NMS的计算过程中，同样也要使用交并比来判断不同矩形框是否重叠。交并比这一概念来源于数学中的集合，用来描述两个集合$A$和$B$之间的关系，它等于两个集合的交集里面所包含的元素个数，除以它们的并集里面所包含的元素个数，具体计算公式如下：$$IoU = \frac{A\cap B}{A \cup B}$$我们将用这个概念来描述两个框之间的重合度。两个框可以看成是两个像素的集合，它们的交并比等于两个框重合部分的面积除以它们合并起来的面积。下图“交集”中青色区域是两个框的重合面积，下图“并集”中蓝色区域是两个框的相并面积。用这两个面积相除即可得到它们之间的交并比，如 图1 所示。图1 交并比假设两个矩形框A和B的位置分别为：$$A: [x_{a1}, y_{a1}, x_{a2}, y_{a2}]$$$$B: [x_{b1}, y_{b1}, x_{b2}, y_{b2}]$$假如位置关系如 图2 所示：图2 计算交并比如果二者有相交部分，则相交部分左上角坐标为：$$x_1 = max(x_{a1}, x_{b1}), \ \ \ \ \ y_1 = max(y_{a1}, y_{b1})$$相交部分右下角坐标为：$$x_2 = min(x_{a2}, x_{b2}), \ \ \ \ \ y_2 = min(y_{a2}, y_{b2})$$计算先交部分面积：$$intersection = max(x_2 - x_1 + 1.0, 0) \cdot max(y_2 - y_1 + 1.0, 0)$$矩形框A和B的面积分别是：$$S_A = (x_{a2} - x_{a1} + 1.0) \cdot (y_{a2} - y_{a1} + 1.0)$$$$S_B = (x_{b2} - x_{b1} + 1.0) \cdot (y_{b2} - y_{b1} + 1.0)$$计算相并部分面积：$$union = S_A + S_B - intersection$$计算交并比：$$IoU = \frac{intersection}{union}$$交并比实现代码如下：[1] - 当矩形框的坐标形式为xyxy时import numpy as np # 计算IoU，矩形框的坐标形式为xyxy def box_iou_xyxy(box1, box2): # 获取box1左上角和右下角的坐标 x1min, y1min, x1max, y1max = box1[0], box1[1], box1[2], box1[3] # 计算box1的面积 s1 = (y1max - y1min + 1.) * (x1max - x1min + 1.) # 获取box2左上角和右下角的坐标 x2min, y2min, x2max, y2max = box2[0], box2[1], box2[2], box2[3] # 计算box2的面积 s2 = (y2max - y2min + 1.) * (x2max - x2min + 1.) # 计算相交矩形框的坐标 xmin = np.maximum(x1min, x2min) ymin = np.maximum(y1min, y2min) xmax = np.minimum(x1max, x2max) ymax = np.minimum(y1max, y2max) # 计算相交矩形行的高度、宽度、面积 inter_h = np.maximum(ymax - ymin + 1., 0.) inter_w = np.maximum(xmax - xmin + 1., 0.) intersection = inter_h * inter_w # 计算相并面积 union = s1 + s2 - intersection # 计算交并比 iou = intersection / union return iou bbox1 = [100., 100., 200., 200.] bbox2 = [120., 120., 220., 220.] iou = box_iou_xyxy(bbox1, bbox2) print('IoU is {}'.fo…

计算机视觉之目标检测边界框和Anchor
type: item
date: 2021-09-07T14:01:00+00:00
description: 出处：Paddle文档平台 - 边界框（bounding box）1. 边界框（bounding box）在检测任务中，需要同时预测物体的类别和位置，因此需要引入一些跟位置相关的概念。通常使用边界框（bounding box，bbox）来表示物体的位置，边界框是正好能包含物体的矩形框，如 图1 所示，图中3个人分别对应3个边界框。图1 边界框通常表示边界框的位置有两种方式：[1] - 即$(x_1, y_1, x_2, y_2)$，其中$(x_1, y_1)$是矩形框左上角的坐标，$(x_2, y_2)$是矩形框右下角的坐标。如，图1 中3个红色矩形框用$xyxy$格式表示如下：左：$(40.93, 141.1, 226.99, 515.73)$。中：$(214.29, 325.03, 399.82, 631.37)$。右：$(247.2, 131.62, 480.0, 639.32)$。[2] - $xywh$，即$(x, y, w, h)$，其中$(x, y)$是矩形框中心点的坐标，$w$是矩形框的宽度，$h$是矩形框的高度。在检测任务中，训练数据集的标签里会给出目标物体真实边界框所对应的$(x_1, y_1, x_2, y_2)$，这样的边界框也被称为真实框（ground truth box），图1 画出了3个人像所对应的真实框。模型会对目标物体可能出现的位置进行预测，由模型预测出的边界框则称为预测框（prediction box）。要完成一项检测任务，通常希望模型能够根据输入的图片，输出一些预测的边界框，以及边界框中所包含的物体的类别或者说属于某个类别的概率，例如这种格式: $[L, P, x_1, y_1, x_2, y_2]$，其中$L$是预测出的类别标签，$P$是预测物体属于该类别的概率。一张输入图片可能会产生多个预测框，接下来让我们一起学习如何完成这项任务。注意：在阅读代码时，请注意使用的是哪一种格式的表示方式。图片坐标的原点在左上角，$x$轴向右为正方向，$y$轴向下为正方向。2. 锚框（Anchor box）目标检测算法通常会在输入图像中采样大量的区域，然后判断这些区域中是否包含我们感兴趣的目标，并调整区域边缘从而更准确地预测目标的真实边界框（ground-truth bounding box）。不同的模型使用的区域采样方法可能不同。这里我们介绍其中的一种方法：它以每个像素为中心生成多个大小和宽高比（aspect ratio）不同的边界框。这些边界框被称为锚框（anchor box）。在目标检测任务中，我们会先设定好锚框的大小和形状，再以图像上某一个点为中心画出这些锚框，将这些锚框当成可能的候选区域。目前，常用的锚框尺寸选择方法有：[1] - 人为经验选取[2] - k-means聚类[3] - 作为超参数进行学习模型对这些候选区域是否包含物体进行预测，如果包含目标物体，则还需要进一步预测出物体所属的类别。还有更为重要的一点是，模型需要预测出微调的幅度。这是因为锚框位置是固定的，它不大可能刚好跟物体边界框重合，所以需要在锚框的基础上进行微调以形成能准确描述物体位置的预测框。在训练过程中，模型通过学习不断的调整参数，最终能学会如何判别出锚框所代表的候选区域是否包含物体，如果包含物体的话，物体属于哪个类别，以及物体边界框相对于锚框位置需要调整的幅度。而不同的模型往往有着不同的生成锚框的方式。在下图中，以像素点[300, 500]为中心可以使用下面的程序生成3个框，如 图2 中蓝色框所示，其中锚框A1跟人像区域非常接近。图2 锚框# 画图展示如何绘制边界框和锚框 import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib.image import imread import math # 定义画矩形框的程序 def draw_rectangle(currentAxis, bbox, edgecolor = 'k', facecolor = 'y', fill=False, linestyle='-'): # currentAxis，坐标轴，通过plt.gca()获取 # bbox，边界框，包含四个数值的list， [x1, y1, x2, y2] # edgecolor，边框线条颜色 # facecolor，填充颜色 # fill, 是否填充 # linestype，边框线型 # patches.Rectangle(xy, width, height,linewidth,edgecolor,facecolor,fill, linestyle) # xy:左下角坐标; …

计算机视觉之目标检测综述
type: item
date: 2021-09-07T13:00:00+00:00
description: 出处：Paddle文档平台 - 目标检测对计算机而言，能够“看到”的是图像被编码之后的数字，它很难理解高层语义概念，比如图像或者视频帧中出现的目标是人还是物体，更无法定位目标出现在图像中哪个区域。目标检测的主要目的是让计算机可以自动识别图片或者视频帧中所有目标的类别，并在该目标周围绘制边界框，标示出每个目标的位置，如 图1 所示。图1 图像分类和目标检测示意图图1(a)是图像分类任务，只需对这张图片进行类别识别。图1(b)是目标检测任务，不仅要识别出这一张图片中的类别为斑马，还要标出图中斑马的位置。1. 应用场景如 图2 所示，如今的目标检测不论在日常生活中还是工业生产中都有着非常多的应用场景。消费娱乐：智能手机的人脸解锁以及支付APP中的人脸支付；自动售货机使用的商品检测；视频网站中图片、视频审核等；智慧交通：自动驾驶中的行人检测、车辆检测、红绿灯检测等；工业生产：工业生产中的零件计数、缺陷检测；设备巡检场景下的设备状态监控；厂区中的烟火检测、安全帽检测等；智慧医疗：眼底、肺部等器官病变检测；新冠疫情中的口罩检测等。图2 目标检测应用场景2. 目标检测发展历程在图像分类任务中，会先使用卷积神经网络提取图像特征，然后再用这些特征预测分类概率，根据训练样本标签建立起分类损失函数，开启端到端的训练，如 图3 所示。图3 图像分类流程示意图但对于目标检测问题，按照 图3 的流程则行不通。因为在对整张图提取特征的过程中无法体现出不同目标之间的区别，最终也就没法分别标示出每个物体所在的位置。为了解决这个问题，结合图片分类任务取得的成功经验，我们可以将目标检测任务进行拆分。假设我们使用某种方式在输入图片上生成一系列可能包含物体的区域，这些区域称为候选区域。对于每个候选区域，可以单独当成一幅图像来看待，使用图像分类模型对候选区域进行分类，看它属于哪个类别或者背景（即不包含任何物体的类别）。那么，现在问题的关键就是如何产生候选区域？比如我们可以使用穷举法来产生候选区域，如 图4 所示。图4 候选区域A为图像上的某个像素点，B为A右下方另外一个像素点，A、B两点可以确定一个矩形框，记作AB。如图4(a)所示：A在图片左上角位置，B遍历除A之外的所有位置，生成矩形框$A_1B_1, …, A_1B_n, …$如图4(b)所示：A在图片中间某个位置，B遍历A右下方所有位置，生成矩形框$A_kB_1, …, A_kB_n, …$当A遍历图像上所有像素点，B则遍历它右下方所有的像素点，最终生成的矩形框集合${A_iB_j}$将会包含图像上所有可以选择的区域。只要我们对每个候选区域的分类足够的准确，则一定能找到跟实际物体足够接近的区域来。穷举法也许能得到正确的预测结果，但其计算量也是非常巨大的，其所生成的总候选区域数目约为$\frac{W^2 H^2}{4}$，假设$H=W=100$，总数将会达到$2.5 \times 10^{7}$个，如此多的候选区域使得这种方法几乎没有什么实用性。但是通过这种方式，我们可以看出，假设分类任务完成的足够完美，从理论上来讲检测任务也是可以解决的，亟待解决的问题是如何设计出合适的方法来产生候选区域。科学家们开始思考，是否可以应用传统图像算法先产生候选区域，然后再用卷积神经网络对这些区域进行分类？2013年，Ross Girshick等人于首次将CNN的方法应用在目标检测任务上，他们使用传统图像算法Selective Search产生候选区域，取得了极大的成功，这就是对目标检测领域影响深远的区域卷积神经网络(R-CNN[1])模型。2015年，Ross Girshick对此方法进行了改进，提出了Fast R-CNN[2]模型。通过将不同区域的物体共用卷积层的计算，大大缩减了计算量，提高了处理速度，而且还引入了调整目标物体位置的回归方法，进一步提高了位置预测的准确性。2015年，Shaoqing Ren等人提出了Faster R-CNN[3]模型，提出了RPN的方法来产生物体的候选区域，这一方法不再需要使用传统的图像处理算法来产生候选区域，进一步提升了处理速度。2017年，Kaiming He等人提出了Mask R-CNN[4]模型，只需要在Faster R-CNN模型上添加比较少的计算量，就可以同时实现目标检测和物体实例分割两个任务。以上都是基于R-CNN系列的著名模型，对目标检测方向的发展有着较大的影响力。此外，还有一些其他模型，比如SSD[5]、YOLO[6,7,8]、R-FCN[9]等也都是目标检测领域流行的模型结构。图5 为目标检测综述文章[10]中的一幅图，梳理了近些年目标检测算法的发展流程。图5 目标检测算法发展流程其中，由于上文所述的R-CNN的系列算法将目标检测任务分成两个阶段，先在图像上产生候选区域，再对候…

目标追踪 - 监控领域必须了解的算法[转]
type: item
date: 2020-11-02T12:29:00+00:00
description: 原文：多目标跟踪：监控领域你必须要了解的算法 - 2011.11.01英文：The Surveillance phenomenon you must know about : Multi Object Tracking出处：AI 公园 - 微信公众号作者：Deval Shah编译：ronghuaiyang在深入到目标跟踪的世界之前，必须理解监控世界的“为什么”和“是什么”. 全球各国都安装了数百万个摄像头，但几乎没有人监控它们. 人与摄像机的比例很小. 由于深度学习技术在监控领域的广泛应用，智能软件在过去十年中接管了监控领域. 复杂的问题，如人员跟踪，交通密度估计，盗窃保护等，已经被世界各地的杰出研究人员解决了，并显示了巨大的前景1. 目标追踪介绍目标跟踪是指根据之前的信息估计场景中目标物体的状态. 在high level的抽象中，主要有两个层次的物体跟踪.单目标跟踪(SOT)多目标跟踪(MOT)目标跟踪不局限于二维序列数据，可以应用于三维领域. 这里，将深入研究目标跟踪范式的一个子领域，即，使用深度学习的二维视频序列中的多目标跟踪(MOT). 深度神经网络(DNN)的强大之处在于它们能够学习丰富的表示，并从输入中提取复杂和抽象的特征. 多目标跟踪(MOT)，也称为多目标跟踪(MTT)，是一种计算机视觉任务，旨在分析视频，以识别和跟踪属于一个或多个类别的对象，如行人，汽车，动物和无生命的物体，没有任何先验的目标外观和目标数量. 在单目标跟踪中，目标的出现是预先知道的，而在多目标跟踪中，需要一个检测步骤来识别出进入或离开场景的目标. 同时跟踪多个目标的主要困难来自于各种各样的遮挡以及物体之间的相互重叠，有时物体间也会有相似的外观. 因此，仅仅使用SOT模型直接解决MOT问题，往往会导致较差的结果，往往会导致目标漂移和大量的ID切换错误，因为此类模型往往难以区分外观相似的类内物体. 近年来，由于深度学习方法的研究呈指数级增长，检测和跟踪方法在准确性和性能方面取得了巨大的进步. 大多数先进的跟踪方法遵循“检测跟踪”的方案，他们首先在场景中找到对象，然后找到对象对应的tracklets(它在下一帧的位置). 如今，这种探测器的性能异常出色，能够适应不同的场景. 因此，它定义了跟踪算法的标准输入. 还有其他的方法，比如Lucas Kanade的光流，基于排序的跟踪等，它们在传统的计算机视觉方法的基础上表现也都很出色.2. 目标追踪挑战在解决目标跟踪问题时，会出现一些问题，这些问题会导致糟糕的结果. 多年来，算法试图解决这些问题，但到目前为止，还没有找到一个被充分证明的解决办法，这仍然是一个开放的研究领域. [1] - 由于几何变化导致的多样性，如：姿态，关节，物体的尺度[2] - 由于光学因素的差异. 例如：照明、外观[3] - 非线性运动[4] - 有限的分辨率，如从低端手机采集的视频[5] - 场景中有相似的物体，例如：相同颜色的衣服，配饰等[6] - 高度拥挤的场景，如街道，音乐会，体育馆，市场. [7] - 跟踪起始和终止. 在开始任何跟踪算法之前，你需要想要跟踪的物体的先验信息. 但是并不是一定可以使用目标对象初始化算法. [8] - 跟踪轨迹可能由于运动的突然变化导致合并和切换，比如相机成像质量的急剧变化等. [9] - 由于相似的特征，如相似的衣服，面部结构，眼镜，肤色，身高等，目标物体的ID可能被切换. [10] - 目标模型更新错误导致漂移. 一次错误的更新可能会导致在错误的方向上持续的更新，从而在整个视频中遗忘掉正确的目标.3. 目标追踪文章这些只是精心挑选出来的一些非常好的跟踪领域的研究论文：[1] - Tracking without bells and whistles.论文：https://arxiv.org/pdf/1903.05625.pdf代码：https://github.com/phil-bergmann/tracking_wo_bnw[2] - Extending IOU Based Multi-Object Tracking by Visual Information.论文：http://elvera.nue.tu-berlin.de/files/1547Bochinski2018.pdf代码：https://github.com/bochinski/iou-tracker[3] - Tracking Objects as Points.论文：https://arxiv.org/pdf/2004.01177.pdf代码：https://github.com/xingyizhou/CenterTrack[4] - Fast Visual Object Tracking with Rotated B…

Github 项目 - yolov5 模型推理detect.py理解
type: item
date: 2020-11-01T01:50:49+00:00
description: Github - ultralytics/yolov5yolov5/detect.py - https://github.com/ultralytics/yolov5/blob/master/detect.pyYolov5 的检测示例, 如：python detect.py --weights yolov5s.pt --img 416 --conf 0.4 --source inference/images/结果例图：1. 数据加载yolov5 detect.py 支持多种输入，如：images, videos, directories, webcams, rtsp 和 http streams.python detect.py \ --source file.jpg # image file.mp4 # video dir/ # directory 0 # webcam 'rtsp://170.93.143.139/rtplive/470011e600ef003a004ee33696235daa' # rtsp 'http://112.50.243.8/PLTV/88888888/224/3221225900/1.m3u8' # http对应的包含两个数据加载 Dataloader 函数：LoadStreams() 和 LoadImages().1.1. LoadStreamsclass LoadStreams: # multiple IP or RTSP cameras def __init__(self, sources='streams.txt', img_size=640): self.mode = 'images' self.img_size = img_size # 多个 sources 源 if os.path.isfile(sources): with open(sources, 'r') as f: sources = [x.strip() for x in f.read().splitlines() if len(x.strip())] else: sources = [sources] n = len(sources) self.imgs = [None] * n self.sources = sources for i, s in enumerate(sources): # 启动视频流读取线程. print('%g/%g: %s... ' % (i + 1, n, s), end='') cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s) assert cap.isOpened(), 'Failed to open %s' % s w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = cap.get(cv2.CAP_PROP_FPS) % 100 _, self.imgs[i] = cap.read() # guarantee first frame thread = Thread(target=self.update, args=([i, cap]), daemon=True) print(' success (%gx%g at %.2f FPS).' % (w, h, fps)) thread.start() print('') # newline # check for common shapes # 检验所有输入图像的shapes s = np.stack([letterbox(x, new_shape=self.img_size)[0].shape for x in self.imgs], 0) # inference shapes self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal if not self.rect: print('WARNING: Different stream shapes detected. For optimal performance supply similarly-shaped streams.') def update(self, index, cap): # 守护线程中读取下一帧 # Read next stream frame in a daemon thread n = 0 while cap.isOpened(): n += 1 # _, sel…

一文打尽目标检测NMS-精度提升篇[转]
type: item
date: 2020-07-14T13:53:54+00:00
description: 原文：一文打尽目标检测NMS——精度提升篇 - 2020.07.01 - 知乎作者：曲終人不散丶众所周知，非极大值抑制NMS是目标检测常用的后处理算法，用于剔除冗余检测框，本文将对可以提升精度的各种NMS方法及其变体进行阶段性总结. 总体概要：对NMS进行分类，大致可分为以下六种，这里是依据它们在各自论文中的核心论点进行分类，这些算法可以同时属于多种类别.分类优先：传统NMS，Soft-NMS (ICCV 2017)定位优先：IoU-Guided NMS (ECCV 2018)加权平均：Weighted NMS (ICME Workshop 2017)方差加权平均：Softer-NMS (CVPR 2019)自适应阈值：Adaptive NMS (CVPR 2019)+中心点距离：DIoU-NMS (AAAI 2020)1. 分类优先1.1. 传统 NMS传统NMS有多个名称，据不完全统计可以被称为：Traditional/Original/Standard/Greedy NMS，为统一起见，下称Traditional NMS. Traditional NMS算法是最为经典的版本，伪代码如下：作为最为人所知晓的版本，Traditional NMS不仅有CPU版本，并且现已有GPU版本，GPU版本为Ross Girshick大神编写，俗称CUDA NMS. 多个深度学习框架也已将CUDA NMS纳入，作为基本函数使用，如Pytorch在Torchvision 0.3中正式集成了CUDA NMS. 缺点：顺序处理的模式，计算IoU拖累了运算效率.剔除机制太严格，依据NMS阈值暴力剔除.阈值是经验选取的.评判标准是IoU，即只考虑两个框的重叠面积，这对描述box重叠关系或许不够全面.1.2. Soft-NMSSoft-NMS是Traditional NMS的推广，主要旨在缓解Traditional NMS的第二条缺点. 数学上看，Traditional NMS的剔除机制可视为：$$ s_i = \begin{cases} 0 & IoU(M, B_i) \geq thresh \\ s_i & IoU(M, B_i) <thresh \end{cases} $$显然，对于 IoU≥NMS阈值的相邻框，Traditional NMS的做法是将其得分暴力置0. 这对于有遮挡的案例较不友好. 因此Soft-NMS的做法是采取得分惩罚机制，使用一个与IoU正相关的惩罚函数对得分 $s$ 进行惩罚. 线性惩罚：$$ s_i = \begin{cases} s_i(1 - IoU(M, B_i)) & DIoU(M, B_i) \geq thresh \\ s_i & DIoU(M, B_i) <thresh \end{cases} $$其中，$M$ 代表当前的最大得分框.线性惩罚有不光滑的地方，因而还有一种高斯惩罚：$$ s_i = s_i e ^{- \frac{IoU(M, B_i)^2}{\sigma}} $$在迭代终止之后，Soft-NMS依据预先设定的得分阈值来保留幸存的检测框，通常设为0.0001.该文对两种惩罚方法的超参数也进行了实验，结果验证了超参数的不敏感性. 经作者实测，Soft-NMS在Faster R-CNN中的提升约有0.5-0.8个点的AP提升. 缺点：仍然是顺序处理的模式，运算效率比Traditional NMS更低.对双阶段算法友好，而在一些单阶段算法上可能失效.如果存在定位与得分不一致的情况，则可能导致定位好而得分低的框比定位差得分高的框惩罚更多(遮挡情况下).评判标准是IoU，即只考虑两个框的重叠面积，这对描述box重叠关系或许不够全面.2. 定位优先IoU-Guided NMS出现于 IoU-Net 一文中，研究者认为框的定位与分类得分可能出现不一致的情况，特别是框的边界有模棱两可的情形时. 因而该文提出了IoU预测分支，来学习定位置信度，进而使用定位置信度来引导NMS. 具体来说，就是使用定位置信度作为NMS的筛选依据，每次迭代挑选出最大定位置信度的框M，然后将IoU≥NMS阈值的相邻框剔除，但把冗余框及其自身的最大分类得分直接赋予M，这样一来，最终输出的框必定是同时具有最大分类得分与最大定位置信度的框. 优点：IoU-Guided NMS有助于提高严格指标下的精度，如AP75, AP90. 缺点：顺序处理的模式，运算效率与Traditional NMS相同.需要额外添加IoU预测分支，造成计算开销.评判标准是IoU，即只考虑两个框的重叠面积，这对描述box重叠关系或许不够全面.3. 加权平均多框共同决定一框Weighted NMS出现于ICME Workshop 2017 Inception Sing…

Pytorch - FocalLoss的几种实现
type: item
date: 2020-02-24T12:49:00+00:00
description: FocalLoss 用于 one-stage 目标检测算法(Retinanet)，提升检测效果.也可以被用于分类任务中，解决数据不平衡问题.1. Github - DeepLabV3Plus-PytorchDeepLabV3Plus-Pytorch/utils/loss.pyimport torch import torch.nn as nn import torch.nn.functional as F class FocalLoss(nn.Module): def __init__(self, alpha=1, gamma=0, size_average=True, ignore_index=255): super(FocalLoss, self).__init__() self.alpha = alpha self.gamma = gamma self.ignore_index = ignore_index self.size_average = size_average def forward(self, inputs, targets): ce_loss = F.cross_entropy(inputs, targets, reduction='none', ignore_index=self.ignore_index) pt = torch.exp(-ce_loss) focal_loss = self.alpha * (1-pt)**self.gamma * ce_loss if self.size_average: return focal_loss.mean() else: return focal_loss.sum()2. Github - Focal-Loss-PytorchGithub - yatengLG/Focal-Loss-Pytorch基于Pytorch实现Focal loss基于 Pytorch 的实现如：#!-*- coding: utf-8 -*- # @Author : LG from torch import nn import torch from torch.nn import functional as F class focal_loss(nn.Module): def __init__(self, alpha=0.25, gamma=2, num_classes = 3, size_average=True): """ focal_loss损失函数, -α(1-yi)**γ *ce_loss(xi,yi) 步骤详细的实现了 focal_loss损失函数. :param alpha: 阿尔法α,类别权重. 当α是列表时,为各类别权重； 当α为常数时,类别权重为[α, 1-α, 1-α, ....], 常用于目标检测算法中抑制背景类, retainnet中设置为0.25 :param gamma: 伽马γ,难易样本调节参数. retainnet中设置为2 :param num_classes: 类别数量 :param size_average: 损失计算方式,默认取均值 """ super(focal_loss,self).__init__() self.size_average = size_average if isinstance(alpha,list): assert len(alpha)==num_classes # α可以以list方式输入, # size:[num_classes] 用于对不同类别精细地赋予权重 print("Focal_loss alpha = {}, 将对每一类权重进行精细化赋值".format(alpha)) self.alpha = torch.Tensor(alpha) else: assert alpha<1 #如果α为一个常数,则降低第一类的影响,在目标检测中为第一类 print("Focal_loss alpha = {} ,将对背景类进行衰减,请在目标检测任务中使用.".format(alpha)) self.alpha = torch.zeros(num_classes) self.alpha[0] += alpha self.alpha[1:] += (1-alpha) # α 最终为 [ α, 1-α, 1-α, 1-α, 1-α, ...] size:[num_classes] self.gamma = gamma def forward(self, preds, labels): """ focal_loss损失计算 :param preds: 预测类别. size:[B,N,C] or [B,C] 分 别对应与检测与分类…