# 认识物体识别
---

##  A.	图像识别与计算机视觉
#####  1.	图像识别
在学习物体识别前，我们先来认识下图像识别。<br>
图像识别，简单地来说，就是一个将图像与特定的词语对应起来的过程。从技术上来看，是利用电脑对图像进行处理、分析和理解，以识别各种不同模式的目标和对象的过程。图像识别的发展经历了三个阶段：文字识别、数字图像处理与识别、物体识别。<br>
文字识别的研究是从 1950年开始的，一般是识别字母、数字和符号，从印刷文字识别到手写文字识别，应用非常广泛。<br>
<img src="/media/ai/AI_n1.png" width="300"/><img src="/media/ai/AI_n2.png" width="350"/><br>
数字图像处理和识别的研究开始于1965年。数字图像与模拟图像相比具有存储、传输方便可压缩、传输过程中不易失真、处理方便等巨大优势，这些都为图像识别技术的发展提供了强大的动力。
<br><img src="/media/ai/AI_n3.png" width="350"/><br>
物体识别主要指对三维世界的物体及环境的感知和认识，属于高级的计算机视觉范畴。它是以数字图像处理与识别为基础的结合人工智能、系统学等学科的研究方向，其研究成果被广泛应用在各种工业及机器人中。
<br><img src="/media/ai/AI_n4.png" width="350"/><br>
了解了这些知识，我们再来看下面这四幅图，第一张图片是手写数字，可以看到电脑将它正确地识别为了425，后三张图片则分别分类为猫、人和车。
<br><img src="/media/ai/AI_n5.png" width="350"/><br>
这就是文字识别和物体识别的一些应用，电脑可通过深度学习算法，对输入的图像进行识别，并给出每幅图片的识别结果。<br>
在人工智能领域，识别问题又可以归类为分类问题，所以物体识别，也可以称之为物体分类。<br>


#####  2.	计算机视觉
我们前面提到了，图像识别就是电脑获取，处理和分析图像数据的过程，这个过程其实也就是计算机视觉的实现过程。简而言之，计算机视觉使得电脑能够“看”事物——甚至包括人类无法看到的事物。然而，要想让电脑做到人类无法做到的事情，我们必须首先使电脑能够做到人类可以做的事情：看到并标记物体和生物。这是图像识别的主要功能。<br>
我们先来看下下面这四幅猫的图片，我们可以很轻松地分辨出这四张图片都是猫，即使它们外形长相完全不同，且体态各异，即使它只露出了一截尾巴，但我们仍然可以分辨的出来。<br>
但这对电脑来说却十分困难，因为电脑并没有像我们人类大脑这样复杂的系统。
<br><img src="/media/ai/AI_n6.png" width="350"/><br>
那么，到底电脑是如何识别图片的呢？我们来看下一节内容。<br>

---
##  B.	神经网路与深度学习
电脑想要正确分类图片，就需要像我们人类一样去学习，知道图片中大量的资讯。目前，最有可能让电脑实现“看”的能力的技术叫做深度学习（Deep Learning，简称DL），它是一种让电脑从图片中学习的方法。学习的过程称为训练，识别的过程称为推理（测试）。
<br><img src="/media/ai/AI_n7.png" width="350"/><br>
电脑要识别图片，前提便是需要大量的图片数据作为输入，传入电脑以供其学习。<br>
我们以识别猫为例，前期需要先准备大量的各种品类的猫，并且打上标签，告诉电脑：这些是猫，也就是这些图片的分类，然后电脑将这些数据输入网路，执行训练，通过不断地迭代进行学习，达到正确认识这些猫的目的。<br>
然后，我们输入电脑一张新的猫的图片，进行测试，电脑执行测试演算法，便可给出输入图片的正确分类。<br>
这个过程就是电脑“看”事物（学习），并给出答案（识别）的过程。<br>
###### 我们再来看一下学术的解释：
深度学习就是一种机器学习框架，通过模仿人类的神经元系统，为电脑提供自主学习能力。因此，电脑可以自动识别与发掘图像数据的特征，准确识别图片中的内容，而无需根据指令或手动编码来实现（但它需要大量的数据），并大大提高了计算精度及识别准确率。<br>
而模仿人类神经元系统的方法，在人工智能领域被称为神经网路（Neural Networks）。<br>
下面，我们以图像识别的入门级应用：MNIST手写数字识别为例，来认识神经网路与深度学习的原理。其中，MNIST是一个手写数字的图片数据集。<br>

