-
ModelBox开发案例 - 使用YOLO v3做口罩检测本案例将使用YOLO v3模型,实现一个简单的口罩检测应用,最终效果如下所示: 本案例所需资源(代码、模型、测试数据等)已做成模板放到华为云上,查看和下载模板可以使用如下命令:Windows PC版本请使用solution.bat工具:PS ███\modelbox>: .\solution.bat -l ... Solutions name: mask_det_yolo3 ...结果中的mask_det_yolo3即为口罩检测模板,可使用如下命令下载模板:PS ███\modelbox>: .\solution.bat -s mask_det_yolo3 ...Linux开发板版本请使用solution.py脚本:rock@rock-3a:~/███/modelbox$ ./solution.py -l ... Solutions name: mask_det_yolo3 ...结果中的mask_det_yolo3即为口罩检测模板,可使用如下命令下载模板:rock@rock-3a:~/███/modelbox$ ./solution.py -s mask_det_yolo3 ...solution.bat/solution.py工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。如果对ModelBox AI应用开发还不熟悉,请先阅读ModelBox 端云协同AI开发套件(RK3568)上手指南,或者ModelBox 端云协同AI开发套件(博时特EC02)上手指南。模型准备本案例使用的是YOLOv3_ResNet18模型,在下载的资源包中,已经包含了转换好的rknn模型或者onnx模型,可以在对应的平台上直接使用。 原始模型是通过TensorFlow框架训练得到的,我们可以用AI Gallery中的物体检测YOLOv3_ResNet18算法和口罩检测小数据集,自行训练出该模型。 得到TensorFlow Frozen Graph格式的模型后,如果想体验rknn模型的转换过程,rknpu版本可参考RK1808模型转换验证案例,rknpu2版本可参考RK3568模型转换验证案例。应用开发打开VS Code,连接到ModelBox sdk所在目录或者远程开发板,开始进行口罩检测应用开发。下面以RK3568版本为例进行说明,其他版本与之类似。1)创建工程使用create.py创建mask_det工程(Windows PC版本请使用create.bat):rock@rock-3a:~/███/modelbox$ ./create.py -t server -n mask_det -s mask_det_yolo3 sdk version is modelbox-rk-aarch64 success: create mask_det in /home/rock/███/modelbox/workspace将会用口罩检测模板创建出一个mask_det工程。2)查看推理功能单元AI应用的核心是模型推理部分,mask_det工程的推理功能单元在工程目录下的model/mask_infer文件夹中,目录结构如下(以RK3568开发板版本为例): 其中yolo3_resnet18_mask_det_288x512-rknpu2.rknn是转换好的rknn模型,mask_infer.toml是该模型的ModelBox功能单元配置文件,其内容如下:# Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. [base] name = "mask_infer" # 功能单元名称 device = "rknpu" # 功能单元运行的设备类型 version = "1.0.0" # 功能单元版本号 type = "inference" # 功能单元类型,推理功能单元此处为固定值inference virtual_type = "rknpu" # 推理引擎类型,RK3399pro/RK1808设备为rknpu,RK3568设备为rknpu2 group_type = "Inference" # 功能单元分组信息, 推理功能单元默认为Inference is_input_contiguous = "false" # rk芯片推理时的固定属性 description = "yolo3 model for mask detection" # 功能单元的描述信息 entry = "./yolo3_resnet18_mask_det_288x512_rknpu.rknn" # 模型文件路径,默认在当前路径下 # 模型输入节点描述:yolo3模型有1个输入,uint8格式的图片数据 [input] [input.input1] name = "data" type = "uint8" device = "rknpu" # 输入数据位于哪种设备 # 模型输出节点描述:yolo3模型有3个输出,不同大小的float类型特征向量 [output] [output.output1] name = "yolo/output1" type = "float" [output.output2] name = "yolo/output2" type = "float" [output.output3] name = "yolo/output3" type = "float"可以看到该模型有3个输出节点,即YOLO v3模型输出的3个feature map,需要从中解码出检测框。3)其他逻辑功能单元后处理功能单元负责从模型推理结果中解码出检测框,在工程目录下的etc/flowunit/yolo3_post文件夹中: 解码过程的核心逻辑在yolo3_utils.py文件中,可以查阅YOLO v3模型细节阅读代码。画图功能单元在工程目录下的etc/flowunit/draw_mask_bbox文件夹中: 画图的核心逻辑在draw_mask_bbox.py文件的draw_mask_info函数中: def draw_mask_info(self, image, bboxes): '''在图中画出口罩佩戴信息''' thickness = 2 font_scale = 1 text_font = cv2.FONT_HERSHEY_SIMPLEX for bbox in bboxes: label_index = int(bbox[5]) # 以头肩部为处理对象 if self.labels[label_index] != 'head': continue x_min, y_min, x_max, y_max = bbox[0], bbox[1], bbox[2], bbox[3] # 根据头肩部找到匹配的人脸框 face_bbox = self.find_max_cover_bbox( bbox, bboxes, 'face', self.face_cover_ratio) if not face_bbox: # 没找到对应的人脸,输出'unknown' yellow = (255, 255, 0) cv2.rectangle(image, (x_min, y_min), (x_max, y_max), yellow, thickness) cv2.putText(image, 'unknown', (x_min, y_min-20), text_font, font_scale, yellow, thickness) continue # 根据人脸框找到匹配的口罩框 mask_bbox = self.find_max_cover_bbox( face_bbox, bboxes, 'mask', self.mask_cover_ratio) if not mask_bbox: # 没找到对应的口罩框,输出'no mask' red = (0, 0, 255) cv2.putText(image, 'no mask', (x_min, y_min-20), text_font, font_scale, red, thickness) cv2.rectangle(image, (x_min, y_min), (x_max, y_max), red, thickness) else: # 找到对应的口罩框,输出'has mask' green = (0, 255, 0) cv2.putText(image, 'has mask', (x_min, y_min-20), text_font, font_scale, green, thickness) cv2.rectangle(image, (x_min, y_min), (x_max, y_max), green, thickness) cv2.rectangle(image, (mask_bbox[0], mask_bbox[1]), (mask_bbox[2], mask_bbox[3]), green, thickness) return image可以看到,针对每个人,该模型会尝试检测出head(头肩部)、face和mask三个检测框。如果face检测框与mask检测框的重合度大于某个阈值,就判为佩戴口罩;否则,就判为没有佩戴口罩;如果没有检测到face检测框,就会显示Unknown,表示未知。4)查看流程图模型推理和配套的功能单元准备好后,我们就可以串联出流程图进行测试了,口罩检测工程的默认流程图为graph/mask_det.toml(以RK3568开发板版本为例):# Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. [driver] # 功能单元的扫描路径,包含在[]中,多个路径使用,分隔 # ${HILENS_APP_ROOT} 表示当前应用的实际路径 # ${HILENS_MB_SDK_PATH} 表示ModelBox核心库的实际路径 dir = [ "${HILENS_APP_ROOT}/etc/flowunit", "${HILENS_APP_ROOT}/etc/flowunit/cpp", "${HILENS_APP_ROOT}/model", "${HILENS_MB_SDK_PATH}/flowunit", ] skip-default = true [profile] # 通过配置profile和trace开关启用应用的性能统计 profile = false # 是否记录profile信息,每隔60s记录一次统计信息 trace = false # 是否记录trace信息,在任务执行过程中和结束时,输出统计信息 dir = "${HILENS_DATA_DIR}/mb_profile" # profile/trace信息的保存位置 [flow] desc = "mask detection example using yolo3 for local video or rtsp video stream" # 应用的简单描述 [graph] format = "graphviz" # 流程图的格式,当前仅支持graphviz graphconf = """digraph mask_det { node [shape=Mrecord] queue_size = 4 batch_size = 1 # 定义节点,即功能单元及其属性 input1[type=input, flowunit=input, device=cpu, deviceid=0] data_source_parser[type=flowunit, flowunit=data_source_parser, device=cpu, deviceid=0] video_demuxer[type=flowunit, flowunit=video_demuxer, device=cpu, deviceid=0] video_decoder[type=flowunit, flowunit=video_decoder, device=rknpu, deviceid=0, pix_fmt="bgr"] image_resize[type=flowunit, flowunit=resize, device=rknpu, deviceid=0, image_width=512, image_height=288] mask_detection[type=flowunit, flowunit=mask_infer, device=rknpu, deviceid=0] yolo3_post[type=flowunit, flowunit=yolo3_post, device=cpu, deviceid=0] draw_mask_bbox[type=flowunit, flowunit=draw_mask_bbox, device=cpu, deviceid=0] video_out[type=flowunit, flowunit=video_out, device=rknpu, deviceid=0] # 定义边,即功能间的数据传递关系 input1:input -> data_source_parser:in_data data_source_parser:out_video_url -> video_demuxer:in_video_url video_demuxer:out_video_packet -> video_decoder:in_video_packet video_decoder:out_video_frame -> image_resize:in_image image_resize:out_image -> mask_detection:data mask_detection:"yolo/output1" -> yolo3_post:in_feat3 mask_detection:"yolo/output2" -> yolo3_post:in_feat2 mask_detection:"yolo/output3" -> yolo3_post:in_feat1 video_decoder:out_video_frame -> draw_mask_bbox:in_image yolo3_post:out_data -> draw_mask_bbox:in_bbox draw_mask_bbox:out_image -> video_out:in_video_frame }"""该流程图对于某个视频流,经过视频解码、图像缩放、口罩检测推理、检测框后处理、画图等一系列操作后,将结果保存下来。口罩检测工程的任务配置文件bin/mock_task.toml中设置了输入输出源,内容为:# 任务输入配置,当前支持以下几种输入方式: # 1. rtsp摄像头或rtsp视频流:type="rtsp", url="rtsp://xxx.xxx" # 2. 设备自带摄像头或者USB摄像头:type="url",url="${摄像头编号}" (需配合local_camera功能单元使用) # 3. 本地视频文件:type="url",url="${视频文件路径}" (请使用${HILENS_APP_ROOT}宏,表示当前应用的实际路径) # 4. http服务:type="url", url="http://xxx.xxx"(指的是任务作为http服务启动,此处需填写对外暴露的http服务地址,需配合httpserver类的功能单元使用) [input] type = "url" # url = "0" url = "${HILENS_APP_ROOT}/data/mask_test.mp4" # 任务输出配置,当前支持以下几种输出方式: # 1. rtsp视频流:type="local", url="rtsp://xxx.xxx" # 2. 本地屏幕:type="local", url="0:xxx" (设备需要接显示器,系统需要带桌面) # 3. 本地视频文件:type="local",url="${视频文件路径}"(请使用${HILENS_APP_ROOT}宏,表示当前应用的实际路径) # 4. http服务:type="webhook", url="http://xxx.xxx"(指的是任务产生的数据上报给某个http服务,此处需填写上传的http服务地址) [output] type = "local" # url = "0:mask_det" # "rtsp://192.168.2.2:8554/outstream" url = "${HILENS_APP_ROOT}/hilens_data_dir/mask_test_result.mp4"测试视频为data/mask_test.mp4,该流程图使用这一视频进行口罩检测,检测结果绘制后保存为hilens_data_dir/mask_test_result.mp4文件。5)运行应用在mask_det工程路径下执行build_project.sh进行工程构建(以RK3568开发板版本为例):rock@rock-3a:~/███/modelbox/workspace/mask_det$ ./build_project.sh build success: you can run main.sh in ./bin folder rock@rock-3a:~/███/modelbox/workspace/mask_det$然后执行bin/main.sh(Windows PC版本请使用bin\main.bat)运行应用,运行结束后在hilens_data_dir目录下生成了mask_test_result.mp4文件,可以下载到PC端查看。
-
MindX SDK -- 工业指针型表计读数参考设计案例1 案例概述1.1 概要描述在本系统中,目的是基于MindX SDK,在华为云昇腾平台上,开发端到端工业指针型表计读数的参考设计,实现对传统机械式指针表计的检测与自动读数功能,达到功能要求。点击链接可以下载本项目到本地。注:本系统中只使用了两种类型的表盘数据参与训练和测试。我们通过预测的刻度根数来判断表盘类型,第一种表盘的刻度根数为50,第二种表盘的刻度根数为32。因此,目前系统只能实现这两种针表计的检测和自动读数功能。1.2 特性及适用场景在电力能源厂区需要定期监测表计读数,以保证设备正常运行及厂区安全。但厂区分布分散,人工巡检耗时长,无法实时监测表计,且部分工作环境危险导致人工巡检无法触达。针对上述问题,希望通过摄像头拍照后利用计算机智能读数的方式高效地完成此任务。注意事项:本系统中只使用了两种类型的表盘数据参与训练和测试。我们通过预测的刻度根数来判断表盘类型,第一种表盘的刻度根数为50,第二种表盘的刻度根数为32。因此,目前系统只能实现这两种针表计的检测和自动读数功能。本系统要求拍摄图片角度正常,尽可能清晰。如果拍摄图片角度不正常,导致图片模糊,则很难正确读出表数。本系统采用opencv进行图片处理,要求输入文件均为opencv可处理文件。1.3 模型介绍本项目主要使用了两个模型,分别是:用于目标检测的YOLOv5模型(PyTorch)和用于检测指针和刻度的语义分割模型DeepLabv3(pdmodel)。YOLOv5模型参考链接:cid:link_8DeepLabv3模型参考链接:cid:link_41.4 实现流程1、基础环境:Ascend 310、mxVision、Ascend-CANN-toolkit、Ascend Driver2、模型转换:目标检测模型: PyTorch模型转昇腾离线模型:yolov5.onnx --> yolov5.om语义分割模型: pdmodel模型转onnx模型:model.pdmodel --> DeepLabv3.onnx onnx模型转昇腾离线模型:DeepLabv3.onnx --> DeepLabv3.om3、业务流程编排与配置4、yolov5后处理开发5、mxpi_process3插件的后处理开发6、python推理流程代码开发:(1)YOLOv5的pipeline流程图如下: 图1. YOLOv5的pipeline流程图(2)DeepLabv3的pipeline流程图如下: 图2. DeepLabv3的pipeline流程图2 软件方案介绍2.1 项目方案架构介绍本系统识别的流程是:先将输入的图像送入流中解码和缩放大小,使用YOLOv5目标检测模型去检测图片中的表盘,结束流。将目标框裁剪下来,再送入流中解码和缩放大小,用DeepLabv3语义分割模型去得到工业表中的指针和刻度,对语义分割模型预测的结果进行读数后处理,找到指针指向的刻度,根据刻度的间隔和刻度根数计算表盘的读数。表2.1 系统方案中各模块功能:序号子系统功能描述1图像输入调用MindX SDK的appsrc输入图片2图像解码调用MindX SDK的mxpi_imagedecoder输入图片3图像放缩调用MindX SDK的mxpi_imageresize,放缩到1024*576大小4工业表检测调用MindX SDK的mxpi_tensorinfer,使用YOLOv5的检测模型,检测出图片中车辆5保存工业表的图像将YOLOv5检测到的工业表结果保存图片6图像输入调用MindX SDK的appsrc输入检测到的工业表7图像解码调用MindX SDK的mxpi_imagedecoder输入图片8图像放缩调用MindX SDK的mxpi_imageresize,放缩到512*512大小9指针刻度检测调用MindX SDK的mxpi_tensorinfer,使用DeepLabv3语义分割模型,检测图像中的指针与刻度10模型后处理调用MindX mxpi_semanticsegpostprocessor,得到语义分割的结果11读数后处理开发mxpi_process3插件,读出工业表的数字2.2 代码目录结构与说明本工程名称为工业指针型表计读数,工程目录如下图所示:├── build.sh ├── README.md ├── evaluate ├── deeplabv3_val #deeplabv3模型测试精度 ├── seg_evaluate.py ├── yolov5_val #yolov5模型测试精度 ├── det.py #1.使用om模型检测测试数据,将得到的结果保存成yolo格式的txt文件 ├── match.py #3.检测是否有的图像没有目标 ├── yolo2voc.py #2.将得到的检测结果yolo数据格式转换成voc格式 ├── images ├── README_img ├── DeepLabv3_pipeline.png ├── YOLOv5_pipeline.png ├── infer ├── det.py ├── main.py ├── seg.py ├── models ├── deeplabv3 ├── seg_aipp.cfg #deeplabv3的onnx模型转换成om模型的配置文件 ├── yolov5 ├── det_aipp.cfg #yolov5的onnx模型转换成om模型的配置文件 ├── pipeline #pipeline文件 ├── deeplabv3 ├── deeplabv3.cfg ├── deeplabv3.names ├── seg.pipeline ├── yolov5 ├── det.pipeline ├── plugins #开发读数处理插件代码 ├── process3 ├── build.sh ├── CMakeLists.txt ├── Myplugin.cpp ├── Myplugin.h ├── postprocess.cpp ├── postprocess.h3 开发环境准备3.1 环境依赖软件和版本环境依赖软件和版本如下表:软件名称版本ubuntu18.04.1 LTSMindX SDK2.0.4Python3.9.2CANN5.0.4numpy1.23.4opencv-python4.6.0MindX SDK开发套件部分可参考MindX SDK开发套件安装指导3.2 导入基础环境. /usr/local/Ascend/ascend-toolkit/set_env.sh . ${SDK安装路径}/mxVision/set_env.sh4 编译与运行示例步骤如下:步骤1 执行编译编译插件,在项目目录下执行如下命令cd ${MeterReader代码根目录}/plugins/process3 . build.sh步骤2 修改pipeline文件中的参数地址修改"${MeterReader代码根目录}/pipeline/yolov5/det.pipeline"第40行处文件的绝对路径,将pipeline中所需要用到的模型路径改为存放模型的绝对路径地址:40 "modelPath":"${MeterReader代码根目录}/models/yolov5/det.om"修改"${MeterReader代码根目录}/pipeline/deeplabv3/seg.pipeline"第30、38、39行处文件的绝对路径,将pipeline中所需要用到的模型路径、配置文件地址改为绝对路径地址:30 "modelPath":"${MeterReader代码根目录}/models/deeplabv3/seg.om" 38 "postProcessConfigPath":"${MeterReader代码根目录}/pipeline/deeplabv3/deeplabv3.cfg", 39 "labelPath":"${MeterReader代码根目录}/pipeline/deeplabv3/deeplabv3.names",步骤3 运行及输出结果总体运行。输入带有预测表盘的jpg图片,在指定输出目录下输出得到带有预测表盘计数的png图片。cd ${MeterReader代码根目录}/infer python main.py --ifile ${输入图片路径} --odir ${输出图片目录}执行结束后,可在命令行内得到yolo模型得到的表盘文件路径,以及通过后续模型得到的预测表盘度数。并可在设定的${输出图片路径}中查看带有预测表盘计数的图片结果。最后展示的结果图片上用矩形框框出了图片中的表计并且标出了预测的表盘读数。5 指标验证分别对yolo模型与deeplabv3模型进行精度测试。1、YOLOv5模型精度测试步骤一:执行以下命令创建所需要的文件目录cd ${MeterReader代码根目录}/evaluate/yolov5_val/ mkdir -p det_val_data/det_val_voc mkdir -p det_val_data/meter_det mkdir -p det_val_data/det_val_img mkdir -p det_val_data/det_sdk_txt mkdir -p det_val_data/det_sdk_voc步骤二:准备标签文件及推理图片下载YOLOv5表计检测数据集并解压到任意目录后,将数据集目录中"test"和"train"目录下的所有图片汇总拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/meter_det"目录下。我们提供了样例的模型验证集标签文件以供下载测试。完成下载并解压后,将"data/yolov5/det_val_voc"目录下的文件拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_val_voc"目录下。然后根据拷贝后目录下样例的txt标签文件名称(txt命名格式为:文件名.txt)在"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/meter_det"目录下找到对应名称的jpg图片并拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_val_img"目录下。步骤三:预处理数据集执行以下命令后,将在"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_sdk_txt"目录下生成当前"det.om"模型检测验证集数据的yolo格式结果,并以图片命名的txt格式保存:cd ${MeterReader代码根目录}/evaluate/yolov5_val python det.py再执行以下命令,将上述得到的yolo数据格式转换成voc数据格式,并保存至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_sdk_voc"目录下:python yolo2voc.py最后执行以下命令,检测验证集中的数据是否有无目标文件:python match.py注意事项:运行脚本之前需要把det_sdk_txt和det_sdk_voc文件夹下的文件清空。步骤四:精度推理登录并点击下载mAP-master.zip代码压缩包,上传服务器解压后,将代码包中的"main.py"脚本拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/"目录下,按照以下步骤修改部分代码:修改main.py第47、48、50行处文件路径47 GT_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_val_voc') 48 DR_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_sdk_voc') 49 # # if there are no images then no animation can be shown 50 IMG_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_val_img')修改main.py原第64行代码64 show_animation = False 65 if not args.no_animation:在main.py原第243行添加代码242 def draw_plot_func(dictionary, n_classes, window_title, plot_title, x_label, output_path, to_show, plot_color, true_p_bar): 243 to_show = False使用下面命令运行脚本,计算得到det.om在验证集上的mAP。python main.py经过测试,YOLOv5模型的mAP为100%。2、deeplabv3模型精度测试。执行以下命令,创建所需文件目录:cd ${MeterReader代码根目录}/evaluate/deeplabv3_val/ mkdir seg_val_img cd seg_val_img mkdir seg_test_img mkdir seg_test_img_groundtruth下载语义分割模型验证集voc格式数据,解压至"${MeterReader代码根录}/evaluate/deeplabv3_val/seg_val_img"目录下。然后执行以下命令拷贝数据:cp -r ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/meter_seg/meter_seg/images/val/. ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/seg_test_img/ cp -r ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/meter_seg/meter_seg/annotations/val/. ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/seg_test_img_groundtruth/采用Miou指标进行精度评价。使用下面命令运行脚本:cd ${MeterReader代码根目录}/evaluate/deeplabv3_val/ python seg_evaluate.py输出各个图的Miou指标,并求得平均值作为deeplabv3模型的精度指标。经测试,deeplabv3的模型的Miou为67%。6 常见问题6.1 模型转换问题问题描述当图像进入流后,输出到模型的图像格式为yuv,数据类型unit8,但是om模型的时候yolov5需要输入的图像格式为RGB。解决方案在转换模型时必须要在AIPP做色域转换,否则模型输入不正确。6.2 插件权限问题问题描述运行pipeline调用第三步的数值处理插件时报错,提示Check Owner permission failed: Current permission is 7, but required no greater than 6.解决方案将插件的权限调整为默认440(只读)即可chmod 440 "$MX_SDK_HOME/lib/plugins/libmxpi_sampleplugin.so"
-
请问这种报错要如何 Debug 呢
-
最全图像融合论文及代码整理 News [2022-07-29] 我们的综述论文《基于深度学习的图像融合方法综述》被《中国图象图形学报》正式接收![论文下载] Github项目地址:https://github.com/Linfeng-Tang/Image-Fusion (欢迎大家Start、 Fork、 Fellow一键三连哦~) 图像融合(Image Fusion) 多模图像融合(Multi-Modal Image Fusion) 红外和可见光图像融合(Infrared and visible image fusion) 医学图像融合(Medical image fusion) 数字摄影图像融合(Digital Photography Image Fusion) 多曝光图像融合(Multi-exposure image fusion) 多聚焦图像融合(Multi-focus image fusion) 遥感影像融合(Remote Sensing Image Fusion) 全色图像锐化(Pansharpening) 通用图像融合框架(General Image Fusion Framerwork) 综述(Survey) 数据集(Dataset) 评估指标(Evaluation Metric) 通用评估指标(General evaluation metric) 遥感影像融合评估指标 Citation 图像融合系列博客还有: 图像融合综述论文整理参见:图像融合综述论文整理 图像融合评估指标参见:红外和可见光图像融合评估指标 图像融合常用数据集整理参见:图像融合常用数据集整理 通用图像融合框架论文及代码整理参见:通用图像融合框架论文及代码整理 基于深度学习的红外和可见光图像融合论文及代码整理参见:基于深度学习的红外和可见光图像融合论文及代码整理 更加详细的红外和可见光图像融合代码参见:红外和可见光图像融合论文及代码整理 基于深度学习的多曝光图像融合论文及代码整理参见:基于深度学习的多曝光图像融合论文及代码整理 基于深度学习的多聚焦图像融合论文及代码整理参见:基于深度学习的多聚焦图像融合(Multi-focus Image Fusion)论文及代码整理 基于深度学习的全色图像锐化论文及代码整理参见:基于深度学习的全色图像锐化(Pansharpening)论文及代码整理 基于深度学习的医学图像融合论文及代码整理参见:基于深度学习的医学图像融合(Medical image fusion)论文及代码整理 彩色图像融合程序参见:彩色图像融合 SeAFusion:首个结合高级视觉任务的图像融合框架参见:SeAFusion:首个结合高级视觉任务的图像融合框架 多模图像融合(Multi-Modal Image Fusion) 红外和可见光图像融合(Infrared and visible image fusion) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 发表年份 DenseFuse DenseFuse: A Fusion Approach to Infrared and Visible Images Paper Code TIP AE 自监督 2019 FusionGAN FusionGAN: A generative adversarial network for infrared and visible image fusion Paper Code InfFus GAN 无监督 2019 DDcGAN Learning a Generative Model for Fusing Infrared and Visible Images via Conditional Generative Adversarial Network with Dual Discriminators Paper Code IJCAI GAN 无监督 2019 NestFuse NestFuse: An Infrared and Visible Image Fusion Architecture Based on Nest Connection and Spatial/Channel Attention Models Paper Code TIM AE 自监督 2020 DDcGAN DDcGAN: A dual-discriminator conditional generative adversarial network for multi-resolution image fusion Paper Code TIP GAN 无监督 2020 RFN-Nest RFN-Nest: An end-to-end residual fusion network for infrared and visible images Paper Code InfFus AE 自监督 2021 CSF Classification Saliency-Based Rule for Visible and Infrared Image Fusion Paper Code TCI AE 自监督 2021 DRF DRF: Disentangled Representation for Visible and Infrared Image Fusion Paper Code TIM AE 自监督 2021 SEDRFuse SEDRFuse: A Symmetric Encoder–Decoder With Residual Block Network for Infrared and Visible Image Fusion Paper Code TIM AE 自监督 2021 MFEIF Learning a Deep Multi-Scale Feature Ensemble and an Edge-Attention Guidance for Image Fusion Paper Code TCSVT AE 自监督 2021 Meta-Learning Different Input Resolutions and Arbitrary Output Resolution: A Meta Learning-Based Deep Framework for Infrared and Visible Image Fusion Paper TIP CNN 无监督 2021 RXDNFuse RXDNFuse: A aggregated residual dense network for infrared and visible image fusion Paper InfFus CNN 无监督 2021 STDFusionNet STDFusionNet: An Infrared and Visible Image Fusion Network Based on Salient Target Detection Paper Code TIM CNN 无监督 2021 D2LE A Bilevel Integrated Model With Data-Driven Layer Ensemble for Multi-Modality Image Fusion Paper TIP CNN 无监督 2021 HAF Searching a Hierarchically Aggregated Fusion Architecture for Fast Multi-Modality Image Fusion Paper Code ACM MM CNN 无监督 2021 SDDGAN Semantic-supervised Infrared and Visible Image Fusion via a Dual-discriminator Generative Adversarial Network Paper Code TMM GAN 无监督 2021 Detail-GAN Infrared and visible image fusion via detail preserving adversarial learning Paper Code InfFus GAN 无监督 2021 Perception-GAN Image fusion based on generative adversarial network consistent with perception Paper Code InfFus GAN 无监督 2021 GAN-FM GAN-FM: Infrared and Visible Image Fusion Using GAN With Full-Scale Skip Connection and Dual Markovian Discriminators Paper Code TCI GAN 无监督 2021 AttentionFGAN AttentionFGAN: Infrared and Visible Image Fusion Using Attention-Based Generative Adversarial Networks Paper TMM GAN 无监督 2021 GANMcC GANMcC: A Generative Adversarial Network With Multiclassification Constraints for Infrared and Visible Image Fusion Paper Code TIM GAN 无监督 2021 MgAN-Fuse Multigrained Attention Network for Infrared and Visible Image Fusion Paper TIM GAN 无监督 2021 TC-GAN Infrared and Visible Image Fusion via Texture Conditional Generative Adversarial Network Paper TCSVT GAN 无监督 2021 TarDAL Target-aware Dual Adversarial Learning and a Multi-scenario Multi-Modality Benchmark to Fuse Infrared and Visible for Object Detection Paper Code CVPR GAN 无监督 2022 RFNet RFNet: Unsupervised Network for Mutually Reinforcing Multi-modal Image Registration and Fusion Paper Code CVPR CNN 无监督 2022 SeAFusion Image fusion in the loop of high-level vision tasks: A semantic-aware real-time infrared and visible image fusion network Paper Code InfFus CNN 无监督 2022 PIAFusion PIAFusion: A progressive infrared and visible image fusion network based on illumination aware Paper Code InfFus CNN 无监督 2022 UMF-CMGR Unsupervised Misaligned Infrared and Visible Image Fusion via Cross-Modality Image Generation and Registration Paper Code IJCAI CNN 无监督 2022 医学图像融合(Medical image fusion) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 年份 CNN A medical image fusion method based on convolutional neural networks Paper ICIF CNN 无监督 2017 Zero-LMF Zero-Learning Fast Medical Image Fusion Paper Code ICIF CNN 无监督 2019 DDcGAN Learning a Generative Model for Fusing Infrared and Visible Images via Conditional Generative Adversarial Network with Dual Discriminators Paper Code IJCAI GAN 无监督 2019 GFPPC-GAN Green Fluorescent Protein and Phase-Contrast Image Fusion via Generative Adversarial Networks Paper CMMM GAN 无监督 2019 CCN-CP Multi-modality medical image fusion using convolutional neural network and contrast pyramid Paper Sensors CNN 无监督 2020 DDcGAN DDcGAN: A Dual-Discriminator Conditional Generative Adversarial Network for Multi-Resolution Image Fusion Paper Code TIP GAN 无监督 2020 MGMDcGAN Medical Image Fusion Using Multi-Generator Multi-Discriminator Conditional Generative Adversarial Network Paper Code Access GAN 无监督 2020 D2LE A Bilevel Integrated Model With Data-Driven Layer Ensemble for Multi-Modality Image Fusion Paper TIP CNN 无监督 2021 HAF Searching a Hierarchically Aggregated Fusion Architecture for Fast Multi-Modality Image Fusion Paper Code ACM MM CNN 无监督 2021 EMFusion EMFusion: An unsupervised enhanced medical image fusion network Paper Code InfFus CNN 无监督 2021 DPCN-Fusion Green Fluorescent Protein and Phase Contrast Image Fusion Via Detail Preserving Cross Network Paper Code TCI CNN 无监督 2021 MSPRN A multiscale residual pyramid attention network for medical image fusion Paper Code BSPC CNN 无监督 2021 DCGAN Medical image fusion method based on dense block and deep convolutional generative adversarial network Paper NCA GAN 无监督 2021 数字摄影图像融合(Digital Photography Image Fusion) 多曝光图像融合(Multi-exposure image fusion) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 年份 DeepFuse DeepFuse: A Deep Unsupervised Approach for Exposure Fusion with Extreme Exposure Image Pairs Paper Code ICCV CNN 无监督 2017 CNN Multi-exposure fusion with CNN features Paper Code ICIP CNN 无监督 2018 MEF-Net Deep guided learning for fast multi-exposure image fusion Paper Code TIP CNN 无监督 2020 ICEN Multi-exposure high dynamic range imaging with informative content enhanced network Paper NC CNN 无监督 2020 MEF-GAN MEF-GAN: Multi-Exposure Image Fusion via Generative Adversarial Networks Paper Code TIP GAN 无监督 2020 CF-Net Deep coupled feedback network for joint exposure fusion and image super-resolutions Paper Code TIP CNN 无监督 2021 UMEF Deep unsupervised learning based on color un-referenced loss functions for multi-exposure image fusion Paper Code InFus CNN 无监督 2021 PA-AGN Two exposure fusion using prior-aware generative adversarial network Paper TMM GAN 无监督 2021 AGAL Attention-guided Global-local Adversarial Learning for Detail-preserving Multi-exposure Image Fusion Paper Code TCSVT GAN 无监督 2022 GANFuse GANFuse: a novel multi-exposure image fusion method based on generative adversarial networks Paper NCAA GAN 无监督 2021 DRLF Automatic Intermediate Generation With Deep Reinforcement Learning for Robust Two-Exposure Image Fusion Paper TNNLS CNN 无监督 2021 Trans-MEF TransMEF: A Transformer-Based Multi-Exposure Image Fusion Framework using Self-Supervised Multi-Task Learning Paper Code AAAI AE 自监督 2022 DPE-MEF Multi-exposure image fusion via deep perceptual enhancement Paper Code InFus CNN 无监督 2022 多聚焦图像融合(Multi-focus image fusion) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 年份 CNN Multi-focus image fusion with a deep convolutional neural network Paper Code InFus CNN 有监督 2017 ECNN Ensemble of CNN for multi-focus image fusion Paper Code InFus CNN 有监督 2019 MLFCNN Multilevel features convolutional neural network for multifocus image fusion Paper TCI CNN 有监督 2019 DRPL DRPL: Deep Regression Pair Learning for Multi-Focus Image Fusion Paper Code TIP CNN 有监督 2020 MMF-Net An α-Matte Boundary Defocus Model-Based Cascaded Network for Multi-Focus Image Fusion Paper Code TCI CNN 有监督 2020 MFF-SSIM Towards Reducing Severe Defocus Spread Effects for Multi-Focus Image Fusion via an Optimization Based Strategy Paper Code Sensors CNN 无监督 2020 MFNet Structural Similarity Loss for Learning to Fuse Multi-Focus Images Paper TIP CNN 有监督 2021 GEU-Net Global-Feature Encoding U-Net (GEU-Net) for Multi-Focus Image Fusion [GEU-Net Paper Code TCI CNN 自监督 2021 DTMNet DTMNet: A Discrete Tchebichef Moments-Based Deep Neural Network for Multi-Focus Image Fusion Paper TMM CNN 无监督 2021 SMFuse SMFuse: Multi-Focus Image Fusion Via Self-Supervised Mask-Optimization Paper Code NCA CNN 无监督 2021 ACGAN A generative adversarial network with adaptive constraints for multi-focus image fusion Paper Code ICCV GAN 有监督 2021 FuseGAN Learning to fuse multi-focus image via conditional generative adversarial network Paper TIP GAN 有监督 2020 D2FMIF Depth-Distilled Multi-focus Image Fusion Paper TMM CNN 有监督 2019 SESF-Fuse SESF-Fuse: an unsupervised deep model for multi-focus image fusion Paper Code NCAA CNN 有监督 2020 MFF-GAN MFF-GAN: An unsupervised generative adversarial network with adaptive and gradient joint constraints for multi-focus image fusion Paper Code InFus GAN 无监督 2021 MFIF-GAN MFIF-GAN: A new generative adversarial network for multi-focus image fusion Paper Code SPIC GAN 有监督 2021 遥感影像融合(Remote Sensing Image Fusion) 全色图像锐化(Pansharpening) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 年份 PNN Pansharpening by Convolutional Neural Networks Paper Code RS CNN 有监督 2016 PanNet PanNet: A deep network architecture for pan-sharpening Paper Code PanNet CNN 有监督 2017 TFNet Remote sensing image fusion based on two-stream fusion network Paper Code TFNet CNN 有监督 2020 BKL Unsupervised Blur Kernel Learning for Pansharpening Paper IGARSS CNN 无监督 2020 Pan-GAN Pan-GAN: An unsupervised pan-sharpening method for remote sensing image fusion Paper Code InFus GAN 无监督 2020 UCNN Pansharpening via Unsupervised Convolutional Neural Networks Paper JSTARS CNN 无监督 2020 UPSNet UPSNet: Unsupervised Pan-Sharpening Network With Registration Learning Between Panchromatic and Multi-Spectral Images Paper ACCESS CNN 无监督 2020 GPPNN Deep Gradient Projection Networks for Pan-sharpening Paper Code CVPR CNN 有监督 2021 GTP-PNet GTP-PNet: A residual learning network based on gradient transformation prior for pansharpening Paper Code ISPRS CNN 有监督 2021 HMCNN Pan-Sharpening Via High-Pass Modification Convolutional Neural Network Paper Code ICIP CNN 有监督 2021 SDPNet SDPNet: A Deep Network for Pan-Sharpening With Enhanced Information Representation Paper Code TGRS CNN 有监督 2021 SIPSA-Net SIPSA-Net: Shift-Invariant Pan Sharpening with Moving Object Alignment for Satellite Imagery Paper Code CVPR CNN 有监督 2021 SRPPNN Super-resolution-guided progressive pansharpening based on a deep convolutional neural network Paper Code TGRS CNN 有监督 2021 PSGAN PSGAN: A generative adversarial network for remote sensing image pan-sharpening Paper Code TGRS GAN 有监督 2021 MDCNN MDCNN: multispectral pansharpening based on a multiscale dilated convolutional neural network Paper JRS CNN 有监督 2021 LDP-Net LDP-Net: An Unsupervised Pansharpening Network Based on Learnable Degradation Processes Paper Code Arxiv CNN 无监督 2021 DIGAN Pansharpening approach via two-stream detail injection based on relativistic generative adversarial networks Paper ESA GAN 有监督 2022 DPFN A Dual-Path Fusion Network for Pan-Sharpening Paper Code TGRS CNN 有监督 2022 MSGAN An Unsupervised Multi-scale Generative Adversarial Network for Remote Sensing Image Pan-Sharpening Paper ICMM GAN 无监督 2022 UCGAN Unsupervised Cycle-Consistent Generative Adversarial Networks for Pan Sharpening Paper Code TGRS GAN 无监督 2022 通用图像融合框架(General Image Fusion Framerwork) 方法 标题 论文 代码 发表期刊或会议 基础框架 监督范式 年份 IFCNN IFCNN: A general image fusion framework based on convolutional neural network Paper Code InFus CNN 有监督 2020 FusionDN FusionDN: A Unified Densely Connected Network for Image Fusion Paper Code AAAI CNN 无监督 2020 PMGI Rethinking the Image Fusion: A Fast Unified Image Fusion Network based on Proportional Maintenance of Gradient and Intensity Paper Code AAAI CNN 无监督 2020 CU-Net Deep Convolutional Neural Network for Multi-Modal Image Restoration and Fusion Paper Code TPAMI CNN 有监督 2021 SDNet SDNet: A Versatile Squeeze-and-Decomposition Network for Real-Time Image Fusion Paper Code IJCV CNN 无监督 2021 DIF-Net Unsupervised Deep Image Fusion With Structure Tensor Representations Paper Code TIP CNN 无监督 2021 IFSepR IFSepR: A general framework for image fusion based on separate representation learning Paper TMM AE 自监督 2021 MTOE Multiple Task-Oriented Encoders for Unified Image Fusion Paper ICME CNN 无监督 2021 U2Fusion U2Fusion: A Unified Unsupervised Image Fusion Network Paper Code TPAMI CNN 无监督 2022 SwinFusion SwinFusion: Cross-domain Long-range Learning for General Image Fusion via Swin Transformer Paper Code JAS Transformer 无监督 2022 综述(Survey) 标题 论文 代码 发表期刊或会议 年份 A review of remote sensing image fusion methods Paper InFus 2016 Pixel-level image fusion: A survey of the state of the art Paper InFus 2017 Deep learning for pixel-level image fusion: Recent advances and future prospects Paper InFus 2018 Infrared and visible image fusion methods and applications: A survey Paper InFus 2019 Multi-focu image fusion: A Survey of the state of the art Paper InFus 2020 Image fusion meets deep learning: A survey and perspective Paper InFus 2021 Deep Learning-based Multi-focus Image Fusion: A Survey and A Comparative Study Paper Code TPAMI 2021 Benchmarking and comparing multi-exposure image fusion algorithms Paper Code InFus 2021 数据集(Dataset) 融合场景 数据集 下载链接 红外和可见光图像融合 TNO https://figshare.com/articles/dataset/TNO_Image_Fusion_Dataset/1008029 INO https://www.ino.ca/en/technologies/video-analytics-dataset/videos/ RoadScene https://github.com/hanna-xu/RoadScene MSRS https://github.com/Linfeng-Tang/MSRS LLVIP https://bupt-ai-cz.github.io/LLVIP/ M3FD https://github.com/JinyuanLiu-CV/TarDAL 医学图像融合 Harvard http://www.med.harvard.edu/AANLIB/home.html 多曝光图像融合 MEF https://github.com/csjcai/SICE MEFB https://github.com/xingchenzhang/MEFB 多聚焦图像融合 Lytro https://mansournejati.ece.iut.ac.ir/content/lytro-multi-focus-dataset MFI-WHU https://github.com/HaoZhang1018/MFI-WHU MFFW https://www.semanticscholar.org/paper/MFFW:-A-new-dataset-for-multi-focus-image-fusion-Xu-Wei/4c0658f338849284ee4251a69b3c323908e62b45 全色图像锐化 GaoFen https://directory.eoportal.org/web/eoportal/satellite-missions/g WorldView https://worldview.earthdata.nasa.gov/ GeoEye https://earth.esa.int/eogateway/missions/geoeye-1 QuickBird https://www.satimagingcorp.com/satellite-sensors/quickbird/ 评估指标(Evaluation Metric) 通用评估指标(General evaluation metric) 通用评估指标位于:https://github.com/Linfeng-Tang/Image-Fusion/tree/main/General%20Evaluation%20Metric or https://github.com/Linfeng-Tang/Evaluation-for-Image-Fusion 遥感影像融合评估指标(Evaluation metric for pansharpening) 如果有任何问题请联系:2458707749 ———————————————— 版权声明:本文为CSDN博主「Timer-419」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/fovever_/article/details/124650534
-
如题,我是用的yolov5s训练的可见光模型,同一个模型pyACL推理耗时330ms单张,而利用mxMamufacture跑只需要40ms左右,pyACL这个表现算正常吗?怎样才能查看pyACL有没有调用华为的NPU?
-
MindX SDK -- FCOS目标检测1 案例概述1.1 概要描述本开发项目演示FCOS模型实现目标检测。本系统基于mxVision SDK进行开发,以昇腾Atlas300卡为主要的硬件平台,主要应用于在CPU上实现实时目标检测。待检测的图片中物体不能被遮挡太严重,并且物体要完全出现在图片中。图片亮度不能过低。输入一张图片,最后会输出图片中能检测到的物体。项目主要流程为:1.环境搭建; 2.模型转换; 3.生成后处理插件; 4.进行精度、性能对比。1.2 代码地址:这个项目的代码地址为:contrib/FCOS · 吴镇/mindxsdk-referenceapps - 码云 - 开源中国 (gitee.com)1.3 模型介绍这个项目使用的模型为FCOS目标检测模型,这个模型的论文地址为https://arxiv.org/abs/1904.01355,相应的代码地址为https://github.com/tianzhi0549/FCOS/。FCOS是一个基于FCN(权卷积神经网络用于目标检测),这是一个无锚点检测算法,并且引入了Center-ness layer。FCOS通过预测一个四维向量$(l,t,r,b)$,来标识图片中识别出来的目标框位置。这个算法相对于有锚点的模型省去了很多计算的时间,加快了计算的速度。1.4 实现流程业务流程介绍:传入待检测的图片到FCOS目录下;通过mmcv库对图片进行预处理;放缩后的图片输入模型推理插件mxpi_tensorinfer进行处理;将经过模型推理输出时候的张量数据流输入到mxpi_objectpostprocessor中,对FCOS目标检测模型推理输出的张量进行后处理;处理完毕之后将数据传入mxpi_dataserialize0插件中,将stream结果组装成json字符串输出。最后将得到的目标框和类别信息写在图片上。业务流程图:2 软件方案介绍2.1 技术原理这个算法是一个anchor-free模型,这个模型不需要anchor。一般来说anchor-free模型通过检测关键点来直接预测边界框。FCOS属于anchor-free,但是却不是基于关键点检测的方法,严格来看其更接近基于anchor-based的方法,但是不需要anchor并加上特殊的设计却能够实现更好的效果。这个算法的运作过程如下:对于特征图上的每一个位置$(x,y)$,如果其落在人格GT的中心区域则认为这个位置是正样本,并且负责预测这个GT。2.2 项目方案架构介绍序号子系统功能描述1图片输入传入图片,修改图片的大小和格式为符合模型要求的格式2图片解码用于对图片进行解码3图像放缩通过mxpi_imageresize插件对图片进行放缩,达到模型传入图片的格式要求4模型推理将已经处理好的图片传入到mxpi_tensorinfer中,使用目标检测模型FCOS进行推理,得到推理的张量数据流5模型后处理将模型推理得到的张量数据流传入mxpi_objectpostprocessor中进行张量后处理。对模型输出的目标框进行去重,排序和筛选等工作。6组装字符串stream结果组装成json字符串输出。3 开发环境准备3.1 环境依赖说明推荐系统为ubuntu 18.04,环境软件和版本如下:软件名称版本说明获取方式MindX SDK2.0.4mxVision软件包点击打开链接ubuntu18.04操作系统请上ubuntu官网获取Ascend-CANN-toolkit5.0.4Ascend-cann-toolkit开发套件包点击打开链接3.2 环境搭建3.2.1 依赖安装项目运行过程中涉及到的第三方软件依赖如下表所示:软件名称版本说明使用教程mmdetection2.25.0用于实现模型精度评估[点击打开链接](GitHub - open-mmlab/mmdetection: OpenMMLab Detection Toolbox and Benchmark)mmcv1.2.4用于实现图片前处理点击打开链接这个软件主要是用来实现对于图片格式的转换。3.2.2 工程创建1.设置环境变量:. /usr/local/Ascend/ascend-toolkit/set_env.sh . ${SDK安装路径}/mxVision/set_env.sh复制2。转换模型:本次使用的模型威威FCOS模型,这个模型的onnx模型可以直接下载,然后利用模型转化你工具ATC将onnx模型转换成为om。模型,模型转换的相关工具介绍参考链接:cid:link_2模型转换步骤如下:首先设置环境变量:export install_path=/usr/local/Ascend/ascend-toolkit/latest export PATH=${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH export PYTHONPATH=${install_path}/atc/python/site-packages:${install_path}/atc/python/site-packages/auto_tune.egg/auto_tune:${install_path}/atc/python/site-packages/schedule_search.egg export LD_LIBRARY_PATH=${install_path}/atc/lib64:$LD_LIBRARY_PATH export ASCEND_OPP_PATH=${install_path}/opp复制进入models文件夹目录下进行模型转换,转换的代码如下:atc --model=fcos.onnx --framework=5 --soc_version=Ascend310 --input_format=NCHW --input_shape="input:1,3,800,1333" --output=fcos_om --precision_mode=allow_fp32_to_fp16复制4 编译与运行步骤1:设置相应的环境变量:. /usr/local/Ascend/ascend-toolkit/set_env.sh . ${SDK安装路径}/mxVision/set_env.sh复制步骤2 :将转换的模型移动到moels文件夹中。步骤3 :修改main.py中的检测图片路径为自己的图片路径:IMAGENAME = '{image path}' # create detection object if os.path.exists(IMAGENAME) != 1: print("The test image does not exist.")复制步骤4 :运行完毕之后会生成带有目标框、类别和置信度的图片,并且该图片保存在FCOS文件夹下。* 5 指标验证5.1 精度测试1.安装python COCO测评工具。执行命令:pip3 install pycocotools复制2.下载COCO VAL 2017数据集和标注文件,下载链接:[cid:link_4 /contrib/EfficientDet/data.zip,](cid:link_4 /contrib/EfficientDet/data.zip,)在python目录下创建dataset目录,将数据集压缩文件和标注数据压缩文件都解压至 python/dataset 目录下。再次创建一个文件夹,在FCOS目录下。确保解压后的 python 目录结构为:|- model | |- aipp_FCOS.aippconfig //模型转换配置文件 | |- fcos.onnx //onnx模型 | |_ Fcos_tf_bs.cfg |- pipeline | |_ FCOSdetection.pipeline |- plugin | |_FCOSPostprocess | |- CMakeLists.txt | |- FCOSDetectionPostProcess.cpp | |- FCOSDetectionPostProcess.h | |_ build.sh |- binresult |- dataset | |- annotations | | |_ instances_val2017.json | |_ val2017 | |-000000581615.jpg | |-000000581781.jpg | |_other-images |- build.sh |- evaluate1.py |- evaluate2.py |- main.py |_ run.sh复制3.从evaluate1.py中找到使用的pipeline 文件路径,将其改为指定的路径,然后执行命令:python3 evaluate1.py --pipeline=pipeline/FCOSdetectiontest.pipeline --output=val2017_detection_result_d0.json复制命令执行完毕之后,会在binresult文件夹,生成模型输出的目标框、置信度等信息。4.然后在同级目录下执行命令:python3 evaluate2.py复制5.命令执行完毕后输出COCO格式的测评结果,输出结果如下:上图中第一行可以看到,这个模型在COCO VAL 2017数据集上,IOU阈值为0.50:0.05:0.95时的精确度为0.347。这个数据与原模型的推理精度误差范围在0.01内。 6 常见问题6.1 模型路径配置问题:问题描述:检测过程中用到的模型以及模型后处理插件需配置路径属性。后处理插件以及模型推理插件配置例子:// 模型推理插件 "mxpi_tensorinfer0": { "props": { "dataSource": "mxpi_imageresize0", "modelPath": "${模型路径}/fcos_bs1.om" }, "factory": "mxpi_tensorinfer", "next": "mxpi_objectpostprocessor0" }, // 模型后处理插件 "mxpi_objectpostprocessor0":{ "props": { "dataSource" : "mxpi_tensorinfer0", "postProcessConfigPath": "./models/Fcos_tf_bs.cfg", "postProcessLibPath": "${MX_SDK_HOME}/lib/modelpostprocessors/libFCOSDetectionPostProcess.so" }, "factory": "mxpi_objectpostprocessor", "next": "mxpi_dataserialize0" },复制6.2 在main.py中图片路径:在传入待检测图片时候需要注意其在main.py中的路径。IMAGENAME = '{image path}' # create detection object if os.path.exists(IMAGENAME) != 1: print("The test image does not exist.")
-
sdk版本:2.0.4CANN:5.0.4
-
目录写在最前面ResNet18简介工具简介MindX SDK简介MindStudio环境搭建与配置MindStudio安装(Windows版本)SSH连接MindX SDK安装推理开发运行流程业务开发Python版本开发新建一个目录代码目录结构模型转换pipeline文件编排main.py文件编写代码运行C++版本开发新建一个项目代码目录结构模型转换(或者不转换)业务代码书写(修改)项目编译代码运行可参考的代码FAQ模型运行报错?如果想换个数据集怎么办?Python找不到模型路径?C++找不到模型路径?No Python interpreter configured for the module?SDK版本获取失败?结语1. 写在最前面这是一篇基于昇腾众智“ResNet18 for pytorch”代码的MindX SDK应用开发经验帖。原始项目代码可以从Ascend/ModelZoo-PyTorch - Gitee.com仓库中找到,根据原始项目代码,我们可以在MindStudio上快速实现一个ImageNet2012数据集1000分类应用的开发。整个过程中,MindStudio昇腾论坛上的教程基于MindStudio的MindX SDK应用开发全流程MindStudio昇腾_华为云论坛 (huaweicloud.com)也提供了很大的帮助。2. ResNet18简介ResNet是ImageNet竞赛中分类问题效果较好的网络,它引入了残差学习的概念,通过增加直连通道来保护信息的完整性,解决信息丢失、梯度消失、梯度爆炸等问题,让很深的网络也得以训练。ResNet有不同的网络层数,常用的有18-layer、34-layer、50-layer、101-layer、152-layer。ResNet18的含义是指网络中有18-layer。参考论文:He K, Zhang X, Ren S, et al. Deep residual learning for image recognition[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2016: 770-778.3. 工具简介3.1. MindX SDK介绍MindX SDK是华为昇腾AI处理器加速的AI软件开发套件(SDK), 提供了大量丰富的API,可以快速完成AI应用的开发3.2. MindStudioMindStudio提供了一个AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助开发者在一个工具上就能高效便捷地完成AI应用开发MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能官网地址:MindStudio-昇腾社区 (hiascend.com)4. 环境搭建与配置因为我使用的Windows系统环境,所以这里提供Windows环境下MindStdio环境搭建和配置的全流程,其它系统可以查看安装方案-安装指南-MindStudio-文档首页-昇腾社区 (hiascend.com)4.1. MindStudio 安装(Windows版本)安装前的说明MindStudio可以单独安装在Windows上。在安装MindStudio前需要在Linux服务器上安装部署好Ascend-cann-toolkit开发套件包,之后在Windows上安装MindStudio,安装完成后通过配置远程连接的方式建立MindStudio所在的Windows服务器与Ascend-cann-toolkit开发套件包所在的Linux服务器的连接,实现全流程开发功能。我所采用的是windows共部署的方法2. 下载安装MindStudio前往MindStudio下载-昇腾社区 (hiascend.com)页面进行MindStudio软件包的下载,并且参照安装MindStudio-安装操作(Windows)完成MindStudio的安装。4.2. SSH连接在进行共部署之前,先确认SSH服务器连接成功按照上面图中所示,依次配置之后,点击Test Connection,显示下图就表示连接成功。4.3. MindX SDK安装远端环境MindX SDK安装Windows 场景下基于 MindStuido 的 SDK 应用开发,请先确保远端环境上 MindX SDK 软件包已安装完成,安装方式请参见《mxManufacture 用户指南》和 《mxVision 用户指南》的“使用命令行方式开发”>“安装 MindX SDK 开发套件” 章节。本地 CANN 安装①:在 Windows 本地打开 MindStudio,点击 Customize > Allsettings…,如下图所示:②:进入设置页面,点击 Appearance & Behavior > System Settings > CANN 进入 CANN 管理界面。完成后的状态如下图所示:3. 本地 MindX SDK安装与步骤 2 开始一致,进入设置页面,点击 Appearance & Behavior > System Settings > MindX SDK 进入 MindX SDK 管理界面。界面中 MindX SDK Location 为软件包的默认安装路径,默认安装路径为“C:\Users\用户名\Ascend\mindx_sdk”。 单击 Install SDK 进入 Installation settings 界面。参数说明Remote Connection远程连接的用户及 IPRemote CANN Location远端环境上 CANN 开发套件包的路 径,请配置到版本号一级Remote SDK Location远端环境上 SDK 的路径,请配置到 版本号一级。IDE 将同步该层级下的 include、opensource、python、 samples 文件夹到本地 Windows 环境Local SDK Location同步远端环境上 SDK 文件夹到本地 的路径。默认安装路径为“C:\Users\ 用户名\Ascend\mindx_sdk”5. 推理开发运行流程使用 MindStudio 开发和运行推理业务步骤如下:(1) 确定业务流程:根据业务功能如目标检测、图像分类、属性识别等,将 业务流程进行模块化。(2) 寻找合适插件:根据已有 SDK 插件的功能描述和规格限制来匹配业务功 能,当 SDK 提供的插件无法满足功能需求时,用户可以开发自定义插件。(3) 准备推理模型文件与数据:准备输入图片和下载模型,使用 Model Convertor 模型转换工具将模型转换为 om 格式。(4) 流程编排:以可视化的方式,开发数据流图,生成 pipeline 文件供应用框 架使用,配置文件以 json 格式编写,必须指定业务流名称、元件名称和 插件名称,并根据需要,补充元件属性和下游元件名称信息。(5) 业务集成:编写 C++程序或 Python 程序,调用业务流管理的 API ( MxStreamManager ), 先 进 行 初 始 化 , 再 加 载 业 务 流 配 置 文 件 (*.pipeline),然后根据 stream 配置文件中的 StreamName 往指定 Stream 获取输出数据,最后销毁 Stream。(6) 编译与运行应用:若新建的工程为 Python 版本的应用工程,不需要执行 编译应用工程,配置 Python 环境后,即可在远端服务器运行;若新建工 程为 C++版本的应用工程,则需要进行远端编译,远端编译时,会对工 程文件夹进行目录拷贝到远端连接的环境,编译成功后即可运行。6. 业务开发业务开发将按照python版和C++版分别进行介绍6.1.Python版本开发6.1.1 新建一个项目首先创建一个项目,选择一个自己喜欢的位置,比如图中所示,将在D:\Codes\python\Ascend\MyApp位置下创建自己的项目。选择好了后,点击下一步选择MindX SDK Project(Python)如图所示,被圈出来的4个项目,上面两个是空模板,在这里面创建我们自己的工程项目,因为我们要创建Python版的应用,所以选箭头指的这个;下面两个是官方给出的样例项目,如果对目录结构和应该写哪些代码不太熟悉的话,也可以创建一个样例项目先学习一下。选择完成后,点击Finish完成项目的创建6.1.2 代码目录结构Python版本的SDK项目大概有哪些文件呢?我们其实可以先打开一个官方样例项目先看看左边是我们自己创建的项目,右边是官方样例项目,对比之下我们可以发现,右边的样例项目主要有models(用于存储模型文件)、pipeline(流程编排文件)、python(项目python代码)和streamserver(实际开发中没用上)。PS: 其实也不一定要按照这个目录结构存放代码,只是这样结构更加清晰一些。我的工程目录文件是这样其中data用来存放数据图片6.1.3 模型转换下载模型首先我们先在ModelZoo-昇腾社区 (hiascend.com)中下载ResNet18模型和代码选Pytorch版分别下载模型脚本和模型其中模型脚本在“pipeline文件编排”和“main.py文件编写”章节得到应用解压后,我们只要这个onnx模型,同时,我们将names标签数据也一起放进models文件夹模型转换点击这个工具,进入模型转换界面选择待转换的模型路径选好后点一下任意一个位置,MindStudio会进入模型解析状态等待模型解析完成后,可以修改输出的模型名字,或者点击下一步点击Finish,开始转换转换完成稍等片刻,出现这个就表明转换完成如上图所示,在显示的路径中可以找到转化好的文件我们将om文件移动到models文件夹中,就可以进行接下去的步骤了6.1.4 pipeline文件编排pipeline文件编排是python版SDK最主要的推理开发步骤作为一个图片分类任务,主要包括以下几个步骤:初始化 → 图片数据传送 → 图片预处理 → 图片分类 → 序列化 → 结果传回由于ResNet18模型采用的是PIL库进行图片预处理,而非opencv,因此我们不在pipeline中进行图片预处理步骤(包括图片解码、缩放、裁剪),而是通过在main.py文件中进行图片预处理,再将结果传给推理业务因此pipeline流程编排为以下几个步骤初始化 → 获取图片数据 → 图片分类 → 序列化 → 结果传回可视化结果如下图所示:实际上,我们可以通过对之前下载好的代码文件中已有的pipeline进行简单修改,就可以完成我们自己的pipeline文件编排在下载好的ResNet18_for_PyTorch_{$version}__code中,路径./infer/sdk/data/config下可以找到resnet18.cfg和resnet8.pipeline两个文件,将这两个文件分别移动到models目录和pipeline目录下,如下图所示:对resnet18.pipeline进行参数修改我个人比较喜欢文本编辑的方式修改,如下图所示修改完成后,就可以进行main.py文件的编写了,离成功运行越来越近了!6.1.5 main.py文件编写根据pipeline文件编排中的说明,我们在main.py中需要完成3件事——对图片进行预处理+将预处理好的结果传给推理业务+获取推理结果实际上,我们依旧可以参考下载的代码文件中./infer/sdk/main.py文件中的做法,稍作修改就可以(1) 图片预处理主要用到resize、center_crop、preprocess和gen_protobuf(图片编码为推理业务需要的字节流)四个函数参照下载代码中的main.py文件,很容易就能得到这四个函数# resize and cropdef resize(img, size, interpolation=Image.BILINEAR): return img.resize(size[::-1], interpolation)def center_crop(img, out_height, out_width): height, width, _ = img.shape left = int((width - out_width) / 2) right = int((width + out_width) / 2) top = int((height - out_height) / 2) bottom = int((height + out_height) / 2) img = img[top:bottom, left:right] return img# preprocessor调用上面的两个函数进行图片缩放裁剪处理def preprocess(in_file): mean = [0.485, 0.456, 0.406] std = [0.229, 0.224, 0.225] img = Image.open(in_file).convert('RGB') w = img.size[0] h = img.size[1] if w > h: input_size = np.array([256, 256 * w / h]) else: input_size = np.array([256 * h / w, 256]) input_size = input_size.astype(int) print(input_size) img = resize(img, input_size) # transforms.Resize(256) img = np.array(img, dtype=np.float32) img = center_crop(img, 224, 224) # transforms.CenterCrop(224) img = img / 255. # transforms.ToTensor() img[..., 0] = (img[..., 0] - mean[0]) / std[0] img[..., 1] = (img[..., 1] - mean[1]) / std[1] img[..., 2] = (img[..., 2] - mean[2]) / std[2] img = img.transpose(2, 0, 1) # HWC -> CHW return img#generate protobuf调用preprocess生成传给推理业务的流数据def gen_protobuf(in_file): img_np = preprocess(in_file) vision_list = MxpiDataType.MxpiVisionList() vision_vec = vision_list.visionVec.add() vision_vec.visionInfo.format = 0 vision_vec.visionInfo.width = 224 vision_vec.visionInfo.height = 224 vision_vec.visionInfo.widthAligned = 224 vision_vec.visionInfo.heightAligned = 224 vision_vec.visionData.memType = 0 vision_vec.visionData.dataStr = img_np.tobytes() vision_vec.visionData.dataSize = len(img_np) protobuf = MxProtobufIn() protobuf.key = b"appsrc0" protobuf.type = b'MxTools.MxpiVisionList' protobuf.protobuf = vision_list.SerializeToString() protobuf_vec = InProtobufVector() protobuf_vec.push_back(protobuf) return protobuf_vec(2) main方法编写main方法的编写,可以基于官方样例代码中的main方法,在那个基础上,调用我们自己的预处理函数再传值给推理业务即可streamName: 业务流的名字,需要和pipeline文件中写的保持一致6.1.6 代码运行前面的步骤完成之后,我们就可以进行代码的运行了。(1) 选择一张测试用图片我们在data目录中放入自己想要的测试图片,比如我放的这张然后在main.py中设置好图片位置全部完成后应该为这样(2) 设置运行脚本接着,我们点击上图中箭头指的地方,设置运行脚本为main.py(3) 获取运行结果点击运行获得推理结果我们可以看到,推理结果为golden retriver 金毛寻回犬上网搜搜看,发现和我们测试的狗狗图片是一样的品种6.2 C++版本开发6.2.1 新建一个项目可以参见“Python版本开发-新建一个项目”章节,这次我们选择的是C++开发空项目应该为这样6.2.2 代码目录结构根据上图的说明,我们还需要建立一个models文件用于存放模型文件,完整的目录结构应该长这样值得注意的是,这里多了一个preprocess.py文件,是用于预处理图片的,在下面“代码运行”章节会详细说明6.2.3 模型转换(或者不转换)和Python版本开发一样,可以对下载到的onnx模型进行转换,也因为转换好的模型其实就是下载的模型中的om模型,所以也可以直接拿来用。6.2.4 业务代码书写(修改)(1) 将下载到的代码中,./infer/mxbase中的src代码和CMakeLists.txt文件全部移动到src目录下(2) 修改src代码①修改路径首先修改main.cpp中的文件路径再修改编译文件中的代码路径②修改业务代码因为我们下载到的代码中,推理结果只保留了推理的类别编号,并且需要传入测试图片所在的父目录。而我们想要让它测试一张图片,并且将推理结果输出类别名称,所以需要对main.cpp和Resnet18Classify.cpp中部分代码进行修改main.cpp主要修改传入图片的方法,像上图中一样,改为传单张图片Resnet18Classify.cpp主要修改一处,将结果储存到文本文件中的方法,修改为打印输出ShowResult函数(记得在.h头文件中也添上这个方法)APP_ERROR Resnet18Classify::ShowResult(const std::string &imgPath, std::vector> \ &BatchClsInfos) { uint32_t batchIndex = 0; std::string fileName = imgPath.substr(imgPath.find_last_of("/") + 1); for (const auto &clsInfos : BatchClsInfos) { std::string resultStr; for (const auto &clsInfo : clsInfos) { resultStr += std::to_string(clsInfo.classId) + "," + clsInfo.className + "," + "confidence: " + std::to_string(clsInfo.confidence) + ";"; } LogInfo << fileName << "->Result: " << resultStr; batchIndex++; } return APP_ERR_OK;}同时,在Process函数中,将SaveResult替换成ShowResult方法调用Process函数APP_ERROR Resnet18Classify::Process(const std::string &imgPath) { std::vector inputs = {}; std::string inputIdsFile = imgPath; APP_ERROR ret = ReadInputTensor(inputIdsFile, &inputs); if (ret != APP_ERR_OK) { LogError << "Read input ids failed, ret=" << ret << "."; return ret; } std::vector outputs = {}; ret = Inference(inputs, outputs); if (ret != APP_ERR_OK) { LogError << "Inference failed, ret=" << ret << "."; return ret; } std::vector> BatchClsInfos = {}; ret = PostProcess(outputs, BatchClsInfos); if (ret != APP_ERR_OK) { LogError << "PostProcess failed, ret=" << ret << "."; return ret; } ret = ShowResult(imgPath, BatchClsInfos); if (ret != APP_ERR_OK) { LogError << "Show result failed, ret=" << ret << "."; return ret; } return APP_ERR_OK;}Init函数中,注释掉生成txt文本的代码全部完成后,就可以进行下一步了!6.2.5 项目编译业务代码写好之后,我们需要编译整个文件点击编译后,等待下方提示编译成功后,就可以运行代码了!编译好的文件在out目录下6.2.6 代码运行由于Resnet18用的预处理方法是PIL,C++中没有相应的图片处理方法,为了精度更高一些,我们需要稍微麻烦一下,使用python编写一个预处理方法prepreocess.py,将处理后的图片再传给C++代码运行preprocess.py文件可以在下载好的代码中 ./infer/util中找到,根据实际需求稍作修改就可以使用。因此我们先准备一张测试图片,比如下面这张,命名为test.jpg①:先通过preprocess.py预处理生成test.bin②:运行项目先配置运行命令点击运行7 可参考的代码我已经将自己写好的项目上传到了GitHub上,有需要可以参考Python版SDK应用开发:cid:link_12C++版SDK应用开发:cid:link_118 FAQ模型运行报错?在模型转换的时候,是否注意了选择FP32? 默认状态下是FP16的方式进行转换。或者也可以直接将下载到的模型中的om模型文件直接拿来用如果想换个数据集怎么办?可以参考modelzoo中,下载ResNet18模型的地方的说明。可以通过ModelArts训练快速进行迁移学习。Python找不到模型路径?注意在pipeline流程编排中,模型路径若使用的是相对路径,则是相对main.py文件的位置的相对路径,而不是相对于pipeline文件的相对路径。因此注意根据自己的main.py文件位置修改模型的路径C++找不到模型路径?检查自己此时代码中的模型路径是否和已经编译好的代码路径一致,C++已经编译完成后再修改代码,则需要重新编译才能运行修改后结果。No Python interpreter configured for the module?SDK版本获取失败?注意这两个地方要选子路径,选择父路径会找不到版本号9 结语MindStudio官方文档非常详细,不一而足。所以在一开始查看的时候难免会有种觉得东西太多,不知道从哪里下手的感觉。但随着开发过程的推进,逐渐发现官方文档才是开发者最应该参考的内容。此外,遇到问题时,也可以在MindStudio 昇腾社区论坛中得到许多启发,相信大家在自己动手的过程中也能体会到这一点。Now, it's time to get your hands dirty!
-
一、MindStudio介绍与安装相关课程:昇腾全流程开发工具链(MindStudio)本课程主要介绍MindStudio在昇腾AI开发中的使用,作为昇腾AI全栈中的全流程开发工具链,提供覆盖训练模型、推理应用和自定义算子开发三个场景下端到端工具,极大提高开发效率。建议开发前,学习该课程的第1章和第3章,可以少走很多弯路!!!MindStudio介绍MindStudio提供您在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务。依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发。MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。 (1)功能简介针对安装与部署,MindStudio提供多种部署方式,支持多种主流操作系统,为开发者提供最大便利。针对网络模型的开发,MindStudio支持TensorFlow、Pytorch、MindSpore框架的模型训练,支持多种主流框架的模型转换。集成了训练可视化、脚本转换、模型转换、精度比对等工具,提升了网络模型移植、分析和优化的效率。针对算子开发,MindStudio提供包含UT测试、ST测试、TIK算子调试等的全套算子开发流程。支持TensorFlow、PyTorch、MindSpore等多种主流框架的TBE和AI CPU自定义算子开发。针对应用开发,MindStudio集成了Profiling性能调优、编译器、MindX SDK的应用开发、可视化pipeline业务流编排等工具,为开发者提供了图形化的集成开发环境,通过MindStudio能够进行工程管理、编译、调试、性能分析等全流程开发,能够很大程度提高开发效率。(2)功能框架MindStudio功能框架如图1-1所示,目前含有的工具链包括:模型转换工具、模型训练工具、自定义算子开发工具、应用开发工具、工程管理工具、编译工具、流程编排工具、精度比对工具、日志管理工具、性能分析工具、设备管理工具等多种工具。图1-1 工具链功能架构 (3)工具功能MindStudio工具中的主要几个功能特性如下:工程管理:为开发人员提供创建工程、打开工程、关闭工程、删除工程、新增工程文件目录和属性设置等功能。SSH管理:为开发人员提供新增SSH连接、删除SSH连接、修改SSH连接、加密SSH密码和修改SSH密码保存方式等功能。应用开发:针对业务流程开发人员,MindStudio工具提供基于AscendCL(Ascend Computing Language)和集成MindX SDK的应用开发编程方式,编程后的编译、运行、结果显示等一站式服务让流程开发更加智能化,可以让开发者快速上手。自定义算子开发:提供了基于TBE和AI CPU的算子编程开发的集成开发环境,让不同平台下的算子移植更加便捷,适配昇腾AI处理器的速度更快。离线模型转换:训练好的第三方网络模型可以直接通过离线模型工具导入并转换成离线模型,并可一键式自动生成模型接口,方便开发者基于模型接口进行编程,同时也提供了离线模型的可视化功能。日志管理:MindStudio为昇腾AI处理器提供了覆盖全系统的日志收集与日志分析解决方案,提升运行时算法问题的定位效率。提供了统一形式的跨平台日志可视化分析能力及运行时诊断能力,提升日志分析系统的易用性。性能分析:MindStudio以图形界面呈现方式,实现针对主机和设备上多节点、多模块异构体系的高效、易用、可灵活扩展的系统化性能分析,以及针对昇腾AI处理器的性能和功耗的同步分析,满足算法优化对系统性能分析的需求。设备管理:MindStudio提供设备管理工具,实现对连接到主机上的设备的管理功能。精度比对:可以用来比对自有模型算子的运算结果与Caffe、TensorFlow、ONNX标准算子的运算结果,以便用来确认神经网络运算误差发生的原因。开发工具包的安装与管理:为开发者提供基于昇腾AI处理器的相关算法开发套件包Ascend-cann-toolkit,旨在帮助开发者进行快速、高效的人工智能算法开发。开发者可以将开发套件包安装到MindStudio上,使用MindStudio进行快速开发。Ascend-cann-toolkit包含了基于昇腾AI处理器开发依赖的头文件和库文件、编译工具链、调优工具等。2. MindStudio安装具体安装操作请参考:MindStudio安装指南 MindStudio环境搭建指导视频 (1)场景介绍纯开发场景(分部署形态):在非昇腾AI设备上安装MindStudio和Ascend-cann-toolkit开发套件包。可作为开发环境仅能用于代码开发、编译等不依赖于昇腾设备的开发活动(例如ATC模型转换、算子和推理应用程序的纯代码开发)。如果想运行应用程序或进行模型训练等,需要通过MindStudio远程连接功能连接已部署好运行环境所需软件包的昇腾AI设备。开发运行场景(共部署形态):在昇腾AI设备上安装MindStudio、Ascend-cann-toolkit开发套件包、npu-firmware安装包、npu-driver安装包和AI框架(进行模型训练时需要安装)。作为开发环境,开发人员可以进行普通的工程管理、代码编写、编译、模型转换等功能。同时可以作为运行环境,运行应用程序或进行模型训练。(2)软件包介绍MindStudio:提供图形化开发界面,支持应用开发、调试和模型转换功能,同时还支持网络移植、优化和分析等功能。Ascend-cann-toolkit:开发套件包。为开发者提供基于昇腾AI处理器的相关算法开发工具包,旨在帮助开发者进行快速、高效的模型、算子和应用的开发。开发套件包只能安装在Linux服务器上,开发者可以在安装开发套件包后,使用MindStudio开发工具进行快速开发。二、MindX SDK介绍与安装MindX SDK介绍MindX SDK提供昇腾AI处理器加速的各类AI软件开发套件(SDK),提供极简易用的API,加速AI应用的开发。应用开发旨在使用华为提供的SDK和应用案例快速开发并部署人工智能应用,是基于现有模型、使用pyACL提供的Python语言API库开发深度神经网络应用,用于实现目标识别、图像分类等功能。图2-1 MindX SDK总体结构通过MindStudio实现SDK应用开发分为基础开发与深入开发,通常情况下用户关注基础开发即可,基础开发主要包含如何通过现有的插件构建业务流并实现业务数据对接,采用模块化的设计理念,将业务流程中的各个功能单元封装成独立的插件,通过插件的串接快速构建推理业务。mxManufacture & mxVision关键特性:配置文件快速构建AI推理业务。插件化开发模式,将整个推理流程“插件化”,每个插件提供一种功能,通过组装不同的插件,灵活适配推理业务流程。提供丰富的插件库,用户可根据业务需求组合Jpeg解码、抠图、缩放、模型推理、数据序列化等插件。基于Ascend Computing Language(ACL),提供常用功能的高级API,如模型推理、解码、预处理等,简化Ascend芯片应用开发。支持自定义插件开发,用户可快速地将自己的业务逻辑封装成插件,打造自己的应用插件。2. MindX SDK安装步骤1 Windows场景下基于MindStuido的SDK应用开发,请先确保远端环境上MindX SDK软件包已安装完成,安装方式请参见《mxManufacture 用户指南》 和《mxVision 用户指南》 的“使用命令行方式开发”>“安装MindX SDK开发套件”章节。步骤2 在Windows本地进入工程创建页面,工具栏点击File > Settings > Appearance & Behavior > System Settings > MindX SDK进入MindX SDK管理界面。界面中MindX SDK Location为软件包的默认安装路径,默认安装路径为“C:\Users\用户名\Ascend\mindx_sdk”。单击Install SDK进入Installation settings界面,如图2-2。图2-2 MindX SDK管理界面如图2-3所示,为MindX SDK的安装界面,各参数选择如下:Remote Connection:远程连接的用户及IP。Remote CANN Location:远端环境上CANN开发套件包的路径,请配置到版本号一级。Remote SDK Location:远端环境上SDK的路径,请配置到版本号一级。IDE将同步该层级下的include、opensource、python、samples文件夹到本地Windows环境,层级选择错误将导致安装失败。Local SDK Location:同步远端环境上SDK文件夹到本地的路径。默认安装路径为“C:\Users\用户名\Ascend\mindx_sdk”。图2-3 MindX SDK安装界面图2-4 安装完成后的MindX SDK管理界面步骤3 单击OK结束,返回SDK管理界面,可查看安装后的SDK的信息,如图2-4所示,可单击OK结束安装流程。三、可视化流程编排介绍SDK基础概念通过stream(业务流)配置文件,Stream manager(业务流管理模块)可识别需要构建的element(功能元件)以及element之间的连接关系,并启动业务流程。Stream manager对外提供接口,用于向stream发送数据和获取结果,帮助用户实现业务对接。Plugin(功能插件)表示业务流程中的基础模块,通过element的串接构建成一个stream。Buffer(插件缓存)用于内部挂载解码前后的视频、图像数据,是element之间传递的数据结构,同时也允许用户挂载Metadata(插件元数据),用于存放结构化数据(如目标检测结果)或过程数据(如缩放后的图像)。图4-1 SDK业务流程相关基础单元 2. 可视化流程编排MindX SDK实现功能的最小粒度是插件,每一个插件实现特定的功能,如图片解码、图片缩放等。流程编排是将这些插件按照合理的顺序编排,实现负责的功能。可视化流程编排是以可视化的方式,开发数据流图,生成pipeline文件供应用框架使用。图 4-2 为推理业务流Stream配置文件pipeline样例。配置文件以json格式编写,用户必须指定业务流名称、元件名称和插件名称,并根据需要,补充元件属性和下游元件名称信息。步骤1 进入工程创建页面,用户可通过以下方式开始流程编排。在顶部菜单栏中选择Ascend>MindX SDK Pipeline,打开空白的pipeline绘制界面绘制,也可打开用户自行绘制好的pipeline文件,如图4-3。绘制界面分为左侧插件库、中间编辑区、右侧插件属性展示区,具体参考pipeline绘制 。步骤2 在左侧编辑框选择插件,拖动至中间编辑框,按照用户的业务流程进行连接。如果拖动错误插件或者错误连线,选中错误插件或者错误连线单击键盘Del键删除。用户自定义的流水线绘制完成后,选中流水线中的所有插件,右键选择Set Stream Name设置Stream名称,如果有多条流水线则需要对每一条流水线设置Stream名称。绘制完成单击Save保存。图4-2 Detection and Classification配置pipeline样例图4-3 pipeline绘制界面四、ESRGAN介绍超分辨率生成对抗网络(SRGAN)是一项能够在单幅超分辨率图像中生成逼真纹理的开创性工作。 然而,产生幻觉的细节往往伴随着令人不快的伪影。 为了进一步提高视觉质量,我们深入研究了SRGAN的三个关键组成部分——网络结构、对抗损失和感知损失,并对它们进行改进,得到了一个增强的SRGAN (ESRGAN)。 特别地,ESRGAN引入了没有批处理规格化的残差-残差密集块(RRDB)作为基本网络构建单元。 此外,ESRGAN借鉴了GAN的思想,让鉴别器预测相对真实而不是绝对值。最后,ESRGAN利用激活前的特征来改善知觉损失,为亮度一致性和纹理恢复提供更强的监督。得益于这些改进,ESRGAN实现了比SRGAN更好的视觉质量和更真实和自然的纹理,并赢得了PIRM2018-SR挑战赛的第一名。如图所示,ESRGAN网络结构,如图4-1所示:图4-1 ESRGAN网络结构代码地址:cid:link_7SDK相关工程目录结构,如图4-2所示:图4-2 SDK相关工程目录结构五、代码文件、推理数据集及模型下载代码文件下载代码地址:cid:link_7下载代码存放到本地,在本项目中只使用MindX SDK功能,所以只用到infer/sdk中的代码。 2.推理数据集下载数据集使用的是Set5,在infer/sdk/目录下先创建两个文件夹“./Set5/HR/”, “./Set5/LR/”,将以“…HR.png”命名的图片保存到“./Set5/HR/”文件夹中, 以“…LR.png”命名的图片保存到“./Set5/LR/”文件夹中。 3.模型文件(*.ckpt)下载cid:link_0先在910上导出air模型文件,保存到infer/sdk目录下。六、创建工程步骤1在顶部菜单栏中选择File > open,选择如图所示,sdk这一级的目录,步骤2 在顶部菜单栏中选择Ascend > Convert To Ascend Projec,进入如图6-1所示页面,各参数选择如图所示,点击OK,将该项目转换为Ascend MindX SDK App。图6-1 转换为Ascend MindX SDK App七、模型转换功能介绍及操作步骤讲解用户使用Caffe/TensorFlow等框架训练好的第三方模型,可通过ATC工具将其转换为昇腾AI处理器支持的离线模型(*.om文件),模型转换过程中可以实现算子调度的优化、权重数据重排、内存使用优化等,可以脱离设备完成模型的预处理,详细架构如图7-1所示。图7-1 ATC工具功能架构在本项目中,要将mindspore框架下训练好的模型(*.air文件),转换为昇腾AI处理器支持的离线模型(*.om文件),具体步骤如下:步骤1 点击Ascend > Model Converter,进入模型转换界面,参数配置如图7-2所示,若没有CANN Machine,请参见第八章第一节CANN安装。图7-2 模型转换界面1各参数解释如下表所示:CANN MachineCANN的远程服务器Model File*.air文件的路径(可以在本地,也可以在服务器上)Model Name生成的om模型名字Output Path生成的om模型保存在本地的路径图7-3 模型转换界面2图7-4 模型转换界面3步骤2 点击Next进入图7-3界面,该项目数据不需要预处理,直接点击Next,进入图7-4界面,再点击Finish开始模型转换。步骤3 等待出现如图7-5所示的提示,模型转换成功图7-5 模型转换成功步骤4 双击转换成功的om模型文件,可以查看网络结构。如图7-6所示图7-6 查看模型网络结构八、运行工程操作步骤讲解步骤1 修改“sdk/config/esrgan.pipeline”中的参数,具体操作如图8-1所示;图8-1 修改pipeline中*.om文件路径步骤2 在MindStudio工程界面,依次选择“Run > Edit Configurations...”,进入运行配置页面。选择“Ascend App > 工程名”配置应用工程运行参数,图8-2为配置示例。配置完成后,单击“Apply”保存运行配置,单击“OK”,关闭运行配置窗口。图8-2 工程推理工程运行参数配置Deployment远程服务器Executable运行文件Command Arguments运行参数在本工程中,推理时运行文件选择main.py,运行参数为--img_path [LR_path] --pipeline_path [pipeline_path] --infer_result_dir [result_path]参数解释如下表:参数解释我的设置img_path推理图片路径./Set5/LR/pipeline_pathPipeline文件路径./config/esrgan.pipelineinfer_result_dir推理结果保存路径./infer_result/步骤3 点击运行,出现如图8-3所示提示,即为运行成功,infer_result文件夹中即为推理结果,保存为二进制形式。图8-3 推理操作过程步骤4 配置后处理运行程序,在MindStudio工程界面,依次选择“Run > Edit Configurations...”,进入运行配置页面,如图8-4所示,点击“+”,后选择Python(后处理可以直接在本地运行),如图8-5所示。图8-4 运行配置界面图8-5 选择本地Python解释器图8-6 运行后处理相关配置Script path运行文件路径Parameters运行时的参数如图8-6所示,运行文件为postprocess.py,运行参数为:--HR_path [HR_image_path] --predict_result [infer_result] --result_path [save_image_path]相关参数解释及设置参数解释我的设置HR_path数据集中高分辨率图片./Set5/HR/predict_result步骤3中的推理结果./infer_result/result_path最终结果保存的目录./sdk_result_img/步骤5 点击运行,出现如图8-7所示提示,即为运行成功,sdk_result_img文件夹中即为最终结果,PSNR为推理生成的图片与原图片对比的指标。图8-7 运行后处理程序 步骤6 结果分析,如图8-8所示,为ESRGAN生成的高分辨率图像与原图像对比,可以看到,在一些细节上生成的图像在细节和纹理上已经很清晰。图8-8 ESRGAN生成的高分辨率图像与原图像对比九、遇见的问题在使用MindStudio时,遇到问题,可以登陆MindStudio昇腾论坛进行互动,提出问题,会有专家老师为你解答。模型转换时,没有CANN Machine图9-1 CANN管理界面解决方案:按以下步骤,重新安装CANN Machine步骤1 点击File>Settings>Appearance & Behavior > System Settings > CANN,进入CANN管理界面,如图9-1所示:步骤2 点击Change CANN,进入Remote CANN Setting界面,如图9-2所示重新安装CANN,点击Finish,安装CANN。9-2 Remote CANN Setting界面图9-3 安装CANN完成参数解释如下表:Remote Connection远程服务器IPRemote CANN location远程服务器中CANN路径步骤3 完成CANN安装,点击OK,重启MindStudio,如图9-3所示。MindStudio导入应用工程后,提示“No Python interpreter configured for the module”解决方案:步骤1 在顶部菜单栏中选择File > Project Structure,在Project Structure窗口中,点击Platform Settings > SDKs,点击上方的“+”添加Python SDK,从本地环境中导入Python,如图9-4所示。图9-4 导入Python SDK步骤2 点击Project Settings > Project,选择上一步添加的Python SDK,如图9-5所示。图9-5 设置Project SDK步骤3 点击Project Settings > Modules,选中“MyApp”,点击“+”后选择Python,为Python Interpreter选择上述添加的Python SDK。点击OK完成应用工程Python SDK配置,如图9-6所示。图9-6 选择Python SDK
-
摘要:介绍如何用昇腾AI处理器上的DVPP单元进行,图像的等比例缩放,保证图像不变形。本文分享自华为云社区《CANN DVPP进行图片的等比例缩放》,作者:马城林 。1. 为什么需要进行等比例的缩放,直接暴力缩放成模型需要的宽高岂不是更省事首先没有任何的规定表示我们必须进行等比例的缩放,因为实际上即使图像上的物体因为缩放而变形,物体本身的特征还是存在,神经网络依旧可以提取对应的特征进而预测出物体的位置,通过计算实际的宽高与模型之间的宽高的比例依旧可以将模型预测到的候选框的映射到实际的原图上。这样看来等比例的缩放存在感好低!但是事情真的是这样吗?肯定不是呀,要不我为啥会写这篇博客呢?首先有以下几点考虑:目标检测除了将图像送入模型,实际上物体在图像中的位置也被作为一部分信息参与了模型的训练,经过等比例缩放的图片在坐标转换上明显省事。有些图像经过非等比例压缩后已经与实际场景中的物体差别很大,严重的变形会干扰到模型的准确性。等比例缩放更加符合我们人类的直觉。2. 如何在昇腾AI处理器上进行等比例缩放如果在我们的训练服务器,或者我们自己的个人计算机上,因为计算能力的相对充沛,我们可以借助很多开源图像库例如opencv,pillow等进行图像的等比例缩放。但是一旦道路端侧部署时这些开源图像库的方法往往成为整个推理过程最耗时的部分,因为他们主要通过CPU进行运算,而在诸如200DK这样的环境上,进行这样的变换让本就不充沛的CPU算力雪上加霜。而昇腾AI处理器上拥有专门处理数字图像的硬件单元。所以如何借助这些专用的硬件单元是十分重要的。话不多说开始吧!3. 实战讲解主要从以下几个方面进行讲解步骤分解每一步在昇腾AI处理器上的实现怎么把几步组合起来完成一个完整的动作介绍 AscendCL 为开发者提供的组合API接口,只需要一个函数完成所有动作,想想都刺激<概念注意>昇腾AI处理器在不同的环境上拥有不同运行模式,常见的分为两种,一种是类似于显卡一样插在服务器的PCIE插槽上,提供加速服务,一种是类似于200DK一样的嵌入式环境。工作在服务器的PCIE插槽上的昇腾310内存有两种存在形态,一种就是我们常见的内存,称为host内存。一种类似于显卡的显存,称为device内存,这种状态下需要涉及到内存拷贝的问题。200DK这种环境,不区分host与device,只有一块device内存,所以并不涉及host与device的内存拷贝问题媒体数据处理描述图形的大小,主要有两种表示方法,width,height,表示图像的真实宽高,widthstride,heightstride表示图像在内存中对其到128,16,2后的宽高,内存宽高标识图像在内存中的位置(但是可能有为了填充而产生的无效数据),真实宽高就标识内存中真实有效的数据。JPEG Decode时对JPEG的源图像没有宽高的要求,但是输出的数据,宽会对齐到128,长会对齐到16,对齐后可能会产生一部分的无效数据。VPC 图像缩放,抠图,贴图对输入的源图像宽高对齐到2,对齐后的内存宽高为,宽对齐到16,高对齐到2,输出与输入约束条件相同JPEG Encode 对输入的源图像宽高对齐到2,对齐后的内存宽高为,宽对齐到16或者16的倍数(128时性能更好),高对齐到16。详细的约束对齐规则JPEG DecodeVPCJPEG Encode3.1 步骤分解很多朋友和我一样属于一听就会,一动手就废的类型,在脑海里勾勒出万里江山,实际一上手,我是个傻子。。。。。实际上是我们还没有掌握做事情的诀窍,就是把事情分解成可以很方便用代码描述出的步骤;计算机编程让人感到头皮发麻的一个重要原因就是计算机它只会一步一步来,不会跳步。所以我们脑海里面很简单的步骤在编程实现后也可能代码很长。将常见的JPEG图片解码成YUV格式的图片aclError acldvppJpegDecodeAsync(acldvppChannelDesc *channelDesc, const void *data, uint32_t size, acldvppPicDesc *outputDesc,aclrtStream stream)因为JPEG解码有128x16的对齐要求,所以解码后的数据边缘会出现无效数据,需要进行裁剪aclError acldvppVpcCropAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, aclrtStream stream)进行resize的操作,没有对应的等比例缩放的接口,但是如果我们最后指定的图像大小相对于原图是等比例的,就是等比例缩放aclError acldvppVpcResizeAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppResizeConfig *resizeConfig, aclrtStream stream)进行等比例缩放时需要一个,与模型大小一致的纯色背景图片作为贴图的背景,我们可以申请对应大小的一些区域然后,将对应区域全部赋值为同一个数。aclError aclrtMemset (void *devPtr, size_t maxCount, int32_t value, size_t count)进行贴图aclError acldvppVpcCropAndPasteAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, acldvppRoiConfig *pasteArea, aclrtStream stream)进行模型推理或编码保存3.2 对应的变量怎么声明与初始化DVPP处理的通道的声明与销毁DVPP的一系列操作都是建立在已经声明初始化的通道上,你可以理解为初始化了相关的硬件资源acldvppChannelDesc *channelDesc channelDesc = acldvppCreateChannelDesc(); aclError ret = acldvppCreateChannel(channelDesc); // 销毁与创建的顺序相反 acldvppDestroyChannel(channelDesc); acldvppDestroyChannelDesc(channelDesc);各种图像的操作描述对应的图像的描述信息的创建与销毁acldvppPicDesc *picDesc picDesc = acldvppCreatePicDesc(); acldvppSetPicDescData(picDesc, decodeOutDevBuffer_); // 图像的内存地址 acldvppSetPicDescSize(picDesc, decodeOutBufferSize); // 图像所占的内存大小 acldvppSetPicDescFormat(picDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); // 图像的格式 acldvppSetPicDescWidth(picDesc, inputWidth_); // 图像的实际宽 acldvppSetPicDescHeight(picDesc, inputHeight_); // 图像的实际高 acldvppSetPicDescWidthStride(picDesc, decodeOutWidthStride); // 图像在内存中对齐后的宽 acldvppSetPicDescHeightStride(picDesc, decodeOutHeightStride); // 图像在内存中对齐后的高 // 销毁 acldvppDestroyPicDesc(picDesc);申请内存// device侧,200DK等只有device内存的也用此接口,且只用此接口 aclError aclrtMalloc(void **devPtr, size_t size, aclrtMemMallocPolicy policy) aclError aclrtFree(void *devPtr) // host侧 aclError aclrtMallocHost(void **hostPtr, size_t size) aclError aclrtFreeHost(void *hostPtr) // dvpp 内存(在device侧,因为需要内存地址128对齐,所以拥有单独的接口) aclError acldvppMalloc(void **devPtr, size_t size) aclError acldvppFree(void *devPtr)创建抠图,贴图的区域acldvppRoiConfig *acldvppCreateRoiConfig(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) // 销毁 aclError acldvppDestroyRoiConfig(acldvppRoiConfig *roiConfig)不知道图片的相关信息获取信息的接口// 通过此接口可以方便的获取JPEG图像的宽,高,色彩通道数,编码格式,只需要传入对应的JPEG源数据地址以及大小 aclError acldvppJpegGetImageInfoV2(const void *data, uint32_t size, uint32_t *width, uint32_t *height, int32_t *components, acldvppJpegFormat *format) // 获取JPEG图片解码后的数据大小,因为解码后会对齐到128,所以不能任何时候都简单地依据原图大小计算解码后占用的内存大小。 aclError acldvppJpegPredictDecSize(const void *data, uint32_t dataSize, acldvppPixelFormat outputPixelFormat, uint32_t *decSize) // 获取PNG图像的宽和高 aclError acldvppPngGetImageInfo(const void *data, uint32_t dataSize, uint32_t *width, uint32_t *height, int32_t *components) // 预测PNG图片解码后占用内存空间 aclError acldvppPngPredictDecSize(const void *data, uint32_t dataSize, acldvppPixelFormat outputPixelFormat, uint32_t *decSize) // 获取JPEG图像编码后的占用内存空间 aclError acldvppJpegPredictEncSize(const acldvppPicDesc *inputDesc, const acldvppJpegeConfig *config, uint32_t *size)图像缩放,贴图,抠图相关的接口(当有多个操作动作时建议使用组合接口,虽然看似是多个步骤,实际上硬件内部只是执行一次操作可以大幅度提升处理的效率)// 缩放接口,单一接口,将缩放后的图片作为输出 aclError acldvppVpcResizeAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppResizeConfig *resizeConfig, aclrtStream stream) // 抠图接口,单一接口,从原图中根据ROI区域抠出一部分作为输出 aclError acldvppVpcCropAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, aclrtStream stream) // 组合接口(抠图+缩放),应用场景:JPEG 解码后的图片中可能有无效的数据,直接缩放到模型需要的大小会把无效数据一起输入,可以先把真实图像的数据抠出来然后进行缩放,减少无效的数据干扰。 aclError acldvppVpcCropResizeAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, acldvppResizeConfig *resizeConfig, aclrtStream stream) // 组合接口(抠图+贴图 / 抠图+缩放+贴图)如果抠图与贴图的大小不一致会进行一步缩放操作。 aclError acldvppVpcCropAndPasteAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, acldvppRoiConfig *pasteArea, aclrtStream stream) // 组合接口(抠图+贴图 / 抠图+缩放+贴图)此接口功能与上一个是一致的,但是此接口可以指定不同的缩放算法 aclError acldvppVpcCropResizePasteAsync(acldvppChannelDesc *channelDesc, acldvppPicDesc *inputDesc, acldvppPicDesc *outputDesc, acldvppRoiConfig *cropArea, acldvppRoiConfig *pasteArea, acldvppResizeConfig *resizeConfig, aclrtStream stream)3.3 实战讲解效果展示:1024x688 =》 416x416// 定义一些全局变量 namespace { std::string aclConfig = "../src/acl.json"; const std::string image_path = "../data/dog2.jpg"; const std::string image_save_path = "../out/dog2.jpg"; int32_t deviceId = 0; aclrtContext context; aclrtStream stream; aclrtRunMode runMode_ = ACL_DEVICE; uint32_t model_width = 416; // 模型需要的图像宽 uint32_t model_height = 416; // 模型需要的图像高 uint32_t image_width = 0; // 图像的真实宽 uint32_t image_height = 0; // 图像的真实高 acldvppChannelDesc *dvppChannelDesc = nullptr; }开始进行解码操作// 将图片读入内存,如果运行模式为(ACL_HOST)模式,需要申请host侧内存存放我们的原始图片数据,然后申请相同大小的device内存拷贝过去。如果运行在(ACL_DEVICE)模式,例如200DK这样的场景,直接申请device内存,不需要进行内存的拷贝搬运。 // 经过读取图片的步骤我们应该能获得如下变量 void* JpegImagePtr; // 原始图像在device侧的内存地址(不管运行在那种方式下的昇腾软件栈都是如此) uint32_t JpegImageSize; // 原始图像的大小 // 我们不了解图像的编码以及真实宽高,还有颜色通道数,所以需要执行获取图像信息的接口 // 图像的原始宽高变量我们前面已经定义过, 所以我们现在只需要定义图像的通道数与编码方式还有图像解码后所占用的内存的大小 int32_t components; // 图像的通道数 acldvppJpegFormat format; // 图像的编码方式 uint32_t JpegdOutSize; void* JpegdOutPtr; aclError ret = acldvppJpegGetImageInfoV2(JpegImagePtr, JpegImageSize, &image_width, &height, &components, &format) aclError ret = acldvppJpegPredictDecSize(JpegImagePtr, JpegImageSize, format, &JpegdOutSize) // 申请存放解码后YUV图像的内存 aclError ret = acldvppMalloc(&JpegdOutPtr, JpegdOutSize); // 设置JPEG解码后图像的描述信息(注意JPEG解码后内存宽高对齐到128x16) acldvppPicDesc* JpegdOutputPicDesc = acldvppCreatePicDesc(); acldvppSetPicDescData(out_pic_desc, JpegdOutPtr); acldvppSetPicDescSize(out_pic_desc, JpegdOutSize); acldvppSetPicDescFormat(out_pic_desc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(out_pic_desc, image_width); acldvppSetPicDescHeight(out_pic_desc, image_height); acldvppSetPicDescWidthStride(out_pic_desc, ALIGN_UP128(image_width)); acldvppSetPicDescHeightStride(out_pic_desc, ALIGN_UP16(image_height)); // 执行解码接口 ret = acldvppJpegDecodeAsync(dvppChannelDesc, JpegImagePtr, JpegImageSize, JpegdOutputPicDesc, stream); ret = aclrtSynchronizeStream(stream_);开始进行抠图的操作,因为我们这次需要执行抠图+缩放+贴图三个动作所以我们选择组合API进行编程// 首先声明原图抠图的区域 // 抠图的区域左偏移和上偏移都是偶数 // 抠图的区域右偏移和下偏移都是奇数 uint32_t left = 0; uint32_t top = 0; uint32_t right = image_width % 2 == 0 ? image_width-1 : image_width; uint32_t bottom = image_height % 2 == 0 ? image_height-1 : image_height; acldvppRoiConfig* cropArea = cropConfig = acldvppCreateRoiConfig(left, right, top, bottom); // 计算等比例缩放后的新的宽高(等比例缩放后可能不满足16x2的对齐规则,需要手动进行对齐的操作) void LargeSizeAtLeast(uint32_t W, uint32_t H, uint32_t &newInputWidth, uint32_t &newInputHeight) { INFO_LOG("W:%u H:%u nw:%u, nh:%u", W, H, newInputWidth, newInputHeight); float scaleRatio = 0.0; float inputWidth = 0.0; float inputHeight = 0.0; float resizeMax = 0.0; bool maxWidthFlag = false; inputWidth = (float)W; inputHeight = (float)H; resizeMax = (float)(416); maxWidthFlag = (W >= H) ? true : false; if (maxWidthFlag == true) { newInputWidth = resizeMax; scaleRatio = resizeMax / W; // 高度2对齐 newInputHeight = scaleRatio * H; newInputHeight = ALIGN_UP2(newInputHeight); INFO_LOG("scaleRatio: %.3f, modelInputWidth: %u, modelInputHeight: %d, newInputWidth: %d, newInputHeight: %d", scaleRatio, W, H, newInputWidth, newInputHeight); } else { scaleRatio = resizeMax / H; // 如果高度是长边,建议宽度在等比例缩放后再做一次16对齐。因为vpc在输出时宽有16字节对齐约束,当贴图的宽非16对齐时,会导致在贴图的时候, // 芯片会自动进行16字节对齐,导致每次写入数据的时候都会引入部分无效数据,从而导致精度下降。 newInputWidth = scaleRatio * W; newInputWidth = ALIGN_UP16(newInputWidth); newInputHeight = resizeMax; INFO_LOG("scaleRatio: %.3f, modelInputWidth: %u, modelInputHeight: %d, newInputWidth: %d, newInputHeight: %d", scaleRatio, W, H, newInputWidth, newInputHeight); } } // 设置贴图的范围左偏移要求16对齐 acldvppRoiConfig *InitVpcOutConfig(uint32_t width, uint32_t height, uint32_t modelInputWidth, uint32_t modelInputHeight) { uint32_t right = 0; uint32_t bottom = 0; uint32_t left = 0; uint32_t top = 0; uint32_t left_stride; acldvppRoiConfig *cropConfig; uint32_t small = width < height ? width : height; uint32_t padded_size_half; if (small == width) { padded_size_half = (modelInputWidth - width) / 2; // 贴图区域距离左边界的距离 left = padded_size_half; left_stride = ALIGN_UP16(left); right = (left_stride + width) % 2 == 0 ? (left_stride + width - 1) : (left_stride + width); if (left_stride + right > modelInputWidth) { while (true) { left_stride = left_stride - 16; right = (left_stride + width) % 2 == 0 ? (left_stride + width - 1) : (left_stride + width); if (left_stride + right < modelInputWidth) break; } } right = (left_stride + width) % 2 == 0 ? (left_stride + width - 1) : (left_stride + width); bottom = (modelInputHeight % 2 == 0 ? modelInputHeight - 1 : modelInputHeight); top = bottom - height + 1; } else { padded_size_half = (modelInputHeight - height) / 2; right = (modelInputWidth % 2 == 0 ? modelInputWidth - 1 : modelInputWidth); left = right + 1 - width; left_stride = ALIGN_UP16(left); top = (padded_size_half % 2 == 0 ? padded_size_half : padded_size_half + 1); bottom = (height + top - 1) % 2 == 0 ? (height + top - 2) : (height + top - 1); } INFO_LOG("left_stride=%d, right=%d, top=%d, bottom=Ð7557a86-c79e-418c-bc75-fa080612ce7dn", left_stride, right, top, bottom); cropConfig = acldvppCreateRoiConfig(left_stride, right, top, bottom); if (cropConfig == nullptr) { ERROR_LOG("acldvppCreateRoiConfig failed"); return nullptr; } return cropConfig; } // 设置最后完成等比例缩放后的图像的信息 void* output_ptr = nullptr; uint32_t output_size = YUV420SP_SIZE(ALIGN_UP16(model_width), ALIGN_UP2(model_height)); ret = acldvppMalloc(&output_ptr, output_size); // 申请模板内存 if (ret != ACL_SUCCESS) { ERROR_LOG("acl malloc output is failed"); } ret = aclrtMemset(output_ptr, output_size, 128, output_size); if (ret != ACL_SUCCESS) { ERROR_LOG("mem set 128 is failed"); } acldvppPicDesc *output_Desc = acldvppCreatePicDesc(); acldvppSetPicDescData(output_Desc, output_ptr); acldvppSetPicDescSize(output_Desc, output_size); acldvppSetPicDescFormat(output_Desc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(output_Desc, model_width); acldvppSetPicDescHeight(output_Desc, model_height); acldvppSetPicDescWidthStride(output_Desc, ALIGN_UP16(model_width)); acldvppSetPicDescHeightStride(output_Desc, ALIGN_UP2(model_height)); // 执行裁剪加贴图的操作 ret = acldvppVpcCropAndPasteAsync(dvppChannelDesc, JpegdOutputPicDesc, output_Desc, cropArea, pasteArea, stream);完成了一系列的操作总结对于DVPP处理来说,单独的接口调用需要全部满足输入和输出的长宽以及对齐的要求但是对于 JPEG+VPC 这样的串联编程来说前一个组件的输出图像描述是后一个组件的输入描述,设定对齐内存是为了有效标定,图像在内存中的位置,如果固执的设定对齐后的值,对于后一个组件来说很有可能得到的输入是有缺失的信息。根据众多对齐要求我们可以看出,对于图像的原始宽高全部2对齐是一个比较好的习惯,而且常用的图像规格都是偶数例如1920x1080,1280x720, 640x640, 416x416,最好不要出现长或者宽为奇数的情况,因为硬件会自动为奇数进行对齐从而产生无效数据。增加了处理的难度。
-
将jpeg解码后的数据格式由YUV420SP NV12定制为YUV420SP NV21。CropAndPasteHelper修改:JpegDHelper修改:ResizeHelper修改:aipp修改:模型转换后的编译运行结果为:
-
与torch对比,缺少ceil_mode参数, 无法保留尺寸不足kernel size的信息
-
将输入数据从jpeg压缩图片更换为png压缩图片。需要修改的文件有两个,分别是:detectPreprocessparams.conf编译运行的结果为
-
摘要:本篇文章结合灰度三维图像讲解图像顶帽运算和图像黑猫运算,通过Python调用OpenCV函数实现。本文分享自华为云社区《[Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算》,作者: eastmount。本篇文章继续深入,结合灰度三维图像讲解图像顶帽运算和图像黑猫运算,通过Python调用OpenCV函数实现。一.图像顶帽运算图像顶帽运算(top-hat transformation)又称为图像礼帽运算,它是用原始图像减去图像开运算后的结果,常用于解决由于光照不均匀图像分割出错的问题。其公式定义如下:图像顶帽运算是用一个结构元通过开运算从一幅图像中删除物体,校正不均匀光照的影响,其效果图如下图所示。在Python中,图像顶帽运算主要调用morphologyEx()实现,其中参数cv2.MORPH_TOPHAT表示顶帽处理,函数原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)src表示原始图像cv2.MORPH_TOPHAT表示图像顶帽运算kernel表示卷积核,可以用numpy.ones()函数构建假设存在一张光照不均匀的米粒图像,如图所示,我们需要调用图像顶帽运算解决光照不均匀的问题。其Python代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test06.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((10,10), np.uint8) #图像顶帽运算 result = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()其运行结果如下,它有效地将米粒与背景分离开来。二.图像黑帽运算图像底帽运算(bottom-hat transformation)又称为图像黑帽运算,它是用图像闭运算操作减去原始图像后的结果,从而获取图像内部的小孔或前景色中黑点,也常用于解决由于光照不均匀图像分割出错的问题。其公式定义如下:图像底帽运算是用一个结构元通过闭运算从一幅图像中删除物体,常用于校正不均匀光照的影响。其效果图如下图所示。在Python中,图像底帽运算主要调用morphologyEx()实现,其中参数cv2.MORPH_BLACKHAT表示底帽或黑帽处理,函数原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)src表示原始图像cv2.MORPH_BLACKHAT表示图像底帽或黑帽运算kernel表示卷积核,可以用numpy.ones()函数构建Python实现图像底帽运算的代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test06.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((10, 10), np.uint8) #图像黑帽运算 result = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()其运行结果如图所示:三.基于灰度三维图的顶帽黑帽运算为什么图像顶帽运算会消除光照不均匀的效果呢?通常可以利用灰度三维图来进行解释该算法。灰度三维图主要调用Axes3D包实现,对原图绘制灰度三维图的代码如下:# -*- coding: utf-8 -*- import numpy as np import cv2 as cv import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter #读取图像 img = cv.imread("test06.png") img = cv.cvtColor(img,cv.COLOR_BGR2GRAY) imgd = np.array(img) #image类转numpy #准备数据 sp = img.shape h = int(sp[0]) #图像高度(rows) w = int(sp[1]) #图像宽度(colums) of image #绘图初始处理 fig = plt.figure(figsize=(16,12)) ax = fig.gca(projection="3d") x = np.arange(0, w, 1) y = np.arange(0, h, 1) x, y = np.meshgrid(x,y) z = imgd surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm) #自定义z轴 ax.set_zlim(-10, 255) ax.zaxis.set_major_locator(LinearLocator(10)) #设置z轴网格线的疏密 #将z的value字符串转为float并保留2位小数 ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) # 设置坐标轴的label和标题 ax.set_xlabel('x', size=15) ax.set_ylabel('y', size=15) ax.set_zlabel('z', size=15) ax.set_title("surface plot", weight='bold', size=20) #添加右侧的色卡条 fig.colorbar(surf, shrink=0.6, aspect=8) plt.show()运行结果如下图所示:从图像中的像素走势显示了该图受各部分光照不均匀的影响,从而造成背景灰度不均现象,其中凹陷对应图像中灰度值比较小的区域。而通过图像白帽运算后的图像灰度三维图的代码如下:# -*- coding: utf-8 -*- import numpy as np import cv2 as cv import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter #读取图像 img = cv.imread("test06.png") img = cv.cvtColor(img,cv.COLOR_BGR2GRAY) #图像黑帽运算 kernel = np.ones((10,10), np.uint8) result = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel) #image类转numpy imgd = np.array(result) #准备数据 sp = result.shape h = int(sp[0]) #图像高度(rows) w = int(sp[1]) #图像宽度(colums) of image #绘图初始处理 fig = plt.figure(figsize=(8,6)) ax = fig.gca(projection="3d") x = np.arange(0, w, 1) y = np.arange(0, h, 1) x, y = np.meshgrid(x,y) z = imgd surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm) #自定义z轴 ax.set_zlim(-10, 255) ax.zaxis.set_major_locator(LinearLocator(10)) #设置z轴网格线的疏密 #将z的value字符串转为float并保留2位小数 ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) # 设置坐标轴的label和标题 ax.set_xlabel('x', size=15) ax.set_ylabel('y', size=15) ax.set_zlabel('z', size=15) ax.set_title("surface plot", weight='bold', size=20) #添加右侧的色卡条 fig.colorbar(surf, shrink=0.6, aspect=8) plt.show()效果图如下所示,对应的灰度更集中于10至100区间,由此证明了不均匀的背景被大致消除了,有利于后续的阈值分割或图像分割。