1. 引言

最近在微软Learn平台学习Azure认知服务相关的内容,看到了一个有关“使用自定义视觉对濒危鸟类进行分类”的专题,该专题的主要内容就是使用 Azure Custom Vision创建一个模型来标识鸟类物种。学习完以后,觉得内容挺有意思,英语不好的同志不要觉得有压力,这个专题学习模块的所有内容已经汉化。但是有个问题就是,学习完以后,你会发现,该项目是在PC上使用现有的照片来进行识别,这样的操作并不是十分方便。目前,随着物联网设备的普及,使用树莓派作为IoT终端、结合摄像头捕捉实时图像,再与Azure Custom Vision进行交互,获得识别结果,这样的方式或许部署起来更加轻巧方便。好的,下面我们就一起来把这个想法实现出来,我整体测算了一下,应该能够在1个小时内搞定。另外,本文使用微软Learn平台的沙盒作为资源,所有的Azure资源使用都是免费的。

2. 硬件准备

树莓派主机、电源、显示器(非必须,可以通过VNC远程查看)、USB摄像头或树莓派专用摄像头。我这里用的是树莓派4(2G)和Microsoft LifeCam HD3000摄像头。

3. 软件资源

需要一个微软账号,可以通过outlook注册一个,在资源搭建过程中使用的Azure资源是以沙盒的形式免费提供的,这个沙盒的使用有时间限制,一般是4个小时的有效期,每个账户每天可以申请10个沙盒。具体的过程可以参考上面提供的这个文档中的第三步:构建模型

4. 创建自定义视觉 API 资源

我们将在 Azure 认知服务自定义视觉中创建 API 资源。

1. 在 Azure 门户中,选择“Create a resource”。

2. 搜索“custom vision”。 在自定义视觉的搜索结果中,选择“create”。

3. 在“基本”选项卡上,输入或选择所需的值:

  • 选择 Azure 订阅:默认就是Concierge Subscription,
  • Option里面记得选择Both,就是Training和Prediction都要。
  • 创建资源组:默认可选的就是learn-***(后面是一串ID号),
  • 名字:自己想一个就行。
  • 位置:选就近的,没有China,就选了Japan East。
  • Pricing Tier:选F0就够了。

图1:创建Custom Vision项目

5. 下载鸟类的图片数据集

数据是创建机器学习模型所需的首要内容。 我们可以使用来自康奈尔实验室的 NABirds 数据集的子集来训练模型。下载包含数据集的 zip 文件,该资源大家可以去Github上下载:资源链接。下载以后,打开可以发现里面有16中鸟类的图片,每一种大概120图片左右。

图2:数据集资源

6. 上传数据集

目前,我们有两种方法来上传图片数据,一种是使用Custom Vision的门户,还有一种是使用Custom Vision的SDK。相对来说,使用门户上传更直观一些。我们这里就使用门户的方式上传。具体步骤如下:

在自定义视觉门户中创建项目:转到 https://www.customvision.ai/projects 并登录。如果在同一浏览器中,使用之前登陆Azure门户的账号就好。

选择“新建项目”。在“创建新项目”中:

  • 在“名称”中,输入所选的项目名称。
  • 在“描述”中,输入模型的短描述。
  • 在“资源组”中,选择在 Azure 门户中创建的资源组。
  • 在“项目类型”中,选择“分类”。
  • 在“分类类型”中,选择“多类(每图像一个标记)”。
  • 在“域”中,选择“常规”。

选择“创建项目”。如下图3所示。

图3:创建Custom Vision项目

在自定义视觉项目中,选择“添加图像”,在“打开”中,转到从数据集 zip 文件中提取图像文件的 birds-photo 文件夹。打开鸟类物种文件夹。选择 Ctrl + A 来选择物种文件夹中的所有图像,然后选择“打开”。

图4:上传图片数据集

在“图像上传”中,在“我的标记”中添加说明以表明照片中显示的鸟类物种,如鸽子。

图5:标记数据集

选择“上传文件”。继续上传其他鸟类的图片,直到完成上传。注意,至少要上传两种以上的Tag的图片,不然后面就没法训练。

7. 训练模型