---
## C.	MNIST手写数字识别
手写识别是常见的图像识别任务。电脑通过手写体图片来识别出图片中的字，与印刷字体不同的是，不同人的手写体风格迥异，大小不一， 造成了电脑对手写识别任务的一些困难。 <br>
在研究过程中，数字手写体识别由于其有限的类别（0~9共10个数字）成为了相对简单的手写识别任务。所以，我们从简单的手写数字识别入手，来认识实现图像识别的演算法。<br>
##### 1.	人类学习和认识数字的过程
前面已经提到，电脑需要像人一样思考学习，才能识别出图像，我们不妨反推一下，想一想我们小时候是怎样学习数字的，大家总结回想一下，我们学习数字的思维过程。为什么我们可以看到各式各样形状的数字，依旧可以知道它们分别是多少呢？
<br><img src="/media/ai/AI_p1.png" width="350"/><br>
这个过程也就是电脑要模仿的，我们把这个学习步骤写出来。
<br><img src="/media/ai/AI_p2.png" width="350"/><br>
这个就是人类学习和认知的过程，也就是机器要模仿的，现在我们将人的学习方式类比到电脑中，就会知道电脑学习并识别数字的过程了。
##### 2.	电脑学习并认识数字的过程
###### 1)	图像在电脑中的样子
我们向电脑输入正确的带有标签的图像数据，电脑看到的并不是像我们人类看到的那样，如下图左边的图片，而是下图右边数字矩阵的样子。电脑中处理图像，处理的是图像中每一个像素（像素是电脑萤幕上所能显示的最小单位，是用来表示图像的单位）。
<br><img src="/media/ai/AI_p3.png" width="350"/><br>
上一节我们提到了，深度学习需要大量的数据作为输入，在手写数字识别系统中，数据来自于MNIST数据集，它包含60000个训练集和10000测试数据集。分为图片和标签，图片是28*28的像素矩阵，标签为0~9共10个数字。
###### 2)	模型训练——神经网路
有了数据集，下一步，便是将数据输入到深度学习网路中，也就是神经网路中（这里采用的是LeNet-5卷积神经网路模型，卷积神经网路是深度学习神经网路中最常见的一种），进行自动的特征提取及学习，这个过程就是前面提到过的训练过程。<br>
我们知道，人类大脑的神经网路是由神经元和突触组成，它们协同工作，完成对外界资讯的处理与传递。
<br><img src="/media/ai/AI_p4.png" width="350"/><img src="/media/ai/AI_p5.png" width="350"/><br>
那么，人脑的神经网路对比到深度学习中，就是如下图所示的网路。
<br><img src="/media/ai/AI_p6.png" width="350"/><br>
大量的手写数字图像就是输入数据，作为第一层：输入层（一般情况下，输入层不在网路结构中体现，而在后面训练开始时给出），因为每张图像的像素是28x28，所以每张图像一共有784个像素，电脑中的索引一般从0开始，所以输入x即为x0-x783。 <br>
中间部分称为隐藏层，在LeNet-5网路中，主要采用的是：卷积层Convolutional Layer（启动层为ReLu Layer）、池化层Pooling Layer以及全连接层Fully Connected Layer。<br>
全连接层中加入启动函数：Softmax，这是一个回归模型，用于分类过程，可解决多分类问题。这里的手写数字识别就是一个多分类问题，0-9共10类，所以最后的输出层y的结果为y0-y9。
<br><img src="/media/ai/AI_p7.png" width="350"/><br>
并且Softmax也是一个概率函数，它可以给出输入图像识别为不同类别的概率，以此来让使用者判断输入图像中的数字更像哪一个识别结果。<br>
这部分就是神经网路的网路结构，是深度学习演算法实现图像处理及学习的根本。
###### 3)	人类学习过程和电脑学习过程的对比
前面我们给出了人类学习和认识数字的过程，也就是下图左边的部分，通过上一节的学习，我们知道了电脑学习并认识数字的过程，那么总结起来，就是下图右边所示的步骤。
<br><img src="/media/ai/AI_p8.png" width="350"/><br>
###### 4)	手写数字识别的实现演示
我们知道了手写数字识别的原理，那么，现在就来看看实际电脑中是如何实现图像识别的吧。
打开网址：https://ai-blockly.cocorobo.hk/ ，进入AI blockly页面。<br>
进入后，首先选择Examples选项。
<br><img src="/media/ai/AI_p9.png" width="350"/><br>
然后，继续选择Tensor Flow选项，然后选择Digit Recognition选项，并选择OK。
<br><img src="/media/ai/AI_p10.png" width="350"/><img src="/media/ai/AI_p11.png" width="350"/><br>
然后，就会出现如下图所示的积木程式块。
<br><img src="/media/ai/AI_p12.png" width="350"/><br>
继续点击右下角区域中的RUN按钮，即可开始训练。
<br><img src="/media/ai/AI_p13.png" width="350"/><br>
训练的迭代过程中，会产生如下图所示的函数曲线图及网路结构资讯（Model Architecture），可通过观察曲线图的变化，来判断训练执行的状态及模型的训练效果。
<br><img src="/media/ai/AI_p14.png" width="350"/><br>
如上图所示，是演示的最终效果，左边是曲线图，第一副图是训练集（loss）和验证集（val_loss）的loss变化曲线，loss是损失函数，即模型预测出的结果与标签标注的真实值的差值。这个差值是随著训练轮数Epoch的增加而逐渐减小的。<br>
第二幅图是训练集（acc）和验证集（val_acc）的准确率变化曲线，准确率为识别正确的图像个数除以总的图像数的比值，该值随著Epoch的增加而逐渐增大。<br>
右侧为推理测试区，在画布中写出你要测试的数字，点击Detect，即可得到最终的识别结果。<br>
其结果将打印显示在右上方区域的Console中。
<br><img src="/media/ai/AI_p15.png" width="350"/><img src="/media/ai/AI_p16.png" width="350"/><br>
手写数字识别的整个实现过程到这里就结束了。<br>
接下来，我们来学习今天最重要的部分——物体识别。

