医学人体关键点检测技术
1 介绍
本项目主要用于研究辅助X线摄影的体位识别和体表解剖标志检测技术。
针对现有的关键点检测算法无法提供体位先验信息及无法进行体表解剖标志的精确定位的问题,本项目提出一种基于多任务学习的体位识别和体表解剖标志检测方法,该方法包含主干网络、体位分类分支、体表解剖标志检测分支和后处理模块,可以同时且高效的进行体位识别和体表解剖标志检测,是本领域的第一个方法。
本开发样例基于MindX SDK实现医学人体关键点检测的功能,其主要流程为:1)利用FasterRcnn模型对输入图像进行人体检测,通过检测得到的box数据对图像进行仿射变换;2)利用HRNET-W48模型对仿射变换后的人像进行多任务学习,同时获取体位分类情况与体表标志检测;3)对上述结果进行后处理,生成一张带有医学人体检测点的人像图片。
样例输入:医学人体的jpg图片
样例输出:根据体位分类后的关键点标注图片
1.1 支持的产品
项目所用的硬件平台:Ascend310,Atlas 200DK板卡
1.2 支持的版本
支持的SDK版本为 npu-smi 20.2.0
1.3 代码目录结构与说明
本工程名称为MedicalKeypointsDetection,工程目录如下图所示:
|-------- data // 存放测试图片
|-------- model // 存放模型
|-------- main.py // 主程序
|-------- pipeline
| |---- fasterrcnn.pipeline // 模型1pipeline配置文件
| |---- hrnet.pipeline // 模型2pipeline配置文件
|-------- evaluate.py // 精度测试程序
|-------- README.md
|-------- run.sh
1.4 特性及适用场景
本案例可以满足医学场景下的人体关键点检测,但同时对输入的图像有以下限制:
- 输入图像要求为 jpg、jpeg、JPG、JPEG编码格式。
- 输入图像有且仅能存在一个人体。
- 输入图像只针对特定体态进行识别,建议从提供的测试图片或根据对应体态自行拍摄图片进行测试,保证背景简单。
2 环境依赖
软件名称 | 版本 |
---|---|
MindX SDK | 2.0.4 |
python | 3.9 |
opencv2 | 4.6.0.66 |
numpy | 1.23.4 |
pycocotools | 2.0.5 |
pillow | 9.2.0 |
在编译运行项目前,需要设置环境变量:
-
MindX SDK 环境变量介绍
. ${SDK-path}/set_env.sh
-
CANN 环境变量介绍
. ${ascend-toolkit-path}/set_env.sh
3 模型转换
3.1 FasterRcnn模型
该模型直接从华为仓内下载即可。点击"下载模型",使用其中的fasterrcnn_mindspore_dvpp.om模型。
Faster R-CNN-昇腾社区 (hiascend.com)
并将该om文件放置在:“项目所在目录/model”
3.2 HRnet-w48模型
医学人体关键点检测采用自行训练的hrnet-w48模型。我们需要借助于ATC工具将onnx模型转化为对应的om模型。
具体步骤如下: 步骤1 获取模型onnx文件 ,下载链接为下载
步骤2 将获取到的HRnet-w48模型onnx文件存放至:“项目所在目录/model”
步骤3 模型转换
在确保环境变量设置正确后,在onnx文件所在目录下执行以下命令:
atc --model=pose_model_384x288.onnx --framework=5 --output=pose_model_384_288_noAipp_fp16 --soc_version=Ascend310 --output_type=FP16
执行完模型转换脚本后,若提示如下信息说明模型转换成功,会在output参数指定的路径下生成pose_model_384_288_noAipp_fp16.om模型文件。
ATC run success
4 编译运行
接下来进行模型的安装运行,具体步骤如下:
步骤1 获取om模型(见前一章节)
步骤2 配置pipeline
根据所需场景,配置pipeline1与pipeline2文件,调整路径参数等。
fasterrcnn.pipeline:
"mxpi_tensorinfer0": {
"props": {
"modelPath": "./model/fasterrcnn_mindspore_dvpp.om"
},
"factory": "mxpi_tensorinfer",
"next":"appsink0"
}
#修改om文件存放的路径
hrnet.pipeline:
"mxpi_tensorinfer0": {
"props": {
"modelPath": "./model/pose_model_384_288_noAipp_fp16.om"
},
"factory": "mxpi_tensorinfer",
"next":"appsink0"
}
#修改om文件存放的路径
步骤3 存放图片,执行模型进行测试
将测试图片存放至主目录下,修改main.py中的图片存放路径以及人像分割后的存储路径的相关代码: 测试图片 【注】本模型定位场景为医学应用下的人体关键点检测,故只针对特定体态进行识别,建议从提供的测试图片或根据对应体态自行拍摄图片进行测试。
FILE_PATH = '' #测试图片路径
SAVEPATH = '' #测试结果保存路径,图片保存路径需提前手动创建
然后执行run.sh文件(执行前需要通过命令提供执行权限):
./run.sh
输出的图片即为样例的人像分割后的图片。
5 精度测试
对测试集中的3651张图片进行精度测试,具体步骤如下:
步骤1 获取测试集的图片,确保测试集的输入图片为jpg格式。获取测试集的标注文件(person_keypoints_val2017.json
)。存放于data路径下。
(数据集暂未开源)
步骤2 修改evaluate.py中的测试集图片存放路径:
coco_anno = ' ' #485行,修改为测试集的标注文件路径
coco_anno = ' ' #557行,修改为测试集的标注文件路径
IMAGEFOLDER = ' ' #677行,修改为测试集的路径
FILE_ANNO = ' ' #678行,修改为测试集的标注文件路径
TXT = '' #689行,体位分类情况,请提前在文件夹对应位置创建同名文本文件
步骤3 找到pycocotools源代码(cocoeval.py文件),修改kpt_oks_sigmas的值如下:(此为自制数据集的标注误差)
self.kpt_oks_sigmas = np.array(
[0.008784891334757884, 0.007934237422930233, 0.008130125823095129, 0.010598041983050829, 0.010611059330895747, 0.013854384373318705, 0.012312922863012592, 0.011434032335303733, 0.011415450225720266, 0.013836090153967652, 0.010062551495331999, 0.012966371944947402, 0.014659796595795808, 0.017770972497132317, 0.030104085032138312, 0.014557348480916475, 0.01536017320369201, 0.012869410502722093, 0.015257251871497391, 0.010375051254335216, 0.011380203661720942, 0.01414838952723429, 0.01382237259730266, 0.013735144644847687, 0.01472162976531488, 0.009619962495050469, 0.008610254442541486,
0.029481674119348003, 0.024059201435679762, 0.042427130812542665, 0.040127749201969376, 0.0525428294612648,
0.026481463695494662, 0.027975991688555843, 0.025593756110373064, 0.027253280146480565, 0.027454019180679124, 0.025064436713274765, 0.02099536659024268, 0.020033183495373304, 0.015050220402346052, 0.015267670545143495,
0.02596082400646692, 0.02923469684259541, 0.027801624530848095, 0.021826487778693508, 0.015060326275153427, 0.014315148040325337,
0.02596082400646692, 0.02923469684259541, 0.027801624530848095, 0.021826487778693508, 0.015060326275153427, 0.014315148040325337,
0.007395141152098735, 0.00762250652117458, 0.010602288831543757, 0.0090104333962127,
0.010453948805939391, 0.010370213072066961,
0.022732842847710055, 0.06232777881671897, 0.045665339866036256,
0.022732842847710055, 0.06232777881671897, 0.045665339866036256,
0.02359125146550032,
0.02359125146550032,
0.031776475097392176,
0.0270604129014659,
0.03426748613886749,
0.03807683079471247,
0.01993400901401409,
0.01993400901401409,
0.032237205934095854,
0.032237205934095854,
0.017419685722172645,
0.017419685722172645,
0.03147083587813606,
0.03147083587813606], dtype=np.float32
)
步骤4 修改run.sh最后的执行文件名称:
python3.9 evaluate.py
并执行:
./run.sh
最终可以得到测试的精度结果及性能结果。
精度测试指标如下:
分类指标-体位识别准确率 | 姿态估计-关键点检测精度AP | |
---|---|---|
Pytorch框架 | 96.47% | 78.3 |
Mindx-sdk架构 | 95.2% | 77.26 |
注:由于模型一(FasterRcnn)未能正常完成模型转换(算子未适配),是在华为仓内找到的替换模型,精度误差来自相似模型之间的精度差距,与模型二(HRNet-w48)无关。
性能测试结果如下:
在Atlas-200dk上进行对整个测试集上进行性能测试,未进行模型1的推理时间统计(因为该模型来自华为仓内,未进行任何调整,无需加入性能测试),模型2(hrnet-w48)的推理总花费时间为161.89s,fps=3651/161=22.67.原modelzoo下的hrnet-w48在五百张图片上推理耗时551s,fps=1.1.可见本模型在模型上的优化可以很好的提升性能。
6 常见问题
6.1 推理时无法正常读取json文件
问题描述:
在进行精度验证时,读取res_file时出现报错,json.decoder.JSONDecodeError: Extra data
,然后自动退出。
解决方案:
这是因为前序的精度验证时出现其他报错信息,导致json写入了部分不该被写入的缓存区内容。可以直接找到生成的json文件(目录一般为output/results/keypoints_coco_results_0.json
)直接删除即可。