香橙派 OrangePi AIpro 目标检测:Two‑Stage Detector 开发模式及内容
一、摘要
Two‑Stage Detector 两阶段目标检测代表算法为 Faster R‑CNN、Mask R‑CNN,分为候选框生成(RPN 区域建议网络)与第二阶段 ROI‑Head 分类回归,检测精度高,适合边缘工业检测、缺陷识别等场景;对比 YOLO 等单阶段算法,计算链路复杂、多输出、Proposal 算子对 NPU 部署有特殊要求。
OrangePi AIpro 搭载昇腾 310B4 AI 处理器,支持 FP16/INT8 离线 om 模型推理,但 Two‑Stage 模型不能直接把 PyTorch/Torch 导出 ONNX 直接运行,存在几个部署难点:
-
RPN Proposal 候选框生成包含大量动态 shape 逻辑,ATC 转换容易出现动态算子报错;
-
多输出:RPN 输出 anchors、proposal,ROI 输出类别、框偏移;
-
ROI Align 算子需要 CANN 算子库支持;
-
后处理 NMS、坐标还原需要 CPU 侧实现,无法全部放入模型内部。
区分两种部署形态:
-
完整端到端模型:网络内部集成 Proposal、NMS;
-
拆分式部署:RPN 网络输出交给 CPU 做 Proposal 后,再送入 ROI Head,降低模型转换难度。
适用场景
-
工业缺陷检测,对检测框精度要求高,允许中等推理时延;
-
边缘摄像头场景,基于 OrangePi AIpro 做本地高精度目标检测;
-
教学实验,学习两阶段检测器在昇腾边缘硬件完整部署链路。
前置约束:开发板预先部署 CANN 驱动、AscendCL 运行时环境;原始模型优先导出去掉后处理的 ONNX,NMS、坐标解码放到应用代码中实现。
二、Two‑Stage Detector 开发模式
2.1 三种开发接入模式
|
开发模式 |
适用场景 |
OrangePi AIpro 接入方式 |
核心特点 |
|
端到端 om 模型模式(优先尝试) |
算子全部兼容,动态 shape 可控 |
MMDeploy 导出 ONNX,ATC 转换 om,AIPP 做图像预处理 |
代码简洁;Proposal、ROIAlign 算子兼容性要求高,转换失败概率较高 |
|
模型拆分推理模式(推荐生产) |
Proposal 算子转换报错,边缘部署 |
拆分为 Backbone+RPN、ROI‑Head 两个 om 模型;CPU 做 Proposal 处理 |
稳定性高;两次推理,应用层逻辑复杂 |
|
MindSpore 在线推理模式 |
算法调试、教学原型 |
MindSpore 加载 FasterRCNN 网络,昇腾在线推理 |
不适合高吞吐业务,适合算法验证 |
注意:Two‑Stage 模型尽量避免把 NMS 算子嵌入 ONNX 内部,建议移到 Python 应用层,降低模型转换失败概率。
2.2 整体数据流
原始图像 → OpenCV读取预处理缩放归一化 → AIPP/CPU预处理
→ 送入Backbone+RPN离线om推理 → 获取RPN输出anchors、box delta
→ CPU执行Proposal筛选候选框 → 候选框与特征图送入ROI‑Head om推理
→ CPU后处理:坐标解码、NMS过滤 → 绘制检测框输出结果
2.3 关键约束(OrangePi AIpro 部署重点)
-
soc_version 必须指定
Ascend310B4,否则 om 无法在香橙派 AIpro 上加载运行; -
ROIAlign、Proposal 对动态输入敏感,转换时合理设置
--dynamic_dims; -
两阶段两次推理之间候选框数据在 CPU 内存交互,候选框数量需要限制;
-
INT8 量化会对两阶段检测精度带来明显损失,优先 FP16 推理;
-
开发板内存有限,输入分辨率不宜设置过高,防止内存 OOM。
三、核心模块内容详解
3.1 Two‑Stage 网络结构
-
Backbone+FPN:图像提取多尺度特征;
-
RPN Head:生成锚框、前景背景分类、框偏移,输出大量候选 Proposal;
-
ROI Align:根据 Proposal 从特征图抠取 ROI 特征;
-
ROI‑Head:完成对候选框的分类与坐标回归。
3.2 核心接口与工具
-
MMDeploy:将 MMDetection 的 Faster‑RCNN 导出拆分式 ONNX 模型;
-
ATC 工具:ONNX 转 om 离线模型;
-
AscendCL:开发板侧 Python 接口 aclruntime,加载 om 执行推理;
-
CPU 侧:Proposal 解码、NMS 非极大抑制、坐标映射还原。
3.3 对接 OrangePi AIpro 要点
预处理可以选择 CPU 做或者 AIPP 配置文件;Two‑Stage 后处理逻辑复杂,大部分逻辑在 ARM CPU 完成,NPU 只负责张量推理计算;可以通过 npu_smi 查看昇腾芯片负载状态。
四、代码实战
环境依赖:OrangePi AIpro,CANN6.3.RC1,AscendCL,opencv‑python,numpy;示例采用拆分式部署模式。
4.1 ATC 模型转换命令(RPN 子网络)
atc --model=faster_rcnn_rpn.onnx \
--framework=5 \
--soc_version=Ascend310B4 \
--output=faster_rcnn_rpn.om \
--input_shape="input:1,3,800,1333" \
--dynamic_dims="proposal_num:1~300" \
--insert_op_conf=aipp.cfg
# ROI‑Head子网络转换
atc --model=faster_rcnn_roi.onnx \
--framework=5 \
--soc_version=Ascend310B4 \
--output=faster_rcnn_roi.om
4.2 推理主代码(基于 aclruntime)
import numpy as np
import cv2
from aclruntime import AclModel
def proposal_decode(rpn_bbox, rpn_cls, anchors, conf_threshold=0.5):
"""CPU侧RPN候选框解码,Two‑Stage关键后处理"""
proposals = []
num_anchor = anchors.shape[0]
for i in range(num_anchor):
score = rpn_cls[i,1]
if score < conf_threshold:
continue
dx, dy, dw, dh = rpn_bbox[i]
xa, ya, wa, ha = anchors[i]
x1 = xa + dx * wa
y1 = ya + dy * ha
w = np.exp(dw) * wa
h = np.exp(dh) * ha
proposals.append([x1,y1,x1+w,y1+h, score])
return np.array(proposals)
def nms(dets, iou_thresh=0.45):
"""NMS非极大抑制CPU实现"""
if len(dets)==0:
return np.empty((0,5))
x1,y1,x2,y2,scores = dets[:,0],dets[:,1],dets[:,2],dets[:,3],dets[:,4]
areas = (x2-x1+1)*(y2-y1+1)
order = scores.argsort()[::-1]
keep = []
while order.size>0:
i = order[0]
keep.append(i)
xx1 = np.maximum(x1[i],x1[order[1:]])
yy1 = np.maximum(y1[i],y1[order[1:]])
xx2 = np.minimum(x2[i],x2[order[1:]])
yy2 = np.minimum(y2[i],y2[order[1:]])
w = np.maximum(0, xx2‑xx1+1)
h = np.maximum(0, yy2‑yy1+1)
inter = w*h
iou = inter/(areas[i]+areas[order[1:]]‑inter)
idx = np.where(iou<=iou_thresh)[0]
order = order[idx+1]
return dets[keep]
if __name__ == "__main__":
# 加载两个子模型
rpn_model = AclModel("./faster_rcnn_rpn.om")
roi_model = AclModel("./faster_rcnn_roi.om")
img = cv2.imread("test.jpg")
img_in = cv2.resize(img,(1333,800)).astype(np.float32).transpose(2,0,1)
img_in = np.expand_dims(img_in,0)
# 第一阶段推理RPN
rpn_out = rpn_model.infer([img_in])
rpn_bbox_pred, rpn_cls_pred, anchors = rpn_out
# CPU处理Proposal候选框
proposals = proposal_decode(rpn_bbox_pred[0], rpn_cls_pred[0], anchors[0])
proposals = nms(proposals, iou_thresh=0.6)
proposals = proposals[:300,0:4]
# 第二阶段ROI‑Head推理
roi_out = roi_model.infer([img_in, proposals.astype(np.float32)])
roi_cls, roi_bbox = roi_out
print(f"检测完成,目标数量:{len(proposals)}")
五、常见问题与调优实践
Q1:ATC 转换报错 ROIAlign 算子不支持
-
根因:CANN 算子版本不匹配,ONNX 算子属性不兼容;
-
解决:升级 CANN,使用 MMDeploy 指定算子版本导出,拆分模型,ROI 逻辑放到 CPU。
Q2:推理结果框全部偏移、坐标不对
-
根因:图像预处理归一化、AIPP 参数和训练不匹配;Proposal 解码逻辑错误;
-
解决:核对均值方差,校验 proposal_decode 坐标变换。
Q3:推理速度慢,FPS 很低
-
根因:两阶段两次推理;CPU 后处理 Proposal、NMS 占用大量 ARM 时间;
-
解决:限制候选框最大数量,降低输入分辨率;优化 NMS 代码。
Q4:om 模型加载失败
-
根因:转换时 soc_version 写错,不是 Ascend310B4;om 是其他昇腾芯片生成;
-
解决:重新执行 atc,指定正确 soc_version。
六、总结
OrangePi AIpro 部署 Two‑Stage Detector(Faster R‑CNN)分为端到端 om、模型拆分推理、MindSpore 在线推理三种模式,工程实践优先模型拆分推理模式,规避 Proposal、ROIAlign 算子转换风险。
开发关键点:
-
Two‑Stage 检测器后处理复杂,Proposal 解码、NMS 建议放在 CPU 应用层,不嵌入模型;
-
ATC 转换必须设置
soc_version=Ascend310B4适配香橙派 AIpro 硬件; -
两阶段为两次推理,候选框数量做限制,控制 ARM‑NPU 之间数据交互开销;
-
优先 FP16 推理,INT8 量化容易造成检测 mAP 精度下降;
-
完成部署后对比 GPU 原始输出,校验坐标、类别、置信度精度对齐。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)