zoukankan      html  css  js  c++  java
  • opencv调用Onnx模型常见问题

    以下都是pytorch模型转换为onnx,然后利用opencv中dnn模块的readNetFromONNX()函数调用后出现的一些问题, 利用onnxruntime库已经验证onnx结果正确。

    相关环境

    python: 3.7.4
    torch: 1.5.0
    onnx: 1.10.2
    onnxruntime: 1.9.0

    一、permute_layer.cpp:138: error: (-215:Assertion failed) (int)_numAxes == inputs[0].size()

    出错原因
    opencv版本:4.5.3
    在网络结构中有一层res = xyz.permute(0, 2, 1) # xyz==> (B, N, C)是对三维数据进行维度变换,cv.dnn目前好像不支持。详细代码可以参考提的issue#21211
    参考#19091说的好像是当前python-opencv会自动把三维输入的第三维转换为彩图的通道数

    尝试解决办法
    考虑先用tensor.view或者tensor.unsqueeze(0)增加一个维度,操作完再用tensor.view或者tensor.squeeze(0)变换为原来的维度。

    有兴趣的可参考#17272尝试其他方法

    二、Unspecified error: Can't create layer "layer_name" of type "Cast" in function getLayerInstance

    出错原因
    opencv版本:4.2.0
    不支持Cast算子

    解决办法

    • 升级opencv版本4.3.0以上
    • 自定义算子 参考https://docs.opencv.org/4.x/dc/db1/tutorial_dnn_custom_layers.html

    三、Unspecified error: Can't create layer "82" of type "ConstantOfShape" in function 'getLayerInstance'

    出错原因
    opencv版本:4.2.0
    不支持ConstantOfShape算子

    解决办法

    • 升级opencv版本4.3.0以上
    • 自定义算子 参考https://docs.opencv.org/4.x/dc/db1/tutorial_dnn_custom_layers.html

    四、onnx_importer.cpp:2146: error: (-2:Unspecified error)

    完整错误

    cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-c2l3r8zm\opencv\modules\dnn\src\onnx\onnx_importer.cpp:2146: error: (-2:Unspecified error) in function 'cv::dnn::dnn4_v20210608::ONNXImporter::handleNode'
    > Node [ConstantOfShape]:(203) parse error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-c2l3r8zm\opencv\modules\dnn\src\onnx\onnx_importer.cpp:1833: error: (-2:Unspecified error) in function 'void __cdecl cv::dnn::dnn4_v20210608::ONNXImporter::handleNode(const class opencv_onnx::NodeProto &)'
    > >  (expected: 'inpShape[i] > 0'), where
    > >     'inpShape[i]' is 0
    > > must be greater than
    > >     '0' is 0
    > 
    

    出错原因
    opencv版本:4.5.3
    在网络结构中有一层B, N, C = inputs.shape torch.zeros(B, C, dtype=torch.long, device=device)是根据已有维度B,C生成一个相同维度的全零tensor, cv.dnn调用的时候shape返回的是tensor,在生成的时候本来应该传入int,这里会导致错误。

    解决办法
    把维度数加上int(), 强制转换为int整数。
    torch.zeros(int(B), int(C), dtype=torch.long, device=device)

    五、Unspecified error: Can't create layer "82" of type "ArgMax" in function 'getLayerInstance'

    出错原因
    opencv版本:4.5.3
    不支持ArgMax算子

    解决办法

    • 自定义算子 参考https://docs.opencv.org/4.x/dc/db1/tutorial_dnn_custom_layers.html
    
    class ArgMaxLayer(object):
        def __init__(self, params, blobs):
            print("params: ", params)
            self.axis = params["axis"]
            self.dim = None
    
        # Our layer receives one inputs. We need to find the max
        def getMemoryShapes(self, inputs):
            print("memory shape", inputs)
            out_dim = []
            input_dim = inputs[0]
            for i in range(len(input_dim)):
                if i != self.axis:
                    out_dim.append(input_dim[i])
            self.dim = out_dim
            return [out_dim]
    
        def forward(self, inputs):
            data = inputs[0]
            print("inputs-: ", type(data), data.dtype)
            print("axis: ", self.axis)
            res = np.argmax(data, axis=self.axis)
    
            # shape = data.shape
            # print("shape: ", shape)
            # res = np.random.randint(0, shape[self.axis], tuple(self.dim), dtype=np.longlong)
    
            print(res, res.shape, res.dtype)
            return [res.astype(np.float32)]
    
    
    cv2.dnn_registerLayer('ArgMax', ArgMaxLayer)
    
    

    六、error: (-215:Assertion failed) pyOutputs[i].size == outputs[i].size in function 'pycvLayer::forward'

    我自定义算子时出现过这种情况,首先检查自定义层中forward函数返回值的维度是否和getMemoryShapes中一致, 则检查下是否遇到以下巨坑
    检查输出维度是否为3维,如果是则可以先把输出(输入)升维,外部调用获取结果后再降维

    七、error: (-215:Assertion failed) pyOutputs[i].type() == outputs[i].type() in function 'pycvLayer::forward'

    我自定义算子时出现过这种情况,自定义层中forward函数返回值类型必须是float32

  • 相关阅读:
    LOJ #2109. 「JLOI2015」骗我呢 数形结合+组合+容斥
    LOJ #2729. 「JOISC 2016 Day 1」俄罗斯套娃 扫描线+贪心
    LOJ #2508. 「AHOI / HNOI2018」游戏 拓扑排序
    LOJ #2106. 「JLOI2015」有意义的字符串 构造+矩阵乘法
    LOJ #2471. 「九省联考 2018」一双木棋 记忆化搜索
    python的md5和base64加密
    [转]python的find()方法
    [转]python的startswith()方法
    获取http请求的响应状态
    with...as...用法
  • 原文地址:https://www.cnblogs.com/xiaxuexiaoab/p/15654972.html
Copyright © 2011-2022 走看看