该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~
上一篇文章是图像处理的最后一篇文章,写到这里,第一阶段的44篇Python图像处理就介绍完毕。接下来我们进入Python图像识别第二阶段,该部分主要以目标检测、图像识别以及深度学习相关图像分类为主,将会分享近50篇文章,感谢您一如至往的支持。作者也会继续加油的!
本文主要介绍目标检测原理,通过七个问题来普及什么是目标检测。然后利用ImageAI实现最简单的目标检测案例,加深读者的印象。希望您喜欢,且看且珍惜。
万字长文整理,希望对您有所帮助。同时,该部分知识均为作者查阅资料撰写总结,并且开设成了收费专栏,为小宝赚点奶粉钱,感谢您的抬爱。如果有问题随时私聊我,只望您能从这个系列中学到知识,一起加油。代码下载地址(如果喜欢记得star,一定喔):
图像识别:
图像处理:
该部分结合自己多年图像识别的经验,并参考图像算法AI(yegeli)、Zhengxia Zou、牛戈和SIGAI老师们的文章进行总结。主要通过七个核心问题带领初学者了解什么是目标检测。
目标检测(Object Detection)旨在寻找出图像中所有感兴趣的目标物体或对象,包含物体定位和物体分类两个子任务,同时确定它们的类别和位置。如下图所示,通过卷积神经网络有效定位猫的轮廓及类别。
目标检测是计算机视觉领域中最基本、最具挑战性的问题之一,近年来受到了广泛的关注。它在过去二十年的发展可以说是计算机视觉历史的缩影。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡、天气、分辨率、景深等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题,并且目标检测的结果将直接影响后续的跟踪、动作识别和行为描述的效果。因此,目标检测发展到今天仍然是非常具有挑战且存在很大提升空间的问题。
在计算机视觉领域,图像识别主要包括四大类任务:
如上图所示(引用yegeli老师,推荐大家关注),目标检测主要是实现分类问题和定位问题的叠加。其核心问题即:
同时,需要解决大小问题(目标存在各种不同的大小)和形状问题(目标可能有各种不同的形状)。
每个领域的分类方法通常各式各样,这里主要介绍两种分类方法。
(1) 基于应用程序的角度分类
目标检测作为计算机视觉的基本问题之一,是许多其他计算机视觉任务的基础,如实例分割、图像字幕、对象跟踪等。从应用程序的角度来看,目标检测可以被分为两个研究主题:
general object detection
旨在探索统一框架下检测不同类型物体的方法,以模拟人类的视觉和认知。
detection applications
指特定应用场景下的检测,如行人检测、人脸检测、文本检测等。
近年来,随着深度学习技术的快速发展,为目标检测注入了新的血液,取得了显著的突破,将其推向了一个前所未有的研究热点。目前,目标检测已广泛应用于自主驾驶、机器人视觉、视频监控等领域。下图显示了过去二十年中与“目标检测”相关的出版物数量的增长。
(2) 基于深度学习的目标检测分类
基于深度学习的目标检测算法主要分为两类:Two stage和One stage。
在过去的二十年中,人们普遍认为,目标检测的发展大致经历了两个历史时期:“ 传统的目标检测时期 ” ( 2014年以前 ) 和 “ 基于深度学习的检测时期 ” ( 2014年以后 ),其发展历程如下图所示。
下面分别列举了各里程碑式的目标检测算法,后续博客会分别进行详细介绍及编程案例实现。
(1) 传统检测器(Traditional Detectors)
早期的目标检测算法大多是基于手工特征构建的。由于当时缺乏有效的图像表示,人们只能设计复杂的特征表示,以及各种加速技术来用尽有限的计算资源。
Viola Jones Detectors
2001年,P. Viola和M. Jones在没有任何约束条件(如肤色分割)的情况下首次实现了人脸的实时检测。VJ检测器采用滑动窗口最直接的检测方法,查看图像中所有可能的位置和比例,看看是否有窗口包含人脸。其检测器结合了 “积分图像”、“特征选择” 和 “检测级联” 三种重要技术,大大提高了检测速度。
HOG Detector
方向梯度直方图(HOG)特征描述符最初是由N. Dalal和B.Triggs在2005年提出的。HOG可以被认为是对当时的尺度不变特征变换和形状上下文的重要改进。多年来,HOG检测器一直是许多目标检测器和各种计算机视觉应用的重要基础。
Deformable Part-based Model (基于可变形部件的模型,DPM)
DPM最初是由P. Felzenszwalb提出的,于2008年作为HOG检测器的扩展。DPM遵循“分而治之”的检测思想,训练可以简单地看作是学习一种正确的分解对象的方法,推理可以看作是对不同对象部件的检测的集合。例如,检测“汽车”的问题可以看作是检测它的窗口、车身和车轮。
(2) CNN based Two-stage Detectors
随着手工特征的性能趋于饱和,目标检测在2010年之后达到了一个稳定的水平。2012年卷积神经网络在世界范围内重生。由于深度卷积网络能够学习图像的鲁棒性和高层次特征表示,一个自然的问题是我们能否将其应用到目标检测中?
在2014年,R. Girshick等人率先打破僵局,提出了具有CNN特征的区域(RCNN)用于目标检测。从那时起,目标检测开始以前所未有的速度发展。在深度学习时代,目标检测可以分为两类,即 two-stage detection 和 one-stage detection,分别对应“从粗到细”的检测过程和“一步完成”的检测过程。
RCNN
RCNN首先通过选择性搜索提取一组对象候选框。然后,每个提案都被重新调整成一个固定大小的图像,并输入到一个在 ImageNet 上训练得到的CNN模型 ( 如AlexNet) 来提取特征。最后,利用线性SVM分类器对每个区域内的目标进行预测,识别目标类别。
SPPNet
2014年,K. He等人提出了空间金字塔池化网络 ( Spatial Pyramid Pooling Networks,SPPNet ) 。以前的CNN模型需要固定大小的输入,例如,AlexNet需要224x224图像。SPPNet主要贡献是引入了空间金字塔池化(SPP)层,它使CNN能够生成固定长度的表示,而不需要重新缩放图像/感兴趣区域的大小。利用SPPNet进行目标检测时,只对整个图像进行一次特征映射计算,然后生成任意区域的定长表示,训练检测器,避免了卷积特征的重复计算。
Fast RCNN
2015年,R. Girshick提出了 Fast RCNN 检测器,这是对 R-CNN和SPPNet的进一步改进。Fast-RCNN融合了R-CNN和SPPNet的优点,使我们能够在相同的网络配置下同时训练检测器和边界框回归器。
Faster RCNN
2015年,S. Ren等人提出了 Faster RCNN 检测器,在 Fast RCNN 之后不久。Faster RCNN是第一个端到端的,也是第一个接近实时的深度学习检测器。Faster RCNN 主要贡献是引入了区域建议网络 ( RPN ),使几乎cost-free的区域建议成为可能。从RCNN到Faster RCNN,一个目标检测系统中的大部分独立块,如提案检测、特征提取、边界框回归等,都已经逐渐集成到一个统一的端到端学习框架中。
Feature Pyramid Networks(FPN)
2017年,T.-Y.Lin等人基于 Faster RCNN 提出了特征金字塔网络 ( FPN )。在FPN之前,大多数基于深度学习的检测器只在网络的顶层进行检测。虽然CNN较深层的特征有利于分类识别,但不利于对象的定位。为此,开发了具有横向连接的自顶向下体系结构,用于在所有级别构建高级语义。由于CNN通过它的正向传播,自然形成了一个特征金字塔,FPN在检测各种尺度的目标方面显示出了巨大的进步。FPN现在已经成为许多最新探测器的基本组成部分。
(3) CNN based One-stage Detectors
You Only Look Once (YOLO)
YOLO由R. Joseph等人于2015年提出,它是深度学习时代的第一个单级检测器。YOLO是“You Only Look Once”的缩写,其速度较快。从它的名字可以看出,作者完全抛弃了之前的“提案检测+验证”的检测范式。相反,它遵循一个完全不同的哲学:将单个神经网络应用于整个图像。该网络将图像分割成多个区域,同时预测每个区域的边界框和概率。后来R. Joseph在 YOLO 的基础上进行了一系列改进,提出了其 v2 和 v3 版本,在保持很高检测速度的同时进一步提高了检测精度。尽管与两级探测器相比,它的探测速度有了很大的提高,但是YOLO的定位精度有所下降,特别是对于一些小目标。
Single Shot MultiBox Detector (SSD)
SSD由W. Liu等人于2015年提出,这是深度学习时代的第二款单级探测器。SSD的主要贡献是引入了多参考和多分辨率检测技术,这大大提高了单级检测器的检测精度,特别是对于一些小目标。SSD与以往任何检测器的主要区别在于,前者在网络的不同层检测不同尺度的对象,而后者仅在其顶层运行检测。
RetinaNet
单级检测器速度快、结构简单,但多年来一直落后于两级检测器的精度。T.-Y.Lin等人发现了背后的原因,并在2017年提出了RetinaNet。他们声称,在密集探测器训练过程中所遇到的极端的前景-背景阶层不平衡(the extreme foreground-background class imbalance)是主要原因。为此,在 RetinaNet 中引入了一个新的损失函数“焦损失(focal loss)”,通过对标准交叉熵损失的重构,使检测器在训练过程中更加关注难分类的样本。焦损耗使得单级检测器在保持很高的检测速度的同时,可以达到与两级检测器相当的精度。
建立具有更少偏置的大数据集,是开发先进的计算机视觉算法的关键。在目标检测方面,在过去10年中,已经发布了许多著名的数据集和基准测试,包括 PASCAL VOC 挑战的数据集(如VOC2007、VOC2012)、ImageNet大尺度视觉识别挑战(如ILSVRC2014)、MS-COCO检测挑战等。表1给出了这些数据集的统计数据。下图显示了这些数据集的一些图像示例。
近20年来,目标检测取得了显著的成就。包括里程碑检测器、关键技术、加速方法、检测应用、数据集和指标,,如VJ、HOG、DPM、Faster-RCNN、YOLO、SSD等。未来的目标检测研究可能会集中在以下几个方面:
加快检测算法的速度(Lightweight object detection)
使其能够在移动设备上平稳运行。一些重要的应用包括移动增强现实、智能摄像头、人脸验证等。虽然近年来已经做了很大的努力,但机器和人眼之间的速度差距仍然很大,特别是在检测一些小物体时。
自动机器学习目标检测(Detection meets AutoML)
近年来,基于深度学习的检测器变得越来越复杂,严重依赖于经验。未来的方向是在使用神经结构搜索设计检测模型时减少人为干预 ,譬如如何设计引擎和如何设置锚框 ) 。AutoML可能是未来的目标检测。
领域自适应检测(Detection meets domain adaptation)
任何目标检测器的训练过程本质上都可以看作是一个假设数据独立且同分布(i.i.d)时的似然估计过程。使用非 i.i.d 数据的目标检测,特别是对一些实际应用程序来说,仍然是一个挑战。GAN在领域自适应方面显示出良好的应用前景,对未来的目标检测具有重要的指导意义。
弱监督检测(Weakly supervised detection)
基于深度学习的检测器的训练通常依赖于大量注释良好的图像。注释过程耗时、开销大且效率低。开发弱监督检测技术,只使用图像级标注或部分使用边界框标注对检测器进行训练,对于降低人工成本和提高检测灵活性具有重要意义。
小目标检测(Small object detection)
在大场景中检测小物体一直是一个挑战。该研究方向的一些潜在应用包括利用遥感图像计算野生动物的数量和检测一些重要JS目标的状态。进一步的方向可能包括视觉注意机制的集成和高分辨率轻量级网络的设计。
视频目标检测(Detection in videos)
高清视频中的实时目标检测/跟踪对于视频监控和自主驾驶具有重要意义。传统的目标检测器通常设计为基于图像的检测,而忽略了视频帧之间的相关性。通过探索时空相关性来改进检测是一个重要的研究方向。
含信息融合的目标检测(Detection with information fusion)
RGB-D图像、三维点云、激光雷达等多数据源/多模式的目标检测对自主驾驶和无人机应用具有重要意义。目前存在的问题包括:如何将训练有素的检测器移植到不同的数据模式,如何进行信息融合以提高检测能力等。
目标检测分为两大系列——RCNN系列和YOLO系列,RCNN系列是基于区域检测的代表性算法,YOLO是基于区域提取的代表性算法,另外还有著名的SSD是基于前两个系列的改进。基本原理包括:
(1) 候选区域产生
目标检测技术大都会涉及候选框(bounding boxes)的生成,物体候选框获取当前主要使用图像分割与区域生长技术。区域生长(合并)主要由于检测图像中存在的物体具有局部区域相似性(颜色、纹理等)。目标识别与图像分割技术的发展进一步推动有效提取图像中信息。
(2) 数据表示
经过标记后的样本数据如下所示:
预测输出可以表示如下,其中pc为预测结果的置信概率,(bx,by,bw,bh)是边框坐标,Ci为属于某个类别的概率。通过预测结果、实际结果,构建损失函数。
(3) 效果评估
使用IoU(Intersection over Union,交并比)来判断模型的好坏。交并比是指预测边框、实际边框交集和并集的比率,一般约定0.5为一个可以接收的值。
(4) 非极大值抑制
预测结果中,可能多个预测结果间存在重叠部分,需要保留交并比最大的、去掉非最大的预测结果,这就是非极大值抑制(Non-Maximum Suppression,简写作NMS)。如下图所示,对同一个物体预测结果包含三个概率0.8、0.9、0.95,经过非极大值抑制后,仅保留概率最大的预测结果。
写到这里,一个简单的目标检测过程介绍完毕。接下来我们重点使用ImageAI库实现最简单的目标检测或对象检测案例。这部分原理应用了yegeli老师的博客。
参加及推荐文章,大家可以关注并前往学习。
- 目标检测(Object Detection) - 图像算法AI yegeli老师
- https://arxiv.org/abs/1905.05055v2
- Object Detection in 20 Years: A Survey 综述:目标检测的二十年 - 牛戈老师
- 目标检测最新进展总结与展望 - SIGAI老师
- 论文笔记-2019-Object Detection in 20 Years: A Survey
ImageAI是一个开源Python库,旨在使开发人员能够使用简单的几行代码构建具有包含深度学习和计算机视觉功能的应用程序和系统。 这个AI Commons项目由Moses Olafenwa和John Olafenwa开发和维护。官方源码及文档如下:
ImageAI本着简洁的原则,支持最先进的机器学习算法,用于 图像预测
、自定义图像预测
、物体检测
、视频检测
、视频对象跟踪
和 图像预测训练
。ImageAI目前支持使用在ImageNet-1000数据集上训练的4种不同机器学习算法进行图像预测和训练。ImageAI还支持使用在COCO数据集上训练的RetinaNet
、YOLOv3
和 TinyYOLOv3
进行对象检测、视频检测和对象跟踪。 最终,ImageAI将为计算机视觉提供更广泛和更专业化的支持,包括但不限于特殊环境和特殊领域的图像识别。
新添加功能:
ImageAI核心功能如下:
1.图像检测
ImageAI提供 4 种不同的算法和模型类型来执行图像预测,并在ImageNet-1000数据集上进行训练。为图像预测提供的4 种算法包括:
2.对象检测
ImageAI提供了非常方便和强大的方法来对图像进行对象检测并从图像中提取每个对象。对象检测类提供对三种模型的支持,并提供针对最先进性能或实时处理进行调整的选项。
person : 91.946941614151
--------------------------------
person : 73.61021637916565
--------------------------------
laptop : 90.24320840835571
--------------------------------
laptop : 73.6881673336029
--------------------------------
laptop : 95.16398310661316
--------------------------------
person : 87.10319399833679
--------------------------------
3.视频对象检测和跟踪
ImageAI提供了非常方便和强大的方法来执行视频中的对象检测和跟踪特定对象。提供的视频对象检测类仅支持当前最先进的RetinaNet,但可以选择调整最先进的性能或实时处理。下图展示了对人、自行车和摩托车的视频快照检测效果。
下面是ImageAI返回到“per_second”函数中的视频分析的可视化。
4.自定义模型训练
ImageAI为您提供了用于训练新模型的类和方法,该模型可用于对您自己的自定义对象进行预测。您可以在5行代码中使用算法训练您的自定义模型 。
下图展示了来自IdenProf数据集的样本,用于训练预测专业人士的模型。
自定义图像预测:来自在 IdenProf 上训练的样本模型的预测,用于预测专业人士。
mechanic : 76.82620286941528
chef : 10.106072574853897
waiter : 4.036874696612358
police : 2.6663416996598244
pilot : 2.239348366856575
ImageAI提供了一些类和方法,供您使用通过ImageAI模型训练类训练的自己的模型来运行图像预测您自己的自定义对象。您可以使用SqueezeNet、ResNet50、InceptionV3和DenseNet训练的自定义模型以及包含自定义对象名称映射的JSON文件。
5.自定义检测模型训练
ImageAI提供类和方法供您在自定义数据集上训练新的YOLOv3对象检测模型。这意味着您可以通过提供图像、注释和使用 ImageAI 进行训练来训练模型以检测任何感兴趣的对象。
下图展示了自定义YOLOv3模型的检测结果,该模型经过训练以检测 Hololens 耳机。
hololens : 39.69653248786926 : [611, 74, 751, 154]
hololens : 87.6643180847168 : [23, 46, 90, 79]
hololens : 89.25175070762634 : [191, 66, 243, 95]
hololens : 64.49641585350037 : [437, 81, 514, 133]
hololens : 91.78624749183655 : [380, 113, 423, 138]
ImageAI现在提供类和方法,供您使用通过DetectionModelTraining类训练的自己的模型检测和识别图像中的自定义对象。您可以使用自定义训练的YOLOv3模式和训练期间生成的detection_config.json文件。
6.自定义视频对象检测和分析
来自自定义 YOLOv3 模型的视频检测结果,训练用于检测视频中的 Hololens 耳机。
安装过程比较简单,直接调用pip工具即可。
(base) C:\Users\xiuzhang>activate tensorflow
(tensorflow) C:\Users\xiuzhang>cd Downloads
(tensorflow) C:\Users\xiuzhang\Downloads>pip install imageai-2.0.2-py3-none-any.whl
Processing c:\users\xiuzhang\downloads\imageai-2.0.2-py3-none-any.whl
Installing collected packages: imageai
Successfully installed imageai-2.0.2
本地安装下载链接如下:
依赖扩展包:
对象检测是计算机视觉领域中的一种技术,它处理识别和跟踪图像和视频中存在的对象。目标检测有多种应用,如人脸检测、车辆检测、行人计数、自动驾驶汽车、安全系统等。ImageAI提供了非常方便和强大的方法来对图像进行对象检测并从图像中提取每个对象。ImageAI 包含几乎所有最先进的深度学习算法的Python 实现,如RetinaNet、YOLOv3和 TinyYOLOv3。
ImageAI使用对象检测、视频检测和对象跟踪 API,无需访问网络即可调用。ImageAI使用预先训练的模型并且可以轻松定制。ImageAI中的 ObjectDetectionImageAI 库的类包含使用预训练模型对任何图像或图像集执行对象检测的函数。借助 ImageAI,可以检测和识别 80 种不同的常见日常物品。
下面开始实现一个简单的对象检测案例。
第一步,成功安装ImageAI后,下载包含将用于对象检测的分类模型的TinyYOLOv3模型文件。
第二步,创建如下图所示的文件夹。
│ test_detector.py
│
├─input
│ test_car.png
│
├─models
│ yolo-tiny.h5
│
└─output
第三步,创建test_detector.py文件,从ImageAI库导入ObjectDetection类。
from imageai.Detection import ObjectDetection
第四步,实例化ObjectDetection并指定相关的路径文件。
model_path = "./models/yolo-tiny.h5"
input_path = "./input/test_car-02.png"
output_path = "./output/pre_car-02.png"
detector = ObjectDetection()
第五步,利用实例化ObjectDetection类,调用其中的函数实现不同的功能。该类包含以下功能调用预先训练模式:
第六步,使用预训练TinyYOLOv3模型,利用setModelTypeAsTinyYOLOv3()函数加载模型。
detector.setModelTypeAsTinyYOLOv3()
第七步,设置模型路径并实现图像对象检测。这里需要detectObjectsFromImage使用detector创建的对象,并输出结果。
detector.setModelPath(model_path)
detector.loadModel()
detection = detector.detectObjectsFromImage(input_image=input_path,
output_image_path=output_path)
完整代码如下图所示:
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 26 14:26:27 2021
@author: xiuzhang
"""
from imageai.Detection import ObjectDetection
#实例化
detector = ObjectDetection()
#路径定义
model_path = "./models/yolo-tiny.h5"
input_path = "./input/test_car.png"
output_path = "./output/pre_car.png"
#预训练模式
detector.setModelTypeAsTinyYOLOv3()
#设置预训练模型路径
detector.setModelPath(model_path)
#加载模型
detector.loadModel()
#创建对象
detection = detector.detectObjectsFromImage(input_image=input_path, output_image_path=output_path)
#检测结果
for eachItem in detection:
print(eachItem["name"] , " : ", eachItem["percentage_probability"])
输入图像如下图所示,位于input文件夹中。
输出结果如下图所示,可以看到不同列类别的预测概率及对应轮廓。
同时,还可以预测其他的车辆及行人等。
个人认为Python提供了良好的扩展包供大家学习,如果您对CV感兴趣,可以先阅读作者前面的图像处理系列文章。后面再进行目标检测的实验,而目标检测可以尝试先了解最简单调包的实现,后面再一步步告诉大家如果构建YOLO或SSD模型。
此外,Python开源库提供了强大的源代码,大家可以去学习及修改对应的功能。比如:
同时,该扩展包可以检测多种类型的对象,从上图源代码中可以看到,也可以看到绘制方块及Text的过程。
后续作者会想办法尝试自定义数据集进行目标识别,比如农产品、飞行器、自然灾害等。
from imageai.Classification.Custom import CustomImageClassification
import os
execution_path = os.getcwd()
prediction = CustomImageClassification()
prediction.setModelTypeAsResNet50()
prediction.setModelPath(os.path.join(execution_path, "idenprof_resnet_ex-056_acc-0.993062.h5"))
prediction.setJsonPath(os.path.join(execution_path, "idenprof.json"))
prediction.loadModel(num_objects=10)
predictions, probabilities = prediction.classifyImage(os.path.join(execution_path, "4.jpg"), result_count=5)
for eachPrediction, eachProbability in zip(predictions, probabilities):
print(eachPrediction + " : " + eachProbability)
最后推荐刘兄的系列文章,也真心不错。
写到这里,第一篇目标检测入门文章就介绍完毕,希望您喜欢。
源代码下载地址,记得帮忙点star和关注喔。
大学之道在明明德,
在亲民,在止于至善。
这周又回答了很多博友的问题,有大一学生的困惑,有论文的咨询,也有老乡和考博的疑问,还有无数博友奋斗路上的相互勉励。虽然自己早已忙成狗,但总忍不住去解答别人的问题。最后那一句感谢和祝福,永远是我最大的满足。虽然会花费我一些时间,但也挺好的,无所谓了,跟着心走。不负遇见,感恩同行。莫愁前路无知己,继续加油。晚安娜和珞。
(By:Eastmount 2021-08-03 晚上10点 http://blog.csdn.net/eastmount/ )