【问题标题】:Forward method error in DNN module of OpenCV (Ptyhon) using .onnx model使用 .onnx 模型的 OpenCV(Ptyhon)的 DNN 模块中的前向方法错误
【发布时间】:2021-04-06 11:39:40
【问题描述】:

我想测试从这里下载的预训练模型以执行 ocr 任务。 Link to download,它的名字是CRNN_VGG_BiLSTM_CTC.onnx。此模型是从here 中提取的。 sample-image.png 可以从here 下载(见下面的代码)。

当我在 blob 中执行神经网络的前向预测 (ocr) 时,出现以下错误:

错误:OpenCV(4.4.0)/tmp/pip-req-build-xgme2194/opencv/modules/dnn/src/layers/convolution_layer.cpp:348:错误:(-215:断言失败)ngroups > 0 && inpCn % ngroups == 0 && outCn % ngroups == 0 在函数“getMemoryShapes”中

请随意阅读下面的代码。我尝试了很多东西,这很奇怪,因为这个模型不需要预先确定的输入形状。如果您知道任何方法来阅读此模型并进行转发,它也会有所帮助,但我宁愿使用 OpenCV 解决。

import cv2 as cv
# The model is downloaded from here https://drive.google.com/drive/folders/1cTbQ3nuZG-EKWak6emD_s8_hHXWz7lAr
# model path 
modelRecognition = os.path.join(MODELS_PATH,'CRNN_VGG_BiLSTM_CTC.onnx')
# read net 
recognizer = cv.dnn.readNetFromONNX(modelRecognition)

# Download sample_image.png from https://i.ibb.co/fMmCB7J/sample-image.png  (image host website)
sample_image = cv.imread('sample-image.png')
# Height , Width and number of channels of the image
H, W, C = sample_image.shape

# Create a 4D blob from cropped image
blob = cv.dnn.blobFromImage(sample_image, size = (H, W))

recognizer.setInput(blob)

# Here is where i get the errror that I mentioned before 
result = recognizer.forward()

非常感谢您。

【问题讨论】:

    标签: python opencv conv-neural-network


    【解决方案1】:

    您的问题实际上是您提供给模型的输入数据与训练模型所依据的数据的形状不匹配。

    我使用this answer 来检查您的onnx 模型,它似乎需要一个形状为(1, 1, 32, 100) 的输入。我修改了您的代码以将图像重塑为1 x 32 x 100 像素,并且推理实际上运行没有错误。

    编辑

    我添加了一些代码来解释推理的结果。我们现在显示图像和推断的 OCR 文本。 这似乎不起作用,但阅读the tutorial on OpenCV,应该有两个模型:

    1. 检测图像中文本的位置。该网络接受各种尺寸的图像,它返回图像中文本的位置,然后将图像的部分裁剪,尺寸为 100x32 的图像传递给第二个
    2. 实际执行“读取”并给定图像块的人会返回字符。为此,有一个文件alphabet_36.txt 与预训练模型一起提供。

    我不清楚使用哪个网络进行文本检测。希望下面编辑的代码可以帮助您进一步开发您的应用程序。

    import cv2 as cv
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    # The model is downloaded from here https://drive.google.com/drive/folders/1cTbQ3nuZG-EKWak6emD_s8_hHXWz7lAr
    # model path 
    MODELS_PATH = './'
    modelRecognition = os.path.join(MODELS_PATH,'CRNN_VGG_BiLSTM_CTC.onnx')
    
    # read net 
    recognizer = cv.dnn.readNetFromONNX(modelRecognition)
    
    # Download sample_image.png from https://i.ibb.co/fMmCB7J/sample-image.png  (image host website)
    sample_image = cv.imread('sample-image.png', cv.IMREAD_GRAYSCALE)
    sample_image = cv.resize(sample_image, (100, 32))
    sample_image = sample_image[:,::-1].transpose()
    
    # Height and Width of the image
    H,W = sample_image.shape
    
    # Create a 4D blob from image
    blob = cv.dnn.blobFromImage(sample_image, size=(H,W))
    recognizer.setInput(blob)
    
    # network inference
    result = recognizer.forward()
    
    # load alphabet
    with open('alphabet_36.txt') as f:
        alphabet = f.readlines()
    alphabet = [f.strip() for f in alphabet]
    
    # interpret inference results
    res = []
    for i in range(result.shape[0]):
        ind = np.argmax(result[i,0])
        res.append(alphabet[ind])
    ocrtxt = ''.join(res)
    
    # show image and detected OCR characters
    plt.imshow(sample_image)
    plt.title(ocrtxt)
    plt.show()
    

    希望对您有所帮助。 干杯

    【讨论】:

    • 你好,克里斯蒂安,非常感谢你的回答。我非常有信心这个网络的架构不需要固定的输入大小(因为它们内部的卷积操作),但我错了。这样的错误!你肯定解决了我发布的问题,因此应该得到标记为正确的答案。然而,这个网络是用于 OCR 模型的,你知道为什么调整到 100,32 会有意义吗?我认为这个 ocr 模型适用于文字。但也许这个模型只适用于字符,它需要的是以前的分割模型?
    • 如果您想分享您对此的想法,那将非常有帮助。提前非常感谢您!
    • 你好汤姆,不客气!好吧,我不熟悉这个特定的网络(你在某处有它的架构吗,来自一篇论文?)但如果它在卷积层之后有完全连接的层,那么网络实际上取决于输入的形状。
    • 关于调整大小是否有意义,这是一个很好的问题。如果字符的大小调整大小后与训练时的大小大致相同,这是有道理的。否则,网络可能很难返回正确的字符。
    • 嗨,汤姆,在我的回答中查看我的编辑,希望对您有所帮助
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多