Python Tesseract 段错误 11

4 投票
1 回答
2072 浏览
提问于 2025-04-17 20:11

我正在使用tesseract和opencv来读取图像,这是我其他程序的一部分。我写了这段代码是为了找出主程序中的一些错误。test()函数基本上会被复制到最终的程序中。现在我遇到的问题是,tesseract似乎会让python崩溃,出现“段错误11”。这个问题时好时坏。有时候这段示例代码能完全运行,有时候在运行到第56次时就会失败(每次都是这样)。
我安装的所有东西都是通过homebrew安装的(我按照这些说明进行的:https://code.google.com/p/python-tesseract/wiki/HowToCompilePythonTesseractForHomebrewMacMountainLion)。
在寻找解决方案的过程中,我尝试了这个网站上的说明:http://www.janeriksolem.net/2011/12/installing-opencv-python-interface-on.html,我很确定我做的都没错,但我还是偶尔会遇到段错误。

import time
import tesseract
import cv2
import cv2.cv as cv
import Image
def test():
    image0=cv2.imread("test.jpg")
    offset=20
    height,width,channel = image0.shape
    image1=cv2.copyMakeBorder(image0,offset,offset,offset,offset,cv2.BORDER_CONSTANT,value=(255,255,255)) 

    api = tesseract.TessBaseAPI()
    api.Init(".","eng",tesseract.OEM_DEFAULT)
    api.SetPageSegMode(tesseract.PSM_AUTO)
    height1,width1,channel1=image1.shape
    print image1.shape
    print image1.dtype.itemsize
    width_step = width*image1.dtype.itemsize
    print width_step
    #method 1 
    iplimage = cv.CreateImageHeader((width1,height1), cv.IPL_DEPTH_8U, channel1)
    cv.SetData(iplimage, image1.tostring(),image1.dtype.itemsize * channel1 * (width1))
    tesseract.SetCvImage(iplimage,api)

    text=api.GetUTF8Text()
    conf=api.MeanTextConf()
    image=None
    print "..............."
    return (text, conf)

for x in xrange(200):
    print "x: %d" %x
    test()
    print
time.sleep(1)
print "Done"

1 个回答

2

我知道这个回答来得有点晚,但我在使用 OS X Lion、python2.7、OpenCV 2.4 和 Tesseract 3.0 时遇到了同样的问题。

在用 eclipse+pydev 调试的时候,我发现了三个问题……

第一个问题是,给 Tesseract 的图像必须是二进制图像,也就是说,它只能包含黑白两种颜色。

第二个问题是 cv2.imread() 有时候不工作,它会返回一个空的 ndarray。我真的不知道为什么会这样,也许是因为在 eclipse+pydev 中运行 python 的原因。

所以当我尝试使用这个空的 ndarray 的 shapedtype 时,结果是得到了空字符,这导致在使用 cv.SetData() 时生成了一个空的 iplimage。而当 api.GetUTF8Text() 尝试处理这个空的 iplimage 时,一切都崩溃了,出现了一个奇怪的错误,提示“Segmentation Error 11”。

第三个问题是 cv2 和 cv 处理数组的方式非常不同,它们的轴是颠倒的。所以如果你做了类似这样的事情……

image = cv2.imread('something.jpg',0) # flag = 0 is for converting to grayscale
image = cv2.threshold(image,128,255,cv2.THRESH_BINARY)
height,width,channel = image.shape

那么你需要这样做……

iplimage = cv.CreateImageHeader((width,height), cv.IPL_DEPTH_8U, 1)
cv.SetData(iplimage, image.tostring(),image.dtype.itemsize * (width)) #the number of channels is 1

我看到你已经解决了第三个问题。

奇怪的是,如果我在 scr = cv2.imread('textSample.jpg',0) 这一行后面紧接着写 img0 = cv.fromarray(scr),那么一切就正常了。

试试下面的代码,使用图像 "textSample.jpg"(在这篇文章的底部),并取消注释那些行(除了第一行,它不是注释),这样你就可以看到你的代码正在处理什么图像。scrimg0img1 最终应该是一样的:

#!/usr/bin/env python

import cv2
import cv2.cv as cv
import tesseract

scr = cv2.imread('textSample.jpg',0)
#img0 = cv.fromarray(scr)
#cv.SaveImage('img0.jpg',img0)

api = tesseract.TessBaseAPI()
api.Init(".","eng",tesseract.OEM_DEFAULT)
api.SetPageSegMode(tesseract.PSM_AUTO)

image = cv.CreateImageHeader((scr.shape[1],scr.shape[0]), cv.IPL_DEPTH_8U, 1)
cv.SetData(image, scr.tostring(), scr.dtype.itemsize*scr.shape[1])

#cv.SaveImage('img1.jpg',image)

tesseract.SetCvImage(image,api)
text=api.GetUTF8Text()
conf=api.MeanTextConf()

print text
print conf

你应该得到类似这样的结果……

OE3456789
!"#$%&'()* .-./

76

textSample.jpg

撰写回答