我们已在自定义视觉中创建了数据集。现在,可以对模型进行训练了。可以使用 SDK 来训练模型,但我们将使用自定义视觉门户来训练模型。在自定义视觉门户中,选择“鸟类分类”项目。在顶部菜单栏中,选择“训练”。在“选择训练类型”中,选择“快速训练”,然后选择“训练”。

图6:训练数据集

在训练过程中,“迭代”窗格将显示在左侧。 窗格中的“正在训练...” 通知指示正在进行训练。 训练完成时,将显示有关如何为正在训练的迭代执行模型的信息。有关训练迭代的详细信息,可通过称为“精度”、“撤回(Recall)”和“平均精度 (AP)”的指标来显示。为整个模型和每个类(标记)显示这些指标。 如图7所示。

图7:数据集训练结果

接下来,我们将详细了解这些指标。自定义视觉在测试模型时显示三个指标。 这些指标是可帮助你了解模型执行情况的指示器。 这些指示器不会指示模型的真实性或准确性。指示器只会告诉你模型在你所提供数据上的执行情况。模型在已知数据上的执行情况可以让你了解模型在新数据上的执行情况。为整个模型和每个类提供以下指标:

  • precision :如果模型预测标记,则此指标表示预测正确标记的可能性有多大。
  • recall:对于模型应正确预测的标记,此指标表示模型正确预测的标记的百分比。
  • average precision:通过计算在不同阈值上的精准率和召回率来度量模型性能。

在测试自定义视觉模型时,将在迭代测试结果中看到每个指标的数值。

8. 测试模型

根据自定义视觉提供的指标,我们的模型性能令人满意。 接下来测试模型,看看它处理未见过的数据时性能如何。 我们可以从网上搜索一张鸟类图像。

  1. 在 Web 浏览器中,搜索你训练该模型识别的其中一个鸟类物种的图像。 复制图像的 URL。
  2. 自定义视觉门户中,选择“鸟类分类”项目。
  3. 在顶部菜单栏中,选择“快速测试”。
  4. 在“快速测试”中,将 URL 粘贴到“图像 URL”,然后按 Enter 测试模型的准确性。 预测将显示在窗口中。

自定义视觉分析图像以测试模型的准确性并显示结果,如图8所示。

图8:测试结果

9. 部署模型

在自定义视觉门户的顶部菜单栏中,选择“性能”。选择“发布”。在“发布模型”中,选择“预测资源”,然后选择自定义视觉项目的预测名称。 选择“发布”。如下图9所示。

图9:发布模型

在发布模型后,模型操作在自定义视觉门户中进行更改。选择“预测 URL”选项卡。在“如何使用预测 API”的“如果你有一个图像 URL”下的文本框中,复制并保存该值,然后选择“获取”。

图10:模型URL

在设置页面,我们可以获得后续所需要的Key、EndPiont和Project ID,如下图所示。

图11:项目设置页面

10. 树莓派应用构建

树莓派中,我们要使用到custom vision的python SDK,所以我们要使用pip工具安装以下库:

  1 pip3 install azure-cognitiveservices-vision-customvision
2 pip3 install msrest

由于我们在项目中使用了USB摄像头,以及后续的图片显示,所以需要安装fswebcam和matplotlib,命令如下:

  1 sudo apt-get install python3-matplotlib
2 sudo apt-get install fswebcam

好了,下面我们可以用树莓派自带的Thonny工具新建一个Python文件,将代码拷贝到编辑器中,保存为customvisionclassify.py。

  1 import os
2 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
3 from msrest.authentication import ApiKeyCredentials
4 from PIL import ImageDraw
5 from PIL import Image
6 import matplotlib.pyplot as plt
7
8 # capture the image with USB webcamera
9 a=os.system("fswebcam --no-banner -r 1280x720 capture.jpg")
10 print(a)
11 credentials = ApiKeyCredentials(in_headers={"Prediction-key": "9b7a001f9d3e4cf38a2124f86******"})
12 predictor = CustomVisionPredictionClient("https://birdcustomvisiondemo.cognitiveservices.azure.com/", credentials)
13 projectID = "c597ccfe-7e32-4777-b773-*******"
14 publish_iteration_name="Iteration1"
15 with open("capture.jpg", mode="rb") as captured_image:
16 results = predictor.classify_image(projectID, publish_iteration_name, captured_image)
17 # Display the results.
18 for prediction in results.predictions:
19 print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
20

