-
求教“获取区域文本”和“提取sheet页内容”这两个控件有什么区别呀?有时候机器人流程里可以用获取区域文本,有时候又一定是提取sheet页内容。
-
升级的固件版本:A200-3000HiLens-FW-V2.2.200.011.hpm错误提示
-
一、What根据官网的介绍,华为云HiLens,由具备AI推理能力的摄像头(如华为云多模态人工智能开发套件HiLens Kit)和云上开发平台组成,提供一站式技能开发、设备管理、数据管理、技能市场等,帮助用户开发AI技能并将其下发到端侧设备。 华为云HiLens首批发布了5类应用场景,包含家庭、车载、园区、商超和其他等。涉及了25+的技能集,主要包含人脸/人形检测、人脸属性检测、异常声音检测、疲劳驾驶、人脸对比、车牌识别、入侵检测、人流热地图等。HiLens关键特性有以下四点:关键能力1:一站式Skill开发服务,快速定制行业应用;关键能力2:端侧算法开发框架HiLens Framework;关键能力3:自动模型转换、模型压缩优化;关键能力4:开放的技能市场及预置丰富的Skill技能。二、Why众所周知,传统视频分析流程一般是先通过智能IPC获取到设备,然后将视频流传到云端,最后通过云端存储与分析。其实,这样传统的方案会有以下几个缺点:全景视频上云宽带成本高;端侧仅能运算有限的算法;算法与硬件存在强绑定的特点,AI技能的扩展性较弱;用户对隐私数据上云较为敏感。与传统的视频分析流程相比,华为云HiLens的解决方案则是通过端侧设备结合智能IPC实现本地AI技能,视频帧传到云API,通过技能市场实现AI技能本地部署。对比传统方案,华为云的解决方案通过AI分析本地运行,大大降低成本。并且,端云协同实现的技能还可以按需进行加载和更新。当然,也支持第三方开发技能,同时保护隐私。华为HiLens平台的优势包含了端云协同推理、Skill开发框架、开箱即用的开发环境、跨平台设计、预置丰富的AI技能、开发者社区。三、How为了更加公正客观的测试HiLens Kit设备的性能,博主先后基于该设备采用了不同的技能进行了多次试验,在整个的试验测试过程中,一句话概括来讲,该设备的鲁棒性比较好并且性价比非常高。 博主将会按照时间线的顺序分享一下测评感悟。从才开始拿到该设备,后续的注册、安装、连接、实景测试的整个流程进行详细讲解,以博主自己和朋友们的亲身体验,与大家分享一下这款能够几乎覆盖全场景应用的可扩展性AI设备。图1 华为HiLens设备HiLens Kit设备的轻巧使其部署更加灵活和方便。一开始,刚拿到该设备的时候,博主还是很惊讶的,虽然已经看过它的官方图片,但是HiLens Kit设备(如图1所示)比博主想象中还是要小得多,小巧玲珑的设计使得其应用变得更加灵活、广泛。外观造型有点像坦克,中间的摄像头可以调整拍摄角度,90度的范围。如图若是,设备两侧是散热孔,后端最右侧是开关按钮,向右依次是电源插口、两个USB接口、HDMI接口、RST键、耳机接口、SD卡插槽、网线接口。图2 网线和HDMI线 HiLens Kit设备的安装需要观看官网教程,但实际操作起来也并不复杂。通过参考官网教程,几分钟就可以搞定。因为寄给博主的时候,没有附带额外的网线,于是,博主从某宝上买了一根网线,再加上博主已有的一根HDMI线,如图2所示。当这些材料准备齐全后,博主就进行了安装。安装之前,博主先是从官网上看了一遍安装和配置教程,其实比较简单,但是为了保证顺利安装,博主还是建议多看几遍安装教程。整个安装过程共有四个步骤:第一步,先用网线把HiLens Kit连接到了博主的电脑上。第二步,通过电脑配置HiLens Kit设备,将其设置到与电脑所在的同一个网段。第三步,利用Web端登录到设备,进入管理页面,进而来连接本地的WiFi。第四步,通过ssh登录到设备,实现注册,如图3。特别要注意的是,当博主进行到第四步操作的时候,出现了一个bug,大概的意思是没有权限访问资源。最后通过华为的客服人员告知,才发现是博主自己以前使用华为云服务的时候欠费所导致。当然只要华为云账户不欠费,就可以正常使用。当博主充上钱之后,重新登录,通过刷新设备列表,页面增加了新注册的设备!图3 设备注册 于是,博主就迫不及待的去点击了技能市场按钮,依次进行测试了人形检测、人脸属性识别、人脸特效、静态手势识别、疲劳驾驶检测等技能,如列表1所示。其中人脸特效和静态手势识别技能更加有趣味性和交互性。表1 市场技能为了让大家对Hilens Kit设备性能有一个直观的感受,博主将会从以下四个主要场景的几个主要应用分别进行测试,分享一下使用华为Hilens Kit的过程和感受。1、智慧家庭—“AI”与呵护家庭+AI的应用,在未来将会越来越多,这种无微不至的智能关怀,会给家人带来更多的温馨。华为Hilens设备包含了人脸识别和陌生人检测、婴儿哭声检测、人体姿态检测技能,利用AI技术不仅及时有效的展示了对家的“爱”,更重要的是呵护了带有温度的家。下图是对人脸属性识别和静态手势检测技能进行测试的效果。图4 手势识别测试2、智能园区—“AI”与守护智能园区的场景中,Hilens设备集成了车牌识别、人形车辆检测、安全帽检测的技能,不仅提高了车辆通行效率,更重要的是守护了人身安全。其中,还包括了趣味性的交互技能,比如人脸特效检测,呈现带有酷炫眼镜和大金链子的视觉效果。下图是对人脸特效技能进行测试的效果。 图5 人脸特效测试3、智能车载—“AI”与保护在智能驾驶领域,Hilens设备加入了人脸属性检测与识别、人脸对比、疲劳驾驶检测的技能。其中,人脸识别属性检测目前可检测到的属性分别是Age、Gender、Smile、Glasses、beard。下图是对人脸属性技能进行测试的效果。 图6 人脸属性识别测试4、智能商超—“AI”与监护随着无人超市的兴起,现代化的智能商业超市的布局也越来越多。Hilens设备中的VIP识别、人形轨迹检测、客流量统计等技能为商户实现无人超市提供了最为便捷的服务。四、Conclusion总体来讲,Hilens Kit设备的实时性非常好,响应非常快,测试的几个技能几乎没有误检,小目标检测也比较鲁棒,准确率高,能够实现精准检测和识别。经过多次测试,除了性别属性有时候会误检之外,其余的几个场景测试效果非常好。 在进行人脸属性实时检测时,即使博主实时的靠近和远离,Hilens Kit设备也几乎不会漏检,并且小目标检测效果也非常稳定,戴上眼镜与摘下眼镜也能实时区分,但是人脸的性别属性有时候会随着光线的变化存在误分类。在进行人脸特效测试时,自动带上戴上墨镜和大金链子的特效非常酷炫,增加了交互的趣味性,测试的时候没有漏检。在进行单目标静态手势识别的时候,不同手势的快速切换,实时检测也非常灵敏,测试的时候没有误检。Hilens Kit设备的可扩展性非常好。它能够辅助我们开发人员研发最新的AI技能,并将该技能快速下发到端侧设备,使得我们开发人员快速实现自己的idea。通过基于Hilens Kit设备的反复测试和改进,这种反馈性更能激励我们开发出更多更好的新技能,满足我们开发人员的成就感。使得我们技术人员不再单单是懂技术,而是更加直观感受了场景的业务需求,这种基于业务的理解会赋予我们开发人员拥有更多的优化技巧。当然,除了以上的优点,还有几点待改进的地方。首先,人脸的性别属性可以通过改进算法加强训练变得更加鲁棒。其次,在进行实时检测的时候,有时候会出现从散热器内产生的噪声,这一点也从侧面说明了AI设备的确需要较多的算力支持。众所周知,深度学习算法在进行实时推理的时候,大量的计算产生大量的热,所以需要及时散热。但是,如果考虑到价格因素,从性价比的角度,综合来说,Hilens Kit设备非常划算,值得购买。最后,感谢华为提供华为Hilens Kit的产品体验,以上是博主为广大粉丝朋友带来的分享。
-
在unity使用koomap的情况下是否可以调用华为HiLens来进行二维图片识别进行三维物体定位
-
使用hilens在 rk3588s开发板上进行部署,在最后一步,./bin/main.sh。后遇到报错debain os need load libgomp,Try modelbox -h for more information.已经试了debian系统和ubuntu系统,都是同样的错误。
-
最近自己开发的技能不能安装,提示“安装失败:原因:命令下发失败,请检查设备网络等问题。”,之前是能够成功安装的,而使用技能市场的却可以。
-
想咨询一下使用Hilens RK3568实现以下功能的可行性:Hilens RK3568上部署AI算法后,使用鸿蒙开发的APP,获取Hilens RK3568的实时视频流,将Yolo的识别结果实时展示;另外还可以根据需要发送抓拍请求,然后将抓拍结果返回给APP显示。
-
1 ModelBox社区案例 - 使用YOLOX做垃圾分类本案例将使用YOLOX模型,实现一个简单的垃圾分类应用,最终效果如下所示:本案例所需资源(代码、模型、测试数据等)均可从garbage_det下载1.1 模型训练与转换模型采用的是YOLOX网络结构,YOLOX是YOLO系列的优化版本,引入了解耦头、数据增强、无锚点以及标签分类等目标检测领域的优秀进展,拥有较好的精度表现,同时对工程部署友好。训练使用的是“华为云杯”生活垃圾图片分类数据集,该数据集包含一次性快餐盒、果皮果肉、旧衣服等44个类别,共14964张图片。其中,训练集与验证集划分比例为4/1,下图为模型迭代个300个Epoch取得的结果:ModelArts提供了包括数据标注,训练环境,预置算法在内的丰富的功能,甚至可以通过订阅预置算法实现0代码的模型训练工作。当然你也可以在本地训练自己的模型。我们假设你现在已经拥有了训练好的模型,接下来我们需要将训练好的模型转换成为可以在开发板上运行的模型。我们发布了开发板模型转换案例,参见RK3568模型转换验证案例:在这个案例中我们演示了从环境适配到模型的转换验证的全流程样例代码,开发者可以通过“Run in ModelArts”一键将Notebook案例在ModelArts控制台快速打开、运行以及进行二次开发等操作。1.2 应用开发打开VS Code,连接到ModelBox sdk所在目录或者远程开发板,开始进行垃圾分类应用的开发。下面以RK3568版本为例进行说明,其他版本与之类似。1.2.1 1)下载模板执行python solution.py -l可看到当前公开的技能模板:███ $ python solution.py -l...Solutions name:mask_det_yolo3…hand_det_yoloxhand_tracking_yoloxsingle_hand_pose_yolox_mbv2multi_hand_pose_yolox_mbv2结果中的hand_det_yolox即为手部检测应用模板,可使用如下命令下载模板:███ $ python solution.py -s hand_det_yolox...solution.py工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。1.2.2 2)创建工程在ModelBox sdk目录下使用create.py创建garbage_det工程,末尾-s参数,表示将使用后面参数值代表的模板创建工程,而不是创建空的工程。███/modelbox$ python create.py -t server -n garbage_det -s hand_det_yoloxsdk version is modelbox-xxxsuccess: create garbage_det in ███/modelbox/workspaceworkspace目录下将创建出garbage_det工程,工程内容如下所示:garbage_det|--bin│ |--main.bat:应用执行入口│ |--mock_task.toml:应用在本地执行时的输入输出配置,此应用默认使用本地视频文件为输入源,最终结果输出到另一本地视频文件,可根据需要修改|--CMake:存放一些自定义CMake函数|--data:存放应用运行所需要的图片、视频、文本、配置等数据│ |--hand.mp4:手部检测测试用视频文件—>替换为自己的视频|--dependence│ |--modelbox_requirements.txt:应用运行依赖的外部库在此文件定义|--etc│ |--flowunit:应用所需的功能单元存放在此目录│ │ |--cpp:存放C++功能单元编译后的动态链接库,此应用没有C++功能单元│ │ |--yolox_post:手部检测使用的是YOLOX模型,此处即为后处理功能单元(修改toml文件的类别参数和py文件的draw函数)|--flowunit_cpp:存放C++功能单元的源代码,此应用没有C++功能单元|--graph:存放流程图│ |--garbage_det.toml:默认流程图,使用本地视频文件作为输入源│ |--garbage_det_camera.toml:摄像头输入对应的流程图│ |--modelbox.conf:modelbox相关配置|--hilens_data_dir:存放应用输出的结果文件、日志、性能统计信息|--model:推理功能单元目录│ |--detect_hand:手部检测推理功能单元│ │ |--detect_hand.toml:手部检测推理功能单元的配置文件│ │ |--yolox_hand.onnx:手部检测onnx模型—>更改为自己的模型|--build_project.sh:应用构建脚本|--CMakeLists.txt|--rpm:打包rpm时生成的目录,将存放rpm包所需数据|--rpm_copyothers.sh:rpm打包时的辅助脚本1.2.3 3)修改后处理功能单元 yolox_posta. 修改yolox_post.toml流程图,将其内容修改为(以Windows版ModelBox为例):b. 修改yolox_post.py的draw函数实现如下: def draw(self, img, bboxes): h, w, c = img.shape thickness = 2 font_scale = 1 text_font = cv2.FONT_HERSHEY_SIMPLEX clss_to_text = { 0: "Disposable snack box", 1: "Books and papers", 2: "Power bank", 3: "Leftovers", 4: "Package", 5: "Trash can", 6: "Plastic utensils", 7: "Plastic toys", 8: "Plastic coat hanger", 9: "Big Bones", 10: "Dry battery", 11: "Express paper bag", 12: "Plug wire", 13: "Old clothes", 14: "The can", 15: "Pillow", 16: "Skin and pulp", 17: "Stuffed animal", 18: "Defacing plastic", 19: "Soiled paper", 20: "Toiletries", 21: "Cigarette butts", 22: "Toothpick", 23: "Glassware", 24: "Block", 25: "Chopsticks", 26: "Carton carton", 27: "Pot", 27: "Tea residue", 29: "Vegetable help vegetable leaf", 30: "Shell", 31: "The spice bottle", 32: "Paste", 33: "Expired drugs", 34: "Bottle", 35: "Metal kitchenware", 36: "Metal ware", 37: "Metal food cans", 38: "Pot", 39: "Ceramic vessels", 40: "Shoes", 41: "Edible oil drum", 42: "Beverage bottle", 43: "Bones" } for box in bboxes: x1, y1, x2, y2, score, clss = box cv2.putText(img, clss_to_text[int(clss)]+': '+"{:.3}".format(score*100)+'%', (int(x1 * w)+10, int(y1 * h)+30),text_font, font_scale, (0, int(clss+1)*5, 0), thickness) cv2.rectangle(img, (int(x1 * w), int(y1 * h)), (int(x2 * w), int(y2 * h)), (0, int(clss+1)*5, 0), 3)1.2.4 4)修改输入输出配置我们需要准备一个mp4文件拷贝到data文件夹下,我们使用测试视频garbage.mp4,然后打开工程目录下bin/mock_task.toml文件,修改其中的任务输入和任务输出配置为如下内容:[input]type = "url"url = "../data/garbage.mp4"[output]type = “local”url = “…/hilens_data_dir/garbage_detection_result.mp4”该流程图在本地运行时的逻辑过程是:data_source_parser解析bin/mock_task.toml文件中输入配置的data/garbage.mp4文件,video_demuxer和video_decoder对该文件进行解码,resize、packed_planar_transpose、normalize对原始图像进行缩放、转码、归一化等预处理,然后detect_garbage在预处理后的图像上进行垃圾检测,yolox_post从推理结果中解码出检测框,并把检测框画到原始图像上,最后video_out将图像输出到bin/mock_task.toml文件中输出配置的hilens_data_dir/garbage_detection_result.mp4文件中。1.2.5 5)用启动脚本执行应用启动应用前执行build_project.sh进行工程构建,该脚本将编译自定义的C++功能单元(本应用不涉及)、将应用运行时会用到的配置文件转码为Unix格式(防止执行过程中的格式错误):███$ ./build_project.shdos2unix: converting file xxx.toml to Unix format......build success: you can run main.bat in ./bin folderPress ‘p’ to pause…, any key to exit然后执行bin/main.bat运行应用:███$ ./bin/main.bat…运行结束后在hilens_data_dir目录下生成了garbage_detection_result.mp4文件,可以打开查看:1.2.6 6)用摄像头检测打开工程目录下bin/mock_task.toml文件,修改其中的任务输入和任务输出配置为如下内容:[input]type = "url"url = "0" # 表示0号摄像头,即PC自带摄像头,若PC无摄像头需外接USB摄像头[output]type = “local”url = “0:garbage_det” # 表示名为garbage_det的本地窗口即使用编号为0的摄像头(默认为PC自带的摄像头),输出画面显示到名为garbage_det的本地屏幕窗口中。1.2.7 7)运行应用执行bin/main.bat camera运行应用,将会自动弹出实时的垃圾分类检测画面:1.3 打包部署1.3.1 打包调试完成后,同样可以通过create.py脚本将应用打包发布:python ./create.py -t rpm -n garbage_det控制台中输出:sdk version is modelbox-win10-x64-1.1.0.5call mb-pkg-tool pack [folder] > [rpm file] to building rpm, waiting...success: create garbage_det.rpm in D:\modelbox-win10-x64-1.1.0.5/workspace/garbage_det等待稍许,可以看到项目工程下已经生成了rpm文件夹和打包好的应用:1.3.2 部署将打包好的应用上传至华为云账号下的obs桶中:在专业版设备管理中选择一个开发板,点击创建部署:最后添加作业:这样我们就已经完成了一个AI应用,从模型训练到转换到开发到部署的全部流程。关于ModelBox核心概念、功能单元和流程图开发的更多介绍,可查看ModelBox手册。
-
ModelBox开发案例 - 隔空作画本案例将使用YOLOX、SCNet两个模型,实现一个简单的隔空作画趣味应用,使用🖐手势作画,使用🤟手势取食指处色块换色,使用✊手势清屏。最终效果如下所示: 案例所需资源(代码、模型、测试数据等)均可从obs桶下载。模型训练我们使用面向开发者的一站式AI开发平台ModelArts进行模型的训练:ModelArts提供了包括数据标注,训练环境,预置算法在内的丰富的功能,甚至可以通过订阅预置算法实现0代码的模型训练工作。当然你也可以在本地训练自己的模型。我们假设你现在已经拥有了训练好的模型,接下来我们需要将训练好的模型转换成为可以在开发板上运行的模型。模型转换我们发布了开发板模型转换案例,参见RK3568模型转换验证案例 :在这个案例中我们演示了从环境适配到模型的转换验证的全流程样例代码,开发者可以通过“Run in ModelArts”一键将Notebook案例在ModelArts控制台快速打开、运行以及进行二次开发等操作。开发环境部署使用开发板进行ModelBox AI应用开发有两种方式,一是开发板连接显示器和键盘鼠标,安装Ubuntu桌面,直接在开发板上进行开发;二是使用远程连接工具(如VS Code中的Remote-SSH)从PC端登录开发板进行开发。这里我们推荐第二种方式,因为PC端可以使用功能更丰富、界面更友好的IDE。1.配置网络PC连接开发板需要知道开发板的ip,但是开发板默认没有固定ip,我们提供了ModelBox PC Tool,可以自动为开发板配置ip,也可以在推理阶段很方便的进行视频推流拉流。PC Tool位于SDK的connect_wizard目录中:双击connect_wizard.exe,在页面中可以看到有两种开发板连接方式,我们使用网线连接开发板的方式:按照指引断开或连接网线:等待一小段时间,可以看到来到了第三步,此时开发板已设置为默认ip:192.168.2.111,PC使用该ip即可SSH登录:2. 远程连接开发板我们推荐在PC端使用VS Code远程连接开发板来对设备操作。使用VS Code连接开发板可以参考我们发布的ModelBox 端云协同AI开发套件(RK3568)上手指南。同时,上手指南也介绍了如何将开发板注册到HiLens管理控制台进行更方便的在线管理。应用开发接下来我们会以隔空作画demo为例,介绍如何使用ModelBox开发一个AI应用。1. 创建工程SDK提供了工程脚本create.py,可以使用./create.py -h查看脚本帮助:ModelBox提供了可视化图编排工具:Editor,可以使用./create.py -t editor开启图编排服务:服务默认ip即为192.168.2.111,如需配置其他ip或端口,可以通过-i ip:port参数进行配置。点击链接即可进入可视化编辑界面,我们点击编排进入工程开发界面,如果进一步了解ModelBox相关内容,可以点击右上角帮助:进入编排界面,点击右上角新建项目:项目路径填写workspace,项目名称填写hand_painting, 确认:可以看到我们已经拥有了一个带有http收发单元的默认图:其中,区域1为SDK预置的高性能通用流单元,区域2为可视化编排界面,区域3为对应的图配置文件内容。同时,VS Code对应目录下也出现了hand_painting项目:2. 创建推理功能单元接下来,我们创建推理流单元:对于手检测模型,我们将流单元命名为hand_detection,模型文件名即为转换好的检测模型名:yolox_hand.rknn,此模型输入为image,输出为feature map,所以我们添加int类型的输入端口与float类型的输出端口。关于开发板的推理流单元创建,在处理类型时我们选择cuda,即为npu推理,推理引擎可选任意一款,目前开发板SDK可以自动进行识别转换。最后将功能单元分组修改为inference,点击确认,即可看到,在右侧inference页签下出现了:同时,在VS Code工程model目录下可以看到创建好的推理流单元:同样的,我们创建pose_detection推理流单元:3. 创建后处理功能单元除了推理流单元外,隔空作画demo还需要一些通用功能单元:检测后处理单元、感兴趣区域提取单元、作画单元,我们新建三个python功能单元来满足上述需求。对于检测后处理单元,我们希望通过原图和hand_detection的输出解码出手检测框,所以该单元应该有两个输入。此外,对于画幅中有手或者没有检测到手两种状态,我们希望该功能单元分情况处理,检测到手时,将检测结果送入感兴趣区域提取单元,没有检测到手时,直接返回,因此功能单元类型选择:IF_ELSE。新建单元如下:同样的,根据输入输出与功能单元状态,我们创建extract_roi和painting两个功能单元:4. 流程图编排拖拽需要的功能单元全部创建好后,我们可以着手编排流程图,我们编排一个视频处理的图,暂时不需要http收发单元,可以删除不需要的单元:⚠️⚠️⚠️:后续版本会对input单元进行校验,该单元名称必须为input1,请将下文图文中所有input0替换为input1。在Generic列表下将虚拟输入单元input和我们刚刚创建的三个功能单元拖入画布:在Image列表下将模型推理需要用到的预处理单元resize拖入画布,因为我们需要两个resize单元,所以重复拖入:值得注意的是,resize单元需要配置参数,需要点击该单元进行配置:在Input列表下拖入输入解析单元data_source_parser:在Video列表下拖入视频处理需要的单元video_demuxer、video_decoder、video_out:最后,在Inference列表下拖入我们创建的两个推理单元:编排将功能单元按照处理逻辑进行连接:虚拟输入input连接输入解析data_source_parser,解析后送入视频解包与解码单元:解码输出送入预处理后可直接进行推理:推理后处理需要输入原图与推理结果,没有结果则直接连接视频输入单元,有结果则连接感兴趣区域提取单元:提取结果送入预处理与推理:最后,得到的关键点结果与原图送入作画单元,作画结果送入视频输出单元进行保存:这样,我们就完成了流程图的编排,可以看到在GraphViz区域也出现了完整的图表述:保存项目,转到VS Code进行每个单元的代码实现:5. 代码补全可视化编排中,创建的推理单元位于项目的model目录下,通用单元位于etc/flowunit目录下,流程图位于graph目录下,可以看到创建的单元与图都已同步过来:其中,video_decoder需要指定类型:video_decoder7 [ type=flowunit flowunit=video_decoder device=rknpu, deviceid="0", pix_fmt=bgr label="{{<in_video_packet> in_video_packet}|video_decoder7|{<out_video_frame> out_video_frame}}" ]推理单元首先完善推理单元,对于推理功能单元,只需要提供独立的toml配置文件,指定推理功能单元的基本属性即可,目录结构为:[flowunit-name] |---[flowunit-name].toml #推理功能单元配置 |---[model].rknn #模型文件 |---[infer-plugin].so #推理自定义插件ModelBox框架在初始化时,会扫描目录中的toml后缀的文件,并读取相关的推理功能单元信息。[infer-plugin].so是推理所需插件,推理功能单元支持加载自定义插件,开发者可以实现自定义算子。将模型拷入对应文件夹,以hand_detection为例我们看一下推理功能单元配置文件:配置文件中有一些单元类型、模型名称、输入输出的基本配置,可以酌情修改。通用单元Python通用单元需要提供独立的toml配置文件,指定python功能单元的基本属性。一般情况,目录结构为:[FlowUnitName] |---[FlowUnitName].toml |---[FlowUnitName].py |---xxx.py相较于推理单元而言,通用单元不但有配置文件,还需要完善具体的功能代码,以yolox_post为例,首先是功能单元配置文件:# Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. # Basic config [base] name = "yolox_post" # The FlowUnit name device = "cpu" # The flowunit runs on cpu version = "1.0.0" # The version of the flowunit type = "python" # Fixed value, do not change description = "description" # The description of the flowunit entry = "yolox_post@yolox_postFlowUnit" # Python flowunit entry function group_type = "generic" # flowunit group attribution, change as input/output/image ... # Flowunit Type stream = false # Whether the flowunit is a stream flowunit condition = true # Whether the flowunit is a condition flowunit collapse = false # Whether the flowunit is a collapse flowunit collapse_all = false # Whether the flowunit will collapse all the data expand = false # Whether the flowunit is a expand flowunit # The default Flowunit config [config] item = "value" # Input ports description [input] [input.input1] # Input port number, the format is input.input[N] name = "in_image" # Input port name type = "uint8" # input port data type ,e.g. float or uint8 device = "cpu" # input buffer type [input.input2] # Input port number, the format is input.input[N] name = "in_feat" # Input port name type = "uint8" # input port data type ,e.g. float or uint8 device = "cpu" # input buffer type # Output ports description [output] [output.output1] # Output port number, the format is output.output[N] name = "has_hand" # Output port name type = "float" # output port data type ,e.g. float or uint8 [output.output2] # Output port number, the format is output.output[N] name = "no_hand" # Output port name type = "float" # output port data type ,e.g. float or uint8Basic config是一些单元名等基本配置,Flowunit Type是功能单元类型,yolox_post是一个条件单元,所以可以看到condition为true,此外还有一些展开、归拢等性质,可以在AI Gallery ModelBox)板块下看到更多案例。config为单元需要配置的一些属性,如本单元需要一些特征图size、阈值等信息,所以在配置文件中修改config为:[config] net_h = 320 net_w = 320 num_classes = 2 conf_threshold = 0.5 iou_threshold = 0.5此外,输入输出type根据实际逻辑可能进行一些修改:# Input ports description [input] [input.input1] # Input port number, the format is input.input[N] name = "in_image" # Input port name type = "uint8" # input port data type ,e.g. float or uint8 device = "cpu" # input buffer type [input.input2] # Input port number, the format is input.input[N] name = "in_feat" # Input port name type = "float" # input port data type ,e.g. float or uint8 device = "cpu" # input buffer type # Output ports description [output] [output.output1] # Output port number, the format is output.output[N] name = "has_hand" # Output port name type = "uint8" # output port data type ,e.g. float or uint8 [output.output2] # Output port number, the format is output.output[N] name = "no_hand" # Output port name type = "uint8" # output port data type ,e.g. float or uint8接下来,我们查看yolox_post.py,可以看到创建单元时已经生成了基本接口:# Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. #!/usr/bin/env python # -*- coding: utf-8 -*- import _flowunit as modelbox class yolox_postFlowUnit(modelbox.FlowUnit): # Derived from modelbox.FlowUnit def __init__(self): super().__init__() def open(self, config): # Open the flowunit to obtain configuration information return modelbox.Status.StatusCode.STATUS_SUCCESS def process(self, data_context): # Process the data in_data = data_context.input("in_1") out_data = data_context.output("out_1") # yolox_post process code. # Remove the following code and add your own code here. for buffer in in_data: response = "Hello World " + buffer.as_object() result = response.encode('utf-8').strip() add_buffer = modelbox.Buffer(self.get_bind_device(), result) out_data.push_back(add_buffer) return modelbox.Status.StatusCode.STATUS_SUCCESS def close(self): # Close the flowunit return modelbox.Status() def data_pre(self, data_context): # Before streaming data starts return modelbox.Status() def data_post(self, data_context): # After streaming data ends return modelbox.Status() def data_group_pre(self, data_context): # Before all streaming data starts return modelbox.Status() def data_group_post(self, data_context): # After all streaming data ends return modelbox.Status()如果功能单元的工作模式是stream = false时,功能单元会调用open、process、close接口;如果功能单元的工作模式是stream = true时,功能单元会调用open、data_group_pre、data_pre、process、data_post、data_group_post、close接口;用户可根据实际需求实现对应接口。根据单元性质,我们主要需要完善open、process接口:import _flowunit as modelbox import numpy as np from yolox_utils import postprocess, expand_bboxes_with_filter, draw_color_palette class yolox_postFlowUnit(modelbox.FlowUnit): # Derived from modelbox.FlowUnit def __init__(self): super().__init__() def open(self, config): self.net_h = config.get_int('net_h', 320) self.net_w = config.get_int('net_w', 320) self.num_classes = config.get_int('num_classes', 2) self.num_grids = int((self.net_h / 32) * (self.net_w / 32)) * (1 + 2*2 + 4*4) self.conf_thre = config.get_float('conf_threshold', 0.3) self.nms_thre = config.get_float('iou_threshold', 0.4) return modelbox.Status.StatusCode.STATUS_SUCCESS def process(self, data_context): modelbox.info("YOLOX POST") in_image = data_context.input("in_image") in_feat = data_context.input("in_feat") has_hand = data_context.output("has_hand") no_hand = data_context.output("no_hand") for buffer_img, buffer_feat in zip(in_image, in_feat): width = buffer_img.get('width') height = buffer_img.get('height') channel = buffer_img.get('channel') img_data = np.array(buffer_img.as_object(), copy=False) img_data = img_data.reshape((height, width, channel)) feat_data = np.array(buffer_feat.as_object(), copy=False) feat_data = feat_data.reshape((self.num_grids, self.num_classes + 5)) ratio = (self.net_h / height, self.net_w / width) bboxes = postprocess(feat_data, (self.net_h, self.net_w), self.conf_thre, self.nms_thre, ratio) box = expand_bboxes_with_filter(bboxes, width, height) if box: buffer_img.set("bboxes", box) has_hand.push_back(buffer_img) else: draw_color_palette(img_data) img_buffer = modelbox.Buffer(self.get_bind_device(), img_data) img_buffer.copy_meta(buffer_img) no_hand.push_back(img_buffer) return modelbox.Status.StatusCode.STATUS_SUCCESS def close(self): # Close the flowunit return modelbox.Status()可以看到,在open中我们进行了一些参数获取,process进行逻辑处理,输入输出可以通过data_context来获取,值得注意的是输出时我们返回的是图,在检测到手时为图附加了检测框信息,该信息可以被下一单元获取。同样的,完善其余通用功能单元,具体可以参考我们提供的代码。应用运行我们需要准备一个mp4文件拷贝到data文件夹下,我们提供了测试视频hand.mp4,然后打开工程目录下bin/mock_task.toml文件,修改其中的任务输入和任务输出配置为如下内容:# 任务输入,mock模拟目前仅支持一路rtsp或者本地url # rtsp摄像头,type = "rtsp", url里面写入rtsp地址 # 其它用"url",比如可以是本地文件地址, 或者httpserver的地址,(摄像头 url = "0") [input] type = "url" url = "../data/hand.mp4" # 任务输出,目前仅支持"webhook", 和本地输出"local"(输出到屏幕,url="0", 输出到rtsp,填写rtsp地址) # (local 还可以输出到本地文件,这个时候注意,文件可以是相对路径,是相对这个mock_task.toml文件本身) [output] type = "local" url = "../hilens_data_dir/paint.mp4"配置好后在工程路径下执行build_project.sh进行工程构建:rock@rock-3a:~/lxy/examples$ cd workspace/hand_painting/ rock@rock-3a:~/lxy/examples/workspace/hand_painting$ ./build_project.sh dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/graph/hand_painting.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/graph/modelbox.conf to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/etc/flowunit/extract_roi/extract_roi.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/etc/flowunit/painting/painting.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/etc/flowunit/yolox_post/yolox_post.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/model/hand_detection/hand_detection.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/model/pose_detection/pose_detection.toml to Unix format... dos2unix: converting file /home/rock/lxy/examples/workspace/hand_painting/bin/mock_task.toml to Unix format... build success: you can run main.sh in ./bin folder rock@rock-3a:~/lxy/examples/workspace/hand_painting$ 构建完成后运行项目:rock@rock-3a:~/lxy/examples/workspace/hand_painting$ ./bin/main.sh 等待稍许即可以在hilens_data_dir文件夹下看到运行结果:除了mp4外我们也支持很多其他类型的输入输出,ModelBox PC TOOL也提供了推流与拉流功能,选择输入实时视频流,启动:运行程序时配置输出地址为推流地址,即可在本机网页中查看到运行结果:如果需要对应用进行性能评估,只需要在流程图配置文件中开启profile:[profile] profile=true # 启用profile trace=true # 启用traceing dir="/tmp/modelbox/perf" # 设置跟踪文件路径配置启动后,启动运行流程图,profile会每隔60s记录一次统计信息,trace会在任务执行过程中和结束时,输出统计信息。运行流程图后,会生成性能相关的json文件,通过将json文件加载到浏览器中即可查看timeline信息。打开chrome浏览器。浏览器中输入chrome://tracing/。点击界面中的Load按钮,加载trace的json文件。加载成功后,将看到类似下面的timeline视图:打包部署打包调试完成后,同样可以通过create.py脚本将应用打包发布:./create.py -t rpm -n hand_painting控制台中输出:sdk version is modelbox-rk-aarch64-1.0.8.8 call mb-pkg-tool pack [folder] > [rpm file] to building rpm, waiting... success: create hand_painting.rpm in /home/rock/lxy/examples/workspace/hand_painting等待稍许,可以看到项目工程下已经生成了rpm文件夹和打包好的应用:部署将打包好的应用上传至华为云账号下的obs桶中:在专业版设备管理中找到开发板,点击创建部署:技能包选择刚刚上传的应用:如果需要,可以配置一些启动参数,否则默认完成即可:这样我们就已经完成了一个AI应用,从模型训练到转换到开发到部署的全部流程。关于ModelBox核心概念、功能单元和流程图开发的更多介绍,可查看ModelBox手册。
-
HiLens Kit是否可以在离线情况下运行技能?
-
HiLens Kit设备告警提示目录空间满怎么办?
-
HiLens kit设备注册时提示:Role is op_restricted,该怎么解决?
-
初次使用ModelBox,跟着这个文档里的教程ModelBox 端云协同AI开发套件(RK3568)上手指南 (huaweicloud.com)构建完工程之后,执行bin/main.sh 报错尝试安装libgomp1发现已安装求助后续如何处理?
-
ModelBox镜像和SDK有什么关系?ModelBox不是已经提供SDK用于开发了,为什么还有开源镜像?
推荐直播
-
华为AI技术发展与挑战:集成需求分析的实战指南
2024/11/26 周二 18:20-20:20
Alex 华为云学堂技术讲师
本期直播将综合讨论华为AI技术的发展现状,技术挑战,并深入探讨华为AI应用开发过程中的需求分析过程,从理论到实践帮助开发者快速掌握华为AI应用集成需求的框架和方法。
去报名 -
华为云DataArts+DWS助力企业数据治理一站式解决方案及应用实践
2024/11/27 周三 16:30-18:00
Walter.chi 华为云数据治理DTSE技术布道师
想知道数据治理项目中,数据主题域如何合理划分?数据标准及主数据标准如何制定?数仓分层模型如何合理规划?华为云DataArts+DWS助力企业数据治理项目一站式解决方案和应用实践告诉您答案!本期将从数据趋势、数据治理方案、数据治理规划及落地,案例分享四个方面来助力企业数据治理项目合理咨询规划及顺利实施。
去报名
热门标签