如何删除未选中的单元格(怎么只删除选中单元格 不删除整行)
780
2022-05-25
前言
在Atlas 200 DK上开发部署自己的模型,我觉得最为关键部分是模型的转换和对推理结果的后处理,做好了这两步,开发就成功了一大半,剩下的基本就是优化设计了。而模型转换后在Atlas 200 DK上需要自己创建模型推理引擎,完成数据的输入和推理结果的输出及解析。在这里,以行人检测的Demo为例,说一下自己对推理引擎创建的了解。
这里省略了如果模型转换失败,要进行修改的步骤,如果不幸遇到了这个问题,就要根据转换模型的报错,具体问题具体分析了,这里推荐一位大神发的关于模型转换遇到问题时解决办法的总结,该总结也被转发在了昇腾论坛里,推荐大家看看,绝对干货满满,特地奉上链接:https://bbs.huaweicloud.com/forum/thread-57916-1-1.html
行人检测Demo链接:https://bbs.huaweicloud.com/blogs/170452
代码介绍
推理引擎的创建,模型是关键。首先,需要得到转换好的.om模型,这一步十分重要,因为模型的创建中可能需要根据模型做一些设置。来看代码来理解吧。这里使用的是行人检测Demo里行人检测推理部分的代码,代码比单纯的讲解更能帮助人理解实现过程,我在代码中加了注释,可以根据注释理解。
# -*- coding: utf-8 -*- # !/usr/bin/python3 # 行人检测,基于开源数据集和ModelArts中YOLOv3_Resnet18算法 # 行人检测推理部分 # 引入ConstManager, 这是一个自行创建的.py文件,用来存放模型的路径 from ConstManager import * # 引入ModelManager,这也是一个.py文件,用来做模型推理创建的模板,按照这个模板,可以轻松创建推理引擎 import ModelManager # 引入hiai库,这是华为的一个库,用来将输入图片做向量化和推理,直接用就好 import hiai from hiai.nn_tensor_lib import DataType # numpy和cv2就不用说了吧,很著名的两个Python库 import numpy as np import cv2 # 引入utils,这是自行创建的一个.py文件,这里用来对推理结果解析,输入模型推理结果,返回我们想要的类别,框 # 的坐标等,这样做个封装,方便使用和移植,会使整体代码较为简洁 import utils # 引入Python库datetime,用来计算程序执行时间,这里没用的,是在测试的时候用的。 import datetime ''' Yolo3_Resnet18模型, 输入H = 352, W = 640,图像输入必须处理成numpy格式 bj_threshold 置信度阈值,取值范围为0~1。推理的时候,如果预测框的置信度小于该值,那么就会过滤掉, 默认为0.3 nms_threshold NMS阈值,取值范围为0~1。默认为0.4 ''' # 创建Yolo3_Resnet18Inference类 class Yolo3_Resnet18Inference(object): def __init__(self): # 由用户指定推理引擎的所在Graph的id号 self.graph_id = 1000 self.model_engine_id = 100 # 基于输入图片框坐标 self.boxList = [] # 置信度 self.confList = [] # 概率 self.scoresList = [] # 输入图片中行人部分 self.personList = [] # 实例化模型管理类 self.model = ModelManager.ModelManager() self.width = 640 self.height = 352 # 描述推理模型以及初始化Graph self.graph = None self._getgraph() def __del__(self): self.graph.destroy() def _getgraph(self): # 描述推理模型 inferenceModel = hiai.AIModelDescription('Yolo3_Resnet18', yolo3_resnet18_model_path) # 初始化Graph self.graph = self.model.CreateGraph(inferenceModel, self.graph_id, self.model_engine_id) if self.graph is None: print("Init Graph failed") ''' 1.定义输入Tensor的格式 2.调用推理接口 3.对一帧推理的正确结果保存到self.resultList中 4.根据返回值True和False判断是否推理成功 ''' def Inference(self, input_image): if isinstance(input_image, np.ndarray) is None: return False # Image PreProcess resized_image_opencv = cv2.resize(input_image, (self.width, self.height)) resized_image = resized_image_opencv inputImageTensor = hiai.NNTensor(resized_image) nntensorList = hiai.NNTensorList(inputImageTensor) # 调用推理接口 resultList = self.model.Inference(self.graph, nntensorList) if resultList is not None: bboxes = utils.get_result(resultList, self.width, self.height) # 获取检测结果 # print("bboxes:", bboxes) # Yolov_resnet18 Inference output_image = utils.draw_boxes(resized_image, bboxes) # 在图像上画框 output_image = cv2.resize(output_image, (input_image.shape[1], input_image.shape[0])) img_name = datetime.datetime.now().strftime("%Y-%m-%d%H-%M-%S-%f") cv2.imwrite('output_image/' + str(img_name) + '.jpg', output_image) else: print('no person in this frame.') return False return True # 程序执行的主要部分,调用前面定义的推理函数Inference完成推理和后处理 def dowork(src_img, yolo3_resnet18_app): res = yolo3_resnet18_app.Inference(src_img) if res is None: print("[ERROR] Please Check yolo3_resnet18_app.Inference!") return False else: print("[ERROR] Run Failed, dowork function failed.") return True
得益于ModelManager.py推理引擎创建模板的使用,我们可以很轻松创建一个推理引擎,而这个ModelManager.py这里并没有放出代码,可在本文开头的行人检测Demo的百度网盘链接中下载压缩包,解压后就能看到这个.py文件了。需要注意的是,如果要使用的话,需要在主函数先完成初始化工作,详情可参见Demo中的main.py,很简单的,就几行代码。
此外,模型创建需要指定Graph和engine的ID号,即告诉处理器,你具体想用的Engine,这里使用的graph_id = 1000, model_engine_id =100:
注意这里的graph_id应该是从1000开始,可以到1003吧,即可选为1000,1001,1002,1003,我试过到1003应该是没问题的,1004可能也可以。model_engine_id是从100开始,可以向后延伸,应该到104都可以吧,不过不建议使用这么多,ID号到103就可以了。
还有一点,不同ID的Graph中的Engine的ID互不干扰,可以相同。简单来说,Graph像是一个国家,而Engine是国家的国民,不同ID的Graph是不同的国家,那么他们国民的名字,也就是ID号即使重复也没什么关系。
那么问题来了,如果我想使用多个模型推理怎么办呢?很简单,有两种方法:
创建一个Graph,在里面创建多个Engine,用于模型推理。
创建多个Graph,在每个Graph里面创建一个Engine,用于模型推理。
个人建议,一个Graph里面不要创建太多用于推理的Engine,两个就差不多了,如果要用的模型较多,可以在创建一个Graph。
最后,说说Graph和Engine的关系吧。对于一个简单的单模型项目,一个Graph和一个模型推理Engine就足够了,比如这个Demo就是一个Graph和一个模型推理的Engine,也即是说一个Graph对应一个项目,但如果项目使用多个模型,比如4个模型,那我觉得创建两个Graph比较好,每个Graph里创建两个Engine,那么上面的代码就变成了四份,每份对应一个Engine。这里要注意下数据的传递,好像不同Graph之间数据传递比较慢,可根据具体的代码去调整Engine。
以上是我个人在使用Python实现Demo时,自己的一点感悟,可能有不对的地方,还请批评指正,博客中写的不完善或看不懂的地方,可以在下面评论或私信我哈,我看到会回复的。有时间,欢迎大家到昇腾论坛发帖提问或交流,一起打造昇腾良好的社区生态。
昇腾 AI
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。