这里,使用你自己创建的Key、projectID和Iteration来替换我上面的,就可以了。

上面这总共加起来就是20行代码,先用USB摄像头捕捉图像,然后调用CustomVisionPredictionClient进行图片识别,对其中的鸟类进行分类,最后将得到的结果打印在调试窗口。点击运行,如果你的摄像头捕捉到了鸟类,例如鸽子什么的,就可以得到结果了。

图12:分类结果页面

当然,有的同学要问了,如果我想识别鸟类在图片中的什么位置,然后给他标记出来呢?这样的话,光是分类就不够了,我们需要新建一个Object Detection类的项目了,具体方式就是在新建项目的时候,选择Object Detection,而不是Classification。之后的步骤也差不多,就是上传图片,加Tag,然后训练,训练完成以后,部署模型。唯一的区别就在于,在Object Detection项目中,我们需要对上传的图片进行标注,就是要将对象在图片中出现的位置进行标注,如下图13所示。

图13:Tag标记页面

另外,在树莓派上的代码也有所不同,因为之前是分类,现在我们是要做检测,具体代码如下。

  1 import os
2 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
3 from msrest.authentication import ApiKeyCredentials
4 from PIL import ImageDraw
5 from PIL import Image
6 import matplotlib.pyplot as plt
7
8 # capture the image with USB webcamera
9 a=os.system("fswebcam --no-banner -r 1280x720 capture.jpg")
10 print(a)
11
12 credentials = ApiKeyCredentials(in_headers={"Prediction-key": "****"})
13 predictor = CustomVisionPredictionClient("https://birdcustomvisiontest.cognitiveservices.azure.com/", credentials)
14 projectID = "27dd8141-93c6-***-***-*******"
15 publish_iteration_name="Iteration*"
16
17 with open("capture.jpg", mode="rb") as captured_image:
18 results = predictor.detect_image(projectID, publish_iteration_name, captured_image)
19
20 # Display the results.
21 for prediction in results.predictions:
22 # print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
23 if prediction.probability>0.9:
24 print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100))
25 bbox = prediction.bounding_box
26 im = Image.open("capture.jpg")
27 draw = ImageDraw.Draw(im)
28 draw.rectangle([int(bbox.left * 1280), int(bbox.top * 720), int((bbox.left + bbox.width) * 1280), int((bbox.top + bbox.height) * 720)],outline='red',width=5)
29 im.save("detect.jpg")
30
31 de=Image.open("detect.jpg")
32 plt.figure("Result")
33 plt.imshow(de)
34 plt.show()
35

执行的结果如下图14所示,图中我们可以看到,返回的结果里面,将识别的鸟类用红色框进行了标注。

图14:鸟类识别结果页面

如果使用了LCD电容屏来做显示器,那么,我们执行的结果如下图15所示。

图15:树莓派硬件整体图

参考链接:

1. Microsoft Learn:使用自定义视觉对濒危鸟类进行分类

2. Azure资源:Azure 门户

3. 图片数据集的Github链接:资源链接

4. Custom Vision 门户:https://www.customvision.ai/projects

