基本概念

MindStudio

MindStudio提供了AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务,依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio实现了在一个工具上高效便捷地开发AI应用。

MindStudio

MindX SDK

提供昇腾AI处理器加速的各类AI软件开发套件(SDK),提供极简易用的API,加速高性能AI应用的开发。核心组件包含制造质检 mxManufacture、视觉分析 mxVision、特征聚类 mxlndex和大模型微调套件 mxTuningKit。

环境配置

安装MindStudio

MindStudio中下载MindStudio安装包,这里我下载的是5.0.RC3。
下载完成后按照安装引导进行安装。

setup

安装完成后,进入界面,可以先使用空白项目,为了方便设置中文File->Settings->Editor->Natural Languages

chinese

准备远程开发环境

利用华为云新建远程开发环境,这里使用官方提供的共享镜像,如使用全新环境,需要安装CANN和MindX SDK。
ECS

配置CANN

设置->系统设置->CANN中设置Remote ConnectionRemote CANN location
CANN

配置MindX SDK

同理,配置MindX SDK
MindX SDK

配置PyThon解释器

当打开工程文件后发现还需配置PyThon解释器环境,但是直接点击该处配置Python解释器时界面会卡住不动。
python

可以通过文件->项目设置->SDK->添加PythonSDK选择SSH Interpreter

pythonsdk
sshinter

再通过main下的编辑配置
main

情绪识别应用

代码下载

mindxsdk-referenceapps中下载情绪识别的代码,文件目录如图所示:
dir

main.py为程序入口,pipeline中是流程编排。

修改代码

  1. 首先需要根据README.md下载所需的模型,放入model文件夹中;
  2. 其次修改pipeline文件夹中的facial_expression_recognition.pipeline,将mxpi_objectpostprocessor0中的postProcessLibPath修改为./model/libyolov3postprocess.so
  3. 测试前需要将测试的图片放入image文件夹中,修改main.py中读取图片文件的路径。

运行

尝试运行时,出现了下图的错误:

error

可知,是打开PostProcessLib出现了权限错误,尝试使用终端连接服务器,将libyolov3postprocess.so文件权限修改为440,但是在运行程序时仍会因为重新同步文件覆盖权限,因此,手动将libyolov3postprocess.so移动到/usr/local/Ascend/mxVision/lib/plugins中,并将权限修改为440

执行程序
exe

查看结果

发现执行结束,但左侧目录中没有出现my_result.jpg,这是需要从远程下载过来,工具->Deployment->Download form ......,查看结果图片。

输入 输出
mayun mayun

测试过程中发现个好玩的(工程师出来挨打==)

输入 输出
ren ren

可视化流程编排

最初打开pipeline文件,全部为灰色,同时点击没有响应,通过在昇腾论坛上查找,发现有人遇到了相同的问题,解决方法为在远端重新安装mxVision
sdk

打开后正常情况如下:

pipeline

情绪识别应用流程编排为
pipeline

appsrc

向Stream中发送数据,appsrc将数据发给下游元件,blocksize为每个buffer读取的大小。

mxpi_imagedecoder

异步图像解码,支持JPG/JPEG/BMP格式。
mxpi_imagedecoder

mxpi_imageresize

对解码后的YUV、RGB格式的图像进行指定宽高的缩放。
mxpi_imageresize

mxpi_tensorinfer

对输入的张量进行推理。需要指定OM文件路径、输入数据索引等等。
mxpi_tensorinfer

mxpi_objectpostprocessor

对目标检测模型推理的输出张量进行后处理。
mxpi_objectpostprocessor

mxpi_distributor

向不同端口发送指定类别或通道的数据。
mxpi_distributor

mxpi_imagecrop

根据目标检测的(x,y)坐标和(width,height)宽高进行图像裁剪(抠图)。
mxpi_imagecrop

appsink

从stream中获取数据。

mian.py

新建Stream

1
2
3
4
5
6
7
8
9
10
11
12
13
streamManagerApi = StreamManagerApi()
# init stream manager
ret = streamManagerApi.InitManager()
if ret != 0:
print("Failed to init Stream manager, ret=%s" % str(ret))
exit()

# create streams by pipeline config file
pipeline_path = b"./pipeline/facial_expression_recognition.pipeline"
ret = streamManagerApi.CreateMultipleStreamsFromFile(pipeline_path)
if ret != 0:
print("Failed to create Stream, ret=%s" % str(ret))
exit()

喂入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
img_path = "image/test_1.jpg"
streamName = b"detection"
inPluginId = 0
dataInput = MxDataInput()
try:
with open(img_path, 'rb') as f:
dataInput.data = f.read()
except:
print("No such image")
exit()
ret = streamManagerApi.SendData(streamName, inPluginId, dataInput)
if ret < 0:
print("Failed to send data to stream")
exit()

取出数据并作图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
keyVec = StringVector()
keyVec.push_back(b"mxpi_imagedecoder0") # 原始图像
keyVec.push_back(b"mxpi_distributor0_0") # 人类检测结果
keyVec.push_back(b"mxpi_imagecrop0")
keyVec.push_back(b"mxpi_tensorinfer1") # 分类结果
infer_result = streamManagerApi.GetProtobuf(streamName, 0, keyVec)

if infer_result.size() == 0:
print("infer_result is null")
exit()
if infer_result.size() < 4:
print("No area of the face was detected in the picture")
exit()

tensorList3 = MxpiDataType.MxpiTensorPackageList()
tensorList3.ParseFromString(infer_result[3].messageBuf)

visionList0 = MxpiDataType.MxpiVisionList()
visionList0.ParseFromString(infer_result[2].messageBuf)

visionList = MxpiDataType.MxpiVisionList()
visionList.ParseFromString(infer_result[0].messageBuf)
visionData = visionList.visionVec[0].visionData.dataStr
visionInfo = visionList.visionVec[0].visionInfo
YUV_BYTES_NU = 3
YUV_BYTES_DE = 2
img_yuv = np.frombuffer(visionData, dtype=np.uint8)
img_yuv = img_yuv.reshape(visionInfo.heightAligned * YUV_BYTES_NU // YUV_BYTES_DE, visionInfo.widthAligned)
img = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR_NV12)

mxpiObjectList = MxpiDataType.MxpiObjectList()
mxpiObjectList.ParseFromString(infer_result[1].messageBuf)

# print the infer result
for i, _ in enumerate(tensorList3.tensorPackageVec):
res1 = np.frombuffer(tensorList3.tensorPackageVec[i].tensorVec[0].dataStr, dtype = np.float32)
maxindex = np.argmax(res1)

visionData0 = visionList0.visionVec[i].visionData.dataStr
visionInfo0 = visionList0.visionVec[i].visionInfo

y0 = mxpiObjectList.objectVec[i].y0
x0 = mxpiObjectList.objectVec[i].x0
y1 = mxpiObjectList.objectVec[i].y1
x1 = mxpiObjectList.objectVec[i].x1
height = y1 - y0
width = x1 - x0
cv2.rectangle(img, (int(x0), int(y0)), (int(x1), int(y1)), (255, 0, 0), 2)
cv2.putText(img, emotions[maxindex], (int(x0), int(y0)-1), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 0), 2)
cv2.imwrite("./my_result.jpg", img)

参考资料

【MindStudio训练营第一季】使用MindStudio体验FacialExpressionRecognition人脸情绪识别
MindX SDK