1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用
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. 测试模型
根据自定义视觉提供的指标,我们的模型性能令人满意。 接下来测试模型,看看它处理未见过的数据时性能如何。 我们可以从网上搜索一张鸟类图像。
- 在 Web 浏览器中,搜索你训练该模型识别的其中一个鸟类物种的图像。 复制图像的 URL。
- 在自定义视觉门户中,选择“鸟类分类”项目。
- 在顶部菜单栏中,选择“快速测试”。
- 在“快速测试”中,将 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