PaddleOCR 尝试OpenCV-DNN/onnxruntime推理

PaddleOCR 尝试下OpenCV-DNN推理

文章目录

    • 说明:
    • 环境:
    • 过程:
    • 不足:
    • 引用:

说明:

  • 本文基于PaddleOCR源码改写,修改部分前处理和模型推理相关代码。需要opencv即可推理。目前测试paddleocr v2版本可行。

完整代码:https://github.com/VITA-Alchemy/PaddleOCR-OpenCV-DNN

环境:

onnx 1.11.0
onnxruntime 1.10.0
opencv 4.5.5.62
paddle2onnx 1.0.1
paddlpaddle 2.3.2

过程:

  1. 准备

paddleocr v2 模型 :det 模型,rec模型
Netron 查看模型结构
onnx-simplifier

  1. 转换模型
  • 使用paddle2onnx 转换模型:
  • 重要:dnn推理需要固化输入shape,onnxruntime支持动态shape不需要固化。
  • 这里固化尺寸,需要使用Netron查看模型中写死的shape,需要根据自己需求设置原来动态的参数(如下图 输入为 ?x3x640x640 说明只有nchw中n可以固化。)。
    PaddleOCR 尝试OpenCV-DNN/onnxruntime推理_第1张图片
#检测模型
 paddle2onnx -m paddle2onnx.optimize --model_dir .\ch_ppocr_mobile_v2.0_det_infer\ --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file ./ch_ppocr_mobile_v2.0_det_infer/model.onnx --opset_version 10 --input_shape_dict="{'x':[1,3,640,640]}" --enable_onnx_checker True --enable_dev_version False
#识别模型
paddle2onnx -m paddle2onnx.optimize --model_dir ./ch_ppocr_mobile_v2.0_rec_infer --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file ./ch_ppocr_mobile_v2.0_rec_infer/model.onnx --opset_version 10 --input_shape_dict="{'x':[1,3,32,1000]}" --enable_onnx_checker True --enable_dev_version False
  1. onnx模型simplifier

这里直接使用在线简化 :https://convertmodel.com/

  1. 修改det模型前处理、后处理
  • 图像缩放paddleOCR源码中提供了几种resize模式都是对应动态shape的,这部分需要修改成固定尺寸的resize;对应就是长边缩放到640,短边等比缩放不足部分填充0;
# 直接在源码中修改的部分代码
def resize_image_type2(self, img):
        h, w, _ = img.shape
        resize_w = w
        resize_h = h
        if resize_h > resize_w:
            ratio = float(self.resize_long) / resize_h
        else:
            ratio = float(self.resize_long) / resize_w
        resize_h = int(resize_h * ratio)
        resize_w = int(resize_w * ratio)
        img = cv2.resize(img, (resize_w, resize_h))
        #这里加个0填充,适配固定shape模型
        img = self.image_padding_640(img)
        return img, [ratio, ratio]
  • box的后处理,需要放到到原图大小,对应源码boxes_from_bitmap函数修改
 def boxes_from_bitmap(self, pred, _bitmap, dest_width, dest_height,ratio):
        '''
        _bitmap: single map with shape (1, H, W),
                whose values are binarized as {0, 1}
        '''
        bitmap = _bitmap
        #height, width = bitmap.shape  
        #长宽都乘以缩放比,还原到原来大小
        height, width = dest_height*ratio, dest_width*ratio,
  1. 修改rec模型前处理
  • 修改res模型输入图片的预处理,主要是输入尺寸
	# 这里 imgC, imgH, imgW 改成自己模型对应的shape
    def resize_norm_img(self, img):
   		# self.model_shape = [3,32,1000]
        imgC, imgH, imgW = [int(v) for v in self.model_shape]
        assert imgC == img.shape[2]
        h, w = img.shape[:2]
        ratio = w / float(h)
  1. 结果
opencv dnn :[('使用深度学习和OpenCV进行目标检测', 0.9423162), ('基于深度学习的对象检测时,您可能会遇到三种主要的对象检测方法:', 0.9942412), ('·Faster R-CNNs(Ren etal,2015)', 0.9131796), ('You Only Look Once (YOLO)(Redmon et al,2015)', 0.9224724), ('SingleShotDetectors(ssD)(Liu等人,2015年)', 0.9578045), ('FasterR-CNNs可能是使用深度学习进行对象检测最“听说”的方法;然而,该技术可能难以理', 0.9848377), ('解(特别是对于深度学习的初学者)、难以实施且难以训练。', 0.9785821), ('此外,即使使用“更快”的R-CNN实现(其中“R”代表“区域提议”),算法也可能非常慢', 0.9776404), ('大约为7FPS。', 0.96622694), ('如果追求纯粹的速度,那么我们倾向于使用YOLO,因为这种算法要快得多,能够在Titan×GPU', 0.98800766), ('上处理40-90FPS。YOLO的超快变体甚至可以达到155FPS。', 0.9868126), ('YOLO的问题在于它的准确性不高。', 0.98904663), ('最初由Google开发的SSD是两者之间的平衡。该算法比FasterR-CNN更直接', 0.9916604)]
------------------------------
onnxruntime :[('使用深度学习和OpenCV进行目标检测', 0.94230413), ('基于深度学习的对象检测时,您可能会遇到三种主要的对象检测方法:', 0.99423134), ('·Faster R-CNNs(Ren etal,2015)', 0.9131659), ('You Only Look Once (YOLO)(Redmon et al,2015)', 0.9224635), ('SingleShotDetectors(ssD)(Liu等人,2015年)', 0.9577948), ('FasterR-CNNs可能是使用深度学习进行对象检测最“听说”的方法;然而,该技术可能难以理', 0.98482645), ('解(特别是对于深度学习的初学者)、难以实施且难以训练。', 0.9785724), ('此外,即使使用“更快”的R-CNN实现(其中“R”代表“区域提议”),算法也可能非常慢', 0.9776268), ('大约为7FPS。', 0.96620893), ('如果追求纯粹的速度,那么我们倾向于使用YOLO,因为这种算法要快得多,能够在Titan×GPU', 0.9879988), ('上处理40-90FPS。YOLO的超快变体甚至可以达到155FPS。', 0.98680395), ('YOLO的问题在于它的准确性不高。', 0.9890286), ('最初由Google开发的SSD是两者之间的平衡。该算法比FasterR-CNN更直接', 0.99165064)]

不足:

  • 由于固化模型shape,使得部分特殊场景下效果不良,如长条形图片,降低了通用性;可根据自己对应的场景去固化模型尺寸(通用场景下建议导出dynamic shape模型,使用onnxruntime推理)。

  • 相同图片下(前后处理一致),速度方面DNN比onnxruntime慢(大约2~3倍)。

  • 精度未与原始paddle模型对比;简单测试效果尚可。

  • 测试PaddleOCR v3版本,det模型dnn支持,rec模型dnn推理失败

引用:

https://github.com/PaddlePaddle/PaddleOCR
https://github.com/PaddlePaddle/Paddle2ONNX
https://github.com/daquexian/onnx-simplifier
https://blog.csdn.net/favorxin/article/details/115270800

你可能感兴趣的:(深度学习部署,opencv,dnn,计算机视觉)