iOS .Tesseract OCR 为啥识别如此纯粹。发动机原理

Posted

技术标签:

【中文标题】iOS .Tesseract OCR 为啥识别如此纯粹。发动机原理【英文标题】:iOS .Tesseract OCR why recognition is so pure. Engine principleiOS .Tesseract OCR 为什么识别如此纯粹。发动机原理 【发布时间】:2013-12-05 14:14:16 【问题描述】:

我有一个关于 Tesseract OCR 原理的问题。据我了解,在形状检测之后,符号(它们的形式)被缩放(调整大小)以具有一些特定的字体大小。 这种字体大小是基于经过训练的数据。基本上,训练集定义了符号(它们的几何形状、形状),也许是它们的表示。

我在 ios 平台上使用 Tesseract 3.01(最新)版本。 我查看了 Tesseract 常见问题解答,查看了论坛,但我不明白为什么对于某些图像我的识别质量很低。

据说字体应该大于 12pt,图像应该有超过 300 DPI。我做了所有必要的预处理,例如模糊(如果需要)、对比度增强。 我什至在 Tesseract OCR 中使用了其他引擎——它被称为 CUBE。

但是对于某些图像(尽管它们更大 MIN(width, height) >1000 - 我为 tesseract 重新缩放它们,我得到了不好的识别结果

http://goo.gl/l9uJMe

但在其他图像集上效果更好:

http://goo.gl/cwA9DC

那些较小的图像我不会调整它们的大小,(只是转换为灰度模式)。

如果我写的关于引擎的内容是正确的。

假设训练集基于大小为 14pt 的字体。图片中的符号被调整到某个特定的大小,我看不出在这种情况下它们没有被识别的任何原因。

我还尝试了自定义词典,以惩罚非词典单词 - 并没有给识别带来太多好处。

tesseract = new tesseract::TessBaseAPI();

GenericVector<STRING> variables_name(1),variables_value(1);
variables_name.push_back("user_words_suffix");
variables_value.push_back("user-words");

int retVal = tesseract->Init([self.tesseractDataPath cStringUsingEncoding:NSUTF8StringEncoding], NULL,tesseract::OEM_TESSERACT_ONLY, NULL, 0, &variables_name, &variables_value, false);
ok |= retVal == 0;
ok |= tesseract->SetVariable("language_model_penalty_non_dict_word", "0.2");
ok |= tesseract->SetVariable("language_model_penalty_non_freq_dict_word", "0.2");

if (!ok)

    NSLog(@"Error initializing tesseract!");

所以我的问题是我应该用另一种字体训练 tesseract 吗?

而且,老实说,我为什么要训练它?在来自 Internet 或 PC(Mac) 的默认训练数据文本上,我得到了很好的识别。

我还检查了原始 tesseract 英语训练数据,它有 38 个 tiff 文件,属于以下系列: 1) 里亚尔 2) 绿地 3)投石机 4次 5) 乔治亚州 6 ) 课程

图片中的字体似乎不属于这个集合。

【问题讨论】:

最新版本是3.02 是的,你是对的。谢谢。 我认为图片应该是(descew & dewarp.)***.com/questions/12275259/… 【参考方案1】:

在您的情况下,图像的大小不是问题。正如我从您所附的图片中看到的那样(我很惊讶之前没有人提到它),问题是图片上的文字会导致您得到不好的结果没有放在直线上。。 p>

Tesseract 在 OCR 过程的早期阶段所做的事情之一是检测图像布局并提取整行文本。

这张图片是说明这部分过程的最佳示例:

如你所见the engine is expecting the text to be perpendicular to the edge of the image。

【讨论】:

【参考方案2】:

如果你完成了所有必要的图像处理,那么试试这个,它可能对你有帮助

 CGSize size = [image size];
 int width = size.width;
 int height = size.height;

 uint32_t* _pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
 if (!_pixels) 
      return;//Invalid image
   

 // Clear the pixels so any transparency is preserved
  memset(_pixels, 0, width * height * sizeof(uint32_t));

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

  // Create a context with RGBA _pixels
  CGContextRef context = CGBitmapContextCreate(_pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

  // Paint the bitmap to our context which will fill in the _pixels array
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);

  // We're done with the context and color space
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    _tesseract->SetImage((const unsigned char *) _pixels, width, height, sizeof(uint32_t), width * sizeof(uint32_t));


    _tesseract->SetVariable("tessedit_char_whitelist", ".#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/-!");
    _tesseract->SetVariable("tessedit_consistent_reps", "0");


    char* utf8Text = _tesseract->GetUTF8Text();
    NSString *str = nil;

   if (utf8Text) 
       str =  [NSString stringWithUTF8String:utf8Text];
     

【讨论】:

谢谢 Katre,我试过了,但没有帮助。现在,我从字符列表(tessedit_char_whitelist)中观察到“垃圾”,而不是看到不同类型的识别垃圾。 通过这段代码,我可以获得 90% 的准确结果。那么可能只是您的图像处理问题。尝试使用您捕获的示例图像,不要处理图像。并查看结果差异。 如果没什么大不了的,您可以在上面提到的“坏”图像之一上尝试 OCR (goo.gl/l9uJMe)。 对于这种类型的图像,我手上没有任何线索,对此感到抱歉。

以上是关于iOS .Tesseract OCR 为啥识别如此纯粹。发动机原理的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中使用 Tesseract OCR 库从图像中识别准确的文本?

iOS Tesseract OCR 图像准备

Tesseract OCR 无法识别除法符号“÷”

光学字符识别。使用tesseract识别里程表

Tesseract-OCR-03-图片文字识别

Python调用Tesseract-OCR完成图片OCR识别