我正在尝试使用openCV从图像中隔离文本,然后再将其发送到tesseract4引擎以最大程度地提高结果。

我找到了这个interesting post,因此决定复制源代码并通过mysdelf尝试

但是我对first call to OpenCV遇到了问题

复制:

  • 只需复制要点
  • 的代码
  • 启动命令script.py /path/to/image.jpg

  • 我遇到了问题:Required argument 'threshold2' (pos 4) not found
    您可能知道这意味着什么吗?
    我是javascript,java和bash脚本开发人员,但不是python ...

    在一个简单的版本中:
    import glob
    import os
    import random
    import sys
    import random
    import math
    import json
    from collections import defaultdict
    
    import cv2
    from PIL import Image, ImageDraw
    import numpy as np
    from scipy.ndimage.filters import rank_filter
    
    if __name__ == '__main__':
        if len(sys.argv) == 2 and '*' in sys.argv[1]:
            files = glob.glob(sys.argv[1])
            random.shuffle(files)
        else:
            files = sys.argv[1:]
    
        for path in files:
            out_path = path.replace('.jpg', '.crop.png')
            if os.path.exists(out_path): continue
            orig_im = Image.open(path)
            edges = cv2.Canny(np.asarray(orig_im), 100, 200)
    

    在此先感谢您的帮助

    最佳答案

    编辑:好的,所以这个答案显然是错误的,因为我试图将自己的16位int图像发送到函数中,并且无法重现结果。

    Edit2:因此,我可以使用以下代码重现该错误:

    from PIL import Image
    import numpy as np
    import cv2
    
    orig_im = Image.open('opencv-logo2.png')
    
    threshold1 = 50
    threshold2 = 150
    edges = cv2.Canny(orig_im, 50, 100)
    



    因此,如果图像未转换为数组,即传入Image类,则会收到错误消息。 PIL Image类是除与其关联的图像数据外还有很多其他东西的类,因此必须将其转换为np.array才能传递给函数。但是,如果将其正确转换,一切对我来说都是膨胀的。

    在与Dan Mašek聊天时,我的以下想法有些错误。确实,较新的Canny()方法需要16位图像,但是绑定(bind)不会查看实际的numpy dtype,以查看它决定使用哪个函数调用的位深度。另外,如果您尝试实际发送uint16图像,则会收到其他错误:
    edges = cv2.Canny(np.array([[0, 1234], [1234, 2345]], dtype=np.uint16), 50, 100)
    



    因此,我最初给出的答案(下)不是罪魁祸首。也许您不小心删除了np.array()orig_im强制转换并得到了该错误,或​​者其他奇怪的事情还在继续。

    原始(错误)答案

    在OpenCV 3.2.0中,引入了Canny()的新方法,以允许用户指定自己的渐变图像。在原始实现中,Canny()将使用Sobel()运算符来计算梯度,但是现在您可以计算出Scharr()导数,并将其传递给Canny()。所以这很酷。但这与您的问题有什么关系?
    Canny()方法已重载。然后根据发送的参数来决定要使用哪个函数。带有所需参数的Canny()的原始调用如下所示:
    cv2.Canny(image, threshold1, threshold2)
    

    但是新的重载方法看起来像
    cv2.Canny(grad_x, grad_y, threshold1, threshold2)
    

    现在,您的错误消息中有一个提示:



    这些调用中的哪一个在位置4具有threshold2?较新的方法调用!那么,如果只传递三个参数,为什么要调用该函数呢?请注意,如果您使用的是PIL图像,则会收到错误消息,但如果您使用的是numpy图像,则不会出错。那么,还有哪些其他原因使您假设您正在使用新电话呢?

    如果检查OpenCV 3.3.0 Canny() docs,则会看到原始Canny()调用要求第一个位置参数为 8位输入图像,而新的Canny()调用要求输入图像为 16位x派生(CV_16SC1或CV_16SC3 )作为第一个位置参数。

    将两个和两个放在一起,PIL为您提供了一个16位输入图像,因此OpenCV认为您正在尝试调用新方法。

    因此,如果您想继续使用PIL,这里的解决方案是将图像转换为8位表示形式。 Canny()首先需要运行一个单 channel (即灰度)图像。因此,您首先需要确保image是单 channel 的,然后对其进行缩放并更改numpy dtype。我相信PIL会将灰度图像读取为单 channel (默认情况下,OpenCV会将所有图像读取为三 channel ,除非您另有说明)。

    如果图像是16位的,那么使用numpy可以很容易地进行转换:
    img = (img/256).astype('uint8')
    

    假设img是一个numpy数组,因此您首先需要使用ndarraynp.array()将PIL图像转换为np.asarray()

    然后,您应该能够使用原始函数调用运行Canny()

    10-08 15:33