然后我就想把这个ONNXRUNTIME部署成C++版本的,我先测试了torchvision的预训练模型Faster-RCNN转行为ONNX格式。然后针对测试图像,代码与测试效果如下:
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor])
sess_options = ort.SessionOptions
# Below is for optimizing performance
sess_options.intra_op_num_threads =
24
# sess_options.execution_mode = ort.ExecutionMode.ORT_PARALLEL
sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
ort_session = ort.InferenceSession(
"faster_rcnn.onnx"
, sess_options=sess_options)
src = cv.imread(
"D:/images/cars.jpg"
)
image = cv.cvtColor(src, cv.COLOR_BGR2RGB)
blob = transform(image)
c, h, w = blob.shape
input_x = blob.view(
1
, c, h, w)
def
to_numpy
(tensor)
:
return
tensor.detach.cpu.numpy
if
tensor.requires_grad
else
tensor.cpu.numpy
# compute ONNX Runtime output prediction
ort_inputs = {ort_session.get_inputs[
0
].name: to_numpy(input_x)}
ort_outs = ort_session.run(
None
, ort_inputs)
boxes = ort_outs[
0
]
# boxes
labels = ort_outs[
1
]
# labels
scores = ort_outs[
2
]
# scores
print(boxes.shape, boxes.dtype, labels.shape, labels.dtype, scores.shape, scores.dtype)
index =
0
for
x1, y1, x2, y2
in
boxes:
if
scores[index] >
0.5
:
cv.rectangle(src, (np.int32(x1), np.int32(y1)),
(np.int32(x2), np.int32(y2)), (
0
,
255
,
255
),
1
,
8
,
0
)
label_id = labels[index]
label_txt = coco_names[str(label_id)]
cv.putText(src, label_txt, (np.int32(x1), np.int32(y1)), cv.FONT_HERSHEY_PLAIN,
1.0
, (
0
,
0
,
255
),
1
)
index +=
1
cv.imshow(
"Faster-RCNN Detection Demo"
, src)
cv.waitKey(
0
)
cv.destroyAllWindows
运行结果如下:
然后我把python代码转行为C++的代码,运行结果如下:
发现很多类型都变成
background类型
了,就是类型预测错误了!C++与Python推理使用的label-map文件完全一致,我晕了!
原因与修改
我仔细核对了两边预测输出三个层分别是boxes、labels、scores、解析顺序都没有错!然后我把python中输出三个层数据类型打印出来如下:
print
(
boxes
.shape
,
boxes
.dtype
,
labels
.shape
,
labels
.dtype
,
scores
.shape
,
scores
.dtype
)
输出打印结果如下:
(
100
,
4
)
float32
(
100
,)
int64
(
100
,)
float32
可以证明:
const
int
* labels_prob = ort_outputs[
1
].GetTensorMutableData;
// labels
cv::
Mat
det_labels
(boxes_shape[
0
],
1
, CV_32S, (
int
*)labels_prob)
;
直接用
int类型而不是int64
获取labels数据了,我立刻意识到是因为数据类型不一致导致的内存错误,我知道
OpenCV中有个数据类型是int64
,于是我把第一行代码改成:
const
int64
* labels_prob = ort_outputs[
1
].GetTensorMutableData;
发现OpenCV Mat没有支持int64的,无法创建这样的Mat对象!
所以我放弃了,直接读取数组,代码如下:
int64 classId = labels_prob[i];
std
::
cout
<<
"class id: "
<< classId <<
std
::
endl
;
就这样,再次运行演示程序,发现结果跟python版本的完全一致!
就这样我又改好了一个bug!
模型推理时刻注意C++的中数据类型问题!
最后show一下我的成果:
扫码查看OpenCV+Pytorch系统化学习路线图
CV全栈开发者说 - 从传统算法到深度学习怎么修炼
2022入坑深度学习,我选择Pytorch框架!
Pytorch轻松实现经典视觉任务
教程推荐 | Pytorch框架CV开发-从入门到实战
OpenCV4 C++学习 必备基础语法知识三
OpenCV4 C++学习 必备基础语法知识二
OpenCV4.5.4 人脸检测+五点landmark新功能测试
OpenCV二值图象分析之Blob分析找圆
OpenCV4.5.x DNN + YOLOv5 C++推理
OpenCV4.5.4 直接支持YOLOv5 6.1版本模型推理
返回搜狐,查看更多
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。