1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用的更多相关文章

  1. 快速搭建基于Azure Paas的高可用WordPress网站

    产品详情 产品介绍 WordPress是一种使用非常广泛的CMS系统.本应用是根据Azure Resource Manager模板创建的.通过该ARM模板可以快速建立web应用和MySQL数据库,部署 ...

  2. Hexo+Git一个小时快速搭建个人博客

    搭建本地环境:Hexo框架 Hexo为何物 Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用Markdown解析文章,并瞬间利用靓丽的主题生成静态网页.其中,Markdown是一个用于将普通 ...

  3. 在Ubuntu上快速搭建基于Beego的RESTful API

    最近在研究Go,打算基于Go做点Web API,于是经过初步调研,打算用Beego这个框架,然后再结合其中提供的ORM以及Swagger的集成,可以快速搭建一个RESTful API的网站. 下面是具 ...

  4. 如何快速搭建基于python+appium的自动化测试环境

    首先申明本文是基本于Python与Android来快速搭建Appium自动化测试环境: 主要分为以下几个步骤: 前提条件: 1)安装与配置python环境,打开 Python官网,找到“Downloa ...

  5. 快速搭建基于Spring Boot + Spring Security 环境

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.Spring Security 权限管理框架介绍 简介: Spring Security 提供了基于 ...

  6. 一个小时快速搭建微信小程序教程

    「小程序」这个划时代的产品发布快一周了,互联网技术人都在摩拳擦掌,跃跃欲试.可是小程序目前还在内测,首批只发放了 200 个内测资格(泪流满面).本以为没有 AppID 这个月就与小程序无缘了,庆幸的 ...

  7. 一个小时快速搭建微信小程序

    「小程序」这个划时代的产品发布快一周了,互联网技术人都在摩拳擦掌,跃跃欲试.可是小程序目前还在内测,首批只发放了 200 个内测资格(泪流满面).本以为没有 AppID 这个月就与小程序无缘了,庆幸的 ...

  8. 使用IDEA快速搭建基于Maven的SpringBoot项目(集成使用Redis)

    迫于好久没写博客心慌慌,随便写个简单版的笔记便于查阅. 新建项目 新建项目 然后起名 继续next netx finish. 首先附上demo的项目结构图 配置pom.xml <?xml ver ...

  9. 利用yeoman快速搭建React+webpack+es6脚手架

    自从前后端开始分离之后,前端项目工程化也显得越来越重要了,之前写过一篇搭建基于Angular+Requirejs+Grunt的前端项目教程,有兴趣的可以点这里去看 但是有些项目可以使用这种方式,但有些 ...

随机推荐

  1. 【Django】有关多用户管理的一点小经验分享

    前言 最近,笔者因为需要开发一个系统作为毕设的展示,因此就产生了有关多用户管理的问题.在这里我把自己的需求重新阐明一下:能够通过Django自带的用户管理框架,实现多用户的管理,例如登录.登出.ses ...

  2. shell字符串处理总结

    1. 字符串切片 1.1 基于偏移量取字符串 返回字符串 string 的长度 ${#string} 示例 [root@centos8 script]#str=" I Love Python ...

  3. 设计原则:开闭原则(OCP)

    1.什么是开闭原则 开闭原则的英文是Open Closed Principle,缩写就是OCP.其定义如下: 软件实体(模块.类.方法等)应该"对扩展开放.对修改关闭". 从定义上 ...

  4. Asp Net Core 5 REST API 使用 RefreshToken 刷新 JWT - Step by Step

    翻译自 Mohamad Lawand 2021年1月25日的文章 <Refresh JWT with Refresh Tokens in Asp Net Core 5 Rest API Step ...

  5. 【Prolog - 1.0 基础语法与概念】

    [概述] Prolog的语法与其它常用语言(如C,JAVA等)不同,它更接近于自然语言. [实例] 当我想表示"Mia是以女人"这个事实(之后会提到事实这个概念)的时候,我可以这么 ...

  6. Git版本控制之-创建配置本地git仓库

    查看全局配置:code .gitconfig [code 就代表的用vscode 打开gitconfig 文件,如果是 sublime 就是 subl ][如果打开失败说明环境变量没有配置] [只有配 ...

  7. c++ 实现向量去重操作

    去重的时候要考虑线性表或链表是否是有序 1.1.无序线性表 对于向量[1,5,3,7,2,4,7,3], 从头开始扫描vector内的元素, 对于表中r处的元素a[r], 检查数组0至r-1区间内是否 ...

  8. 10. Vue-Vue 的{{}}、v-html、v-text

    {{ }} 将元素当成纯文本输出 v-html v-html会将元素当成HTML标签解析后输出 v-text v-text会将元素当成纯文本输出 代码: <!DOCTYPE html> & ...

  9. Salesforce学习之路(九)Org的命名空间

    1. 命名空间的适用场景 每个组件都是命名空间的一部分,如果Org中设置了命名空间前缀,那么需使用该命名空间访问组件.否则,使用默认命名空间访问组件,系统默认的命名空间为"c". ...

  10. Insertion Sort and Merge Sort

    Insertion Sort(插入排序) 思路:for 循环遍历数组中的每一个数 用while将每次遍历到的数于左侧的数进行对比,将小的排到左边 void InsertionSort(int*A, i ...