---
## D.	物体识别与YOLO演算法
物体识别（Object Recognition）是计算机视觉中的一个应用，目的是让电脑去分析一张图片或者一段影片中的物体，并标注出其中物体所属的类别。
<br><img src="/media/ai/AI_q1.png" width="350"/><br>
###### YOLO演算法介绍：
<br><img src="/media/ai/AI_q2.png" width="350"/><br>
YOLO是目前应用非常广泛的一种物体识别演算法。YOLO的意思是You only look once，也就是你只看一眼，就能认出这是什么物体，体现YOLO演算法识别的精度和速度。<br>
YOLO是基于Pascal VOC2012数据集的目标检测系统。它能够检测到20种Pascal的目标类别，包括：<br>
- 人
- 鸟，猫，牛，狗，马，羊
- 飞机，自行车，船，汽车，摩托车，火车
- 瓶子，椅子，桌子，盆栽植物，沙发，电视或者显示器<br>
YOLO演算法目前最新的已经迭代到了v4版本，各个版本的应用场景都是相同的，区别只在于识别精度及速度。这里，视频中展示的是YOLOv3的应用及识别结果，但这并不影响学习，我们这里主要讲的是入门级的YOLOv1的原理。<br>
YOLO演算法的识别过程分为两个部分，这也基本是所有视觉领域内的深度学习演算法的实现过程。<br>
1.  训练图像数据，迭代过程优化参数，获得最终模型；
2.  输入新的图像数据，调用模型，实现推理（inference）过程，也称为测试过程。
我们先来看下第一步的原理：<br>
训练就需要有网路，YOLO的网路结构如下图所示，整个检测网路包括24个卷积层和2个全连接层。其中，卷积层用来提取图像特征，全连接层用来预测图像位置和类别概率值。
<br><img src="/media/ai/AI_q3.png" width="350"/><br>
第二步：推理过程：
<br><img src="/media/ai/AI_q4.png" width="350"/><br>
加载网路模型后，其推理的计算流程如图所示，我们可以将最终识别结果之前的步骤都看做一个函数计算，通过这个计算过程，就可以得到最后的物体识别结果了。<br>
那么，YOLO具体是如何实现物体识别的呢？我们来深入地学习一下它的内部原理。
<br><img src="/media/ai/AI_q5.png" width="350"/><br>
如上图所示，YOLO演算法将输入图片划分成7x7=49个网格（即上图中左边第一副图，S=7），如果一个物体的中心落在某网格(cell)内，则相应网格负责检测该物体。<br>
每个网格预测两个边界框（Bounding boxes），一共预测49x2=98个边界框（上图中位于上面的那副图）。可以近似理解为在输入图片上粗略的选取98个候选区，这98个候选区覆盖了图片的整个区域，进而用回归预测这98个候选框对应的边界框。<br>
除了给出边界框，也就是图像的位置资讯外，还会给出对应的置信度（confidence）和分类结果（categories）。其中，置信度代表了所预测的 box 中含有 object 的置信度（概率）和这个 box 预测目标位置的准确度这两重资讯。<br>
最后，网路就给出了图像的最终识别结果，如下图所示。
<br><img src="/media/ai/AI_q6.png" width="350"/><br>

---
## E.	AI模型积木说明
在学习了解了深度学习与物体识别的原理之后，我们开始积木程式块的学习，将理论与实践相结合，才能更好地学习并认识物体识别。
<table style="margin-top:20px;">
	<tr>
		<td width="50%">积木</td>
		<td width="20%">指令</td>
    <td width="30%">说明</td>
	</tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r1.png" width="300"/></td>
    <td width="20%">载入模型</td>
    <td width="30%">载入人工智能模型，可以从选单中选择常用识别模型<img src="/media/ai/AI_r2.png" width="300"/></td>
  </tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r3.png" width="300"/></td>
    <td width="20%">获取识别结果</td>
    <td width="30%">获取当前结果，可选择数字识别的结果或者识别为某个数字的置信度<img src="/media/ai/AI_r4.png" width="300"/></td>
  </tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r5.png" width="300"/></td>
    <td width="20%">物体识别</td>
    <td width="30%">获取物体识别真假值，如果识别到物体会返回「真」值，否则返回「假」值</td>
  </tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r6.png" width="300"/></td>
    <td width="20%">物体识别结果的参数</td>
    <td width="30%">获取识别到的每个物体的各项参数，包括：<img src="/media/ai/AI_r7.png" width="300"/></td>
  </tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r8.png" width="300"/></td>
    <td width="20%">人脸识别</td>
    <td width="30%">获取人脸识别真假值，如果识别到人脸会返回「真」值，否则返回「假」值</td>
  </tr>
  <tr>
    <td width="50%"><img src="/media/ai/AI_r9.png" width="300"/></td>
    <td width="20%">人脸识别结果的参数</td>
    <td width="30%">获取识别到的每个人脸的各项参数，包括：<img src="/media/ai/AI_r10.png" width="300"/></td>
  </tr>
<tr>
    <td width="50%"><img src="/media/ai/AI_r11.png" width="300"/></td>
    <td width="20%">加载客制化模型</td>
    <td width="30%">从指定路径加载用户预训练好的客制化模型：/sd/user/mymodel.kmodel
并根据要识别的物体种类来设定客制化物体的类别名称：Object Name
</td>
  </tr>
<tr>
    <td width="50%"><img src="/media/ai/AI_r12.png" width="300"/></td>
    <td width="20%">客制化的物体识别</td>
    <td width="30%">获取客制化物体识别真假值，如果识别到客制化物体会返回「真」值，否则返回「假」值</td>
  </tr>
<tr>
    <td width="50%"><img src="/media/ai/AI_r13.png" width="300"/></td>
    <td width="20%">客制化物体识别结果的参数</td>
    <td width="30%">获取识别到的每个客制化物体的各项参数，包括：<img src="/media/ai/AI_r14.png" width="300"/></td>
  </tr>
</table>

---
## F.	基础编程
##### 活动一：物体检测并显示识别结果在「串口互动窗」
<table style="margin-top:20px;">
<tr>
  <td colspan=2>在积木指令区点按以下指令，并依次放在积木编程区：<br>
1.	AI模组｜图像处理：【相机初始化】<br>
2.	循环：【一直重复执行】<br>
3.	AI模组｜AI模型：【加载预设模型】
选择：模型：「常见物体检测模型」  图像：「img_objectrecognition」<br>
4.	变数：【设定变数】img_objectrecognition<br>
5.	AI模组｜相机：【获取相机捕捉的图像】<br>
6.	逻辑：【逻辑判断】<br>
7.	AI模组｜模型：【识别到了任意常见物体】<br>
8.	序列埠通讯｜打印：【打印文字】
识别到物体则显示「Object Detected」，否则「Nothing Detected」<br>
</td>
</tr>
<tr >
<td><img src="/media/ai/AI_s1.png" width="300"/></td>
<td>注意：步骤4必须使用内建变数「img_objectrecognition」，所以首先要在步骤3使用「加载预设模型」指令，然后才进行步骤4及步骤5。</td>
</tr>
<tr >
<td><img src="/media/ai/AI_s2.png" width="300"/></td>
<td><img src="/media/ai/AI_s3.png" width="300"/></td>
</tr>
<tr >
<td>测试结果：在「代码区」点按「串口互动窗」，将模组向四周扫描，并观察显示的结果如下，当检测到有物体时会显示「Object Found」，否则会显示「Nothing」</td>
<td><img src="/media/ai/AI_s4.png" width="300"/></td>
</tr>
</table>

##### 活动二：物体检测并显示物体名称
<table style="margin-top:20px;">
<tr>
  <td colspan=2>重复活动一的程式，在步骤8「显示文字」指令修改如下：<br>
1.	循环：【For循环】<br>
2.	AI模组｜模型：【识别到了任意常见物体】<br>
3.	序列埠通讯：【打印】<br>
4.	AI模组｜模型：【获取物体参数】选择「物体名称」<br>
</td>
</tr>
<tr >
<td colspan=2><img src="/media/ai/AI_s5.png" width="300"/></td>
</tr>
<tr >
<td><img src="/media/ai/AI_s6.png" width="300"/></td>
<td><img src="/media/ai/AI_s7.png" width="300"/></td>
</tr>
<tr >
<td>测试结果：点按「串口互动窗」，将模组向四周扫描，并观察显示的结果如下，当检测到有物体时会显示「物体名称」，否则会显示「Nothing」</td>
<td><img src="/media/ai/AI_s8.png" width="300"/></td>
</tr>
</table>
思考问题：活动二的程式运用「物体检测模型」，判断摄影镜头拍摄到的图像，并输出物体名称，此名称是如何决定？「物体检测模型」是否能够判断所有物体，输出正确名称？
<br><img src="/media/ai/AI_s9.png" width="300"/>

---
## G.	专题学习
硬体设备：AI推理模组、萤幕模组、摄像头模组<br>
任务目标：利用摄影镜头将影像显示在萤幕模组上，载入物体识别模型，将识别到的物体在萤幕上标示出来。<br>
基本流程/步骤：
<br><img src="/media/ai/AI_t1.png" width="350"/><br>

###### 第一步：模组初始化
<table style="margin-top:20px;">
<tr >
<td>在积木指令区点按以下指令，并依次放在积木编程区：<br>
1.	AI模组｜萤幕：【初始化】<br>
2.	AI模组｜相机：【初始化】<br>
3.	循环：【重复执行】<br>
</td>
<td><img src="/media/ai/AI_t2.png" width="300"/></td>
</tr>
</table>

###### 第二步：获取影像，载入物体识别模型，进行物体识别
<table style="margin-top:20px;">
<tr>
  <td colspan=2>在【重复执行】积木指令内，放置下列积木指令：<br>
4.	AI模组｜AI模型：【加载模型】
(模型：常见物体识别模型 图像：img_objectrecognition)<br>
5.	变数：【赋值】(名称：img_objectrecognition)<br>
6.	AI模组｜相机：【获取影像】<br>
7.	变数：【建立变数】(名称：img_display)<br>
8.	AI模组｜图像处理：【调整画布尺寸】<br>
9.	AI模组｜图像处理：【图像转换】<br>
</td>
</tr>
<tr >
<td colspan=2><img src="/media/ai/AI_t3.png" width="300"/></td>
</tr>
<tr >
<td><img src="/media/ai/AI_t4.png" width="300"/></td>
<td><img src="/media/ai/AI_t5.png" width="300"/></td>
</tr>
</table>

###### 第三步：获取影像，载入物体识别模型，进行物体识别
<table style="margin-top:20px;">
<tr>
  <td colspan=2>在【图像转换】积木指令之后，放置下列积木指令：<br>
10.	逻辑：【逻辑判断】<br>
11.	AI模组｜AI模型：【物体识别】<br>
12.	循环：【For循环】<br>
13.	AI模组｜AI模型：【物体识别】<br>
14.	AI模组｜图像处理：【萤幕文字】，并修改座标的X值及Y值，使「物体名称」显示在萤幕左上角的适宜位置<br>
15.	文字：【建立字串使用】<br>
16.	AI模组｜模型：【获取物体参数】选择「物体名称」<br>
17.	AI模组｜图像处理：【萤幕文字】并输入「Nothing Detected.」，并修改座标的X值及Y值<br>

</td>
</tr>
<tr >
<td colspan=2><img src="/media/ai/AI_t6.png" width="300"/></td>
</tr>
<tr >
<td colspan=2><img src="/media/ai/AI_t7.png" width="300"/></td>
</tr>
</table>

###### 第四步：在萤幕上显示影像
<table style="margin-top:20px;">
<tr>
  <td colspan=2>在步骤10【逻辑判断】积木指令之后，放置下列积木指令：<br>
18.	AI模组｜萤幕：【设定起始点坐标】、【显示画布】(名称：img_display  起始座标X：8   Y值：36)
</td>
</tr>
<tr >
<td colspan=2><img src="/media/ai/AI_t8.png" width="300"/></td>
</tr>
</table>

###### 完整程式：
<table style="margin-top:20px;">
<tr>
 <td ><img src="/media/ai/AI_t9.png" width="300"/>
</td>
</tr>
<tr >
<td><img src="/media/ai/AI_t10.png" width="200"/></td>
</tr>
</table>

---
## H.	专题学习进阶
将上面专题中的第三步改为以下内容：在萤幕中显示识别到的物体位置并以检测框的形式标注出来。
<table style="margin-top:20px;">
<tr>
  <td >在【图像转换】积木指令之后，放置下列积木指令：<br>
10. 逻辑：【逻辑判断】<br>
11. AI模组｜AI模型：【物体识别】<br>
12. 循环：【For循环】<br>
13. AI模组｜AI模型：【物体识别】<br>
14. AI模组｜萤幕：【绘制矩形】（画布：img_display  矩形：空心  颜色：白色  厚度：2）
起始座标：X值，Y值   尺寸：宽度，高度<br>
a.	数学运算：【int】转换整数<br>
b.	数学运算：【四则运算】，物体识别数值 / 1.42<br>
c.	AI模组｜AI模型：【物体识别属性】<br>
18. AI模组｜萤幕：【绘制实心圆形】放置在屏幕中间<br>
</td>
</tr>
<tr >
<td><img src="/media/ai/AI_u1.png" width="200"/></td>
</tr>
</table>

###### 第四步：在萤幕上显示影像

<table style="margin-top:20px;">
<tr>
  <td >在步骤10【逻辑判断】积木指令之后，放置下列积木指令：<br>
19. AI模组｜萤幕：【显示画布】(名称：img_display  起始座标X：8   Y值：36)<br>
</td>
</tr>
<tr >
<td> <img src="/media/ai/AI_u2.png" width="200"/></td>
</tr>
<tr >
<td> 完整Python代码：<img src="/media/ai/AI_u3.png" width="200"/></td>
</tr>
<tr >
<td> 完整程式：<img src="/media/ai/AI_u4.png" width="200"/></td>
</tr>
<tr >
<td> 运行结果：<img src="/media/ai/AI_u5.png" width="200"/><img src="/media/ai/AI_u6.png" width="200"/></td>
</tr>
</table>
