Tesseract OCR简单示例

35

大家好,能否给我一个简单的Tesseract OCR测试例子,最好是使用C#。
我尝试了在这里找到的演示程序。 我下载了英文数据集并解压到C盘,并按以下方式修改了代码:

string path = @"C:\pic\mytext.jpg";
Bitmap image = new Bitmap(path);
Tesseract ocr = new Tesseract();
ocr.SetVariable("tessedit_char_whitelist", "0123456789"); // If digit only
ocr.Init(@"C:\tessdata\", "eng", false); // To use correct tessdata
List<tessnet2.Word> result = ocr.DoOCR(image, Rectangle.Empty);
foreach (tessnet2.Word word in result)
    Console.WriteLine("{0} : {1}", word.Confidence, word.Text);

很不幸,代码无法工作。程序停在“ocr.Init(...)"这一行。即使使用try-catch也无法得到任何异常。

我能够运行vietocr!但对我来说,那是一个非常庞大的项目,我需要像上面那样简单的示例。


1
“它不工作”是什么意思?是崩溃了还是没有按照你的意愿执行? - Jesus Ramos
好的,程序没有任何错误或异常就关闭了。它也没有将输出写入控制台。因此,我进行了逐行调试,并发现程序在第5行退出 -> ocr.Init(@“C:\ tessdata \”,“eng”,false); - Will Robinson
1
你可以进入函数并找出导致程序退出的原因。 - Jesus Ramos
加载C盘下的tessdata可能存在权限问题吗?您可以尝试更改路径并重试。 - Rachel
该函数位于tessnet dll中。我无法进入它!这是一台Windows 7机器,我以管理员身份登录。我不明白为什么会有权限问题。我甚至没有其他驱动器。 - Will Robinson
9个回答

21

好的,我在这里找到了解决方案: tessnet2加载失败 由Adam提供的答案。

显然我使用了错误版本的tessdata。我直觉地按照源页面上的说明操作导致了问题。

说明如下:

快速使用Tessnet2

  1. 在此处下载二进制文件,并将程序集Tessnet2.dll添加为.NET项目的引用。

  2. 在此处下载语言数据定义文件,并将其放置在tessdata目录中。Tessdata目录和您的exe文件必须在相同的目录中。

在您下载二进制文件之后,当您跟随链接下载语言文件时,会出现许多语言文件,但没有一个是正确的版本。你需要选择所有版本并转到下一页以获取正确的版本(tesseract-2.00.eng)!他们应该更新下载二进制文件链接到第3版或将第2版语言文件放在第一页。或者至少要粗体提到这个版本问题是一个大问题!

不管怎样,我找到了它。 谢谢大家。


@ Will Robinson,我也遇到了同样的问题。我尝试了你上面的步骤...但仍然遇到了你曾经遇到的问题。首先,我从你的链接中下载了二进制文件并将其解压到我的桌面上。然后从Release32文件夹中添加tessnet2_32.dll文件的引用。其次,我从你的链接中下载了LDD文件,并将文件提取到我的桌面上。它有一个名为tessdata的目录,并将其放在我的项目bin\debug文件夹中(我的项目exe也在这个文件夹中)。但是我现在仍然遇到同样的问题...请帮助我解决这个问题... - Saravanan
你尝试下载正确版本的tessdata了吗? tesseract-2.00.eng位于第二页列表的末尾。 - Will Robinson
@Will Robinson:我的VS是2008,Windows XP(32位)。我按照你的指示操作了,但没有成功。它运行到“tessocr.Init…”这一行,然后VS停止执行,没有任何错误消息或异常。作为解决方法,我已经下载了一个包含英语语言包的tesseract-3.00版本(http://code.google.com/p/tesseract-ocr/downloads/detail?name=tesseract-ocr-3.02.02.tar.gz&can=2&q=)。 - derloopkat

15

在C#中测试Tesseract OCR的简单示例:

    public static string GetText(Bitmap imgsource)
    {
        var ocrtext = string.Empty;
        using (var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.Default))
        {
            using (var img = PixConverter.ToPix(imgsource))
            {
                using (var page = engine.Process(img))
                {
                    ocrtext = page.GetText();
                }
            }
        }

        return ocrtext;
    }

信息:存储库中必须存在tessdata文件夹:bin\Debug\


2
我运行了这段代码,调试时出现了“无法找到平台x86的库“liblept172.dll”。”的错误。该错误发生在第一个using语句处。我已经找到了liblept172.ddl并将其复制到了bin文件夹中,实际上我已经复制到了很多地方,但都没有用。我正在使用来自NuGet的Tesseract v3.0.2。我找不到tessnet2,因为互联网上所有链接都似乎已经失效了。 - Ewan
3
这里的“PixConverter”是什么?在“Tesseract”软件包中似乎没有这样命名的类。 - shashwat
请参阅此链接以获取与 Tesseract 相关的代码:https://github.com/charlesw/tesseract/blob/master/src/Tesseract/PixConverter.cs - A Petrov
我也无法像这样运行它,但我将PixConverter部分更改为using (var img = Pix.LoadFromFile(imgsource)),现在它可以正常工作了。 - A Petrov

6
我按照这些 说明 操作,成功使其工作。
  • 下载示例代码 Tesseract sample code

  • 将其解压缩到新位置。

  • 打开~\tesseract-samples-master\src\Tesseract.Samples.sln(我使用的是Visual Studio 2017)。

  • 为该项目安装Tesseract NuGet包(或卸载/重新安装,因为我不得不这样做)NuGet Tesseract

  • 取消注释Tesseract.Samples.Program.cs中的最后两行有意义的代码:Console.Write("Press any key to continue . . . "); Console.ReadKey(true);

  • 运行(按F5键)。

  • 您应该会得到这个Windows控制台输出 enter image description here


1

尝试将该行更新为:

ocr.Init(@"C:\", "eng", false); // 这里的路径应该是tessdata的父文件夹


刚试了一下,问题还是一样。 - Will Robinson

0

这对我很有用,我有3-4个PDF转文本提取器,如果一个不起作用,另一个就会起作用...特别是Tesseract,此代码可用于Windows 7、8、Server 2008。希望对您有所帮助。

    do
    {
    // Sleep or Pause the Thread for 1 sec, if service is running too fast...
    Thread.Sleep(millisecondsTimeout: 1000);
    Guid tempGuid = ToSeqGuid();
    string newFileName = tempGuid.ToString().Split('-')[0];
    string outputFileName = appPath + "\\pdf2png\\" + fileNameithoutExtension + "-" + newFileName +
                            ".png";
    extractor.SaveCurrentImageToFile(outputFileName, ImageFormat.Png);
    // Create text file here using Tesseract
    foreach (var file in Directory.GetFiles(appPath + "\\pdf2png"))
    {
        try
        {
            var pngFileName = Path.GetFileNameWithoutExtension(file);
            string[] myArguments =
            {
                "/C tesseract ", file,
                " " + appPath + "\\png2text\\" + pngFileName
            }; // /C for closing process automatically whent completes
            string strParam = String.Join(" ", myArguments);

            var myCmdProcess = new Process();
            var theProcess = new ProcessStartInfo("cmd.exe", strParam)
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                WindowStyle = ProcessWindowStyle.Minimized
            }; // Keep the cmd.exe window minimized
            myCmdProcess.StartInfo = theProcess;
            myCmdProcess.Exited += myCmdProcess_Exited;
            myCmdProcess.Start();

            //if (process)
            {
                /*
                MessageBox.Show("cmd.exe process started: " + Environment.NewLine +
                                "Process Name: " + myCmdProcess.ProcessName +
                                Environment.NewLine + " Process Id: " + myCmdProcess.Id
                                + Environment.NewLine + "process.Handle: " +
                                myCmdProcess.Handle);
                */
                Process.EnterDebugMode();
                //ShowWindow(hWnd: process.Handle, nCmdShow: 2);
                /*
                MessageBox.Show("After EnterDebugMode() cmd.exe process Exited: " +
                                Environment.NewLine +
                                "Process Name: " + myCmdProcess.ProcessName +
                                Environment.NewLine + " Process Id: " + myCmdProcess.Id
                                + Environment.NewLine + "process.Handle: " +
                                myCmdProcess.Handle);
                */
                myCmdProcess.WaitForExit(60000);
                /*
                MessageBox.Show("After WaitForExit() cmd.exe process Exited: " +
                                Environment.NewLine +
                                "Process Name: " + myCmdProcess.ProcessName +
                                Environment.NewLine + " Process Id: " + myCmdProcess.Id
                                + Environment.NewLine + "process.Handle: " +
                                myCmdProcess.Handle);
                */
                myCmdProcess.Refresh();
                Process.LeaveDebugMode();
                //myCmdProcess.Dispose();
                /*
                MessageBox.Show("After LeaveDebugMode() cmd.exe process Exited: " +
                                Environment.NewLine);
                */
            }


            //process.Kill();
            // Waits for the process to complete task and exites automatically
            Thread.Sleep(millisecondsTimeout: 1000);

            // This works fine in Windows 7 Environment, and not in Windows 8
            // Try following code block
            // Check, if process is not comletey exited

            if (!myCmdProcess.HasExited)
            {
                //process.WaitForExit(2000); // Try to wait for exit 2 more seconds
                /*
                MessageBox.Show(" Process of cmd.exe was exited by WaitForExit(); Method " +
                                Environment.NewLine);
                */
                try
                {
                    // If not, then Kill the process
                    myCmdProcess.Kill();
                    //myCmdProcess.Dispose();
                    //if (!myCmdProcess.HasExited)
                    //{
                    //    myCmdProcess.Kill();
                    //}

                    MessageBox.Show(" Process of cmd.exe exited ( Killed ) successfully " +
                                    Environment.NewLine);
                }
                catch (System.ComponentModel.Win32Exception ex)
                {
                    MessageBox.Show(
                        " Exception: System.ComponentModel.Win32Exception " +
                        ex.ErrorCode + Environment.NewLine);
                }
                catch (NotSupportedException notSupporEx)
                {
                    MessageBox.Show(" Exception: NotSupportedException " +
                                    notSupporEx.Message +
                                    Environment.NewLine);
                }
                catch (InvalidOperationException invalidOperation)
                {
                    MessageBox.Show(
                        " Exception: InvalidOperationException " +
                        invalidOperation.Message + Environment.NewLine);
                    foreach (
                        var textFile in Directory.GetFiles(appPath + "\\png2text", "*.txt",
                            SearchOption.AllDirectories))
                    {
                        loggingInfo += textFile +
                                       " In Reading Text from generated text file by Tesseract " +
                                       Environment.NewLine;
                        strBldr.Append(File.ReadAllText(textFile));
                    }
                    // Delete text file after reading text here
                    Directory.GetFiles(appPath + "\\pdf2png").ToList().ForEach(File.Delete);
                    Directory.GetFiles(appPath + "\\png2text").ToList().ForEach(File.Delete);
                }
            }
        }
        catch (Exception exception)
        {
            MessageBox.Show(
                " Cought Exception in Generating image do{...}while{...} function " +
                Environment.NewLine + exception.Message + Environment.NewLine);
        }
    }
    // Delete png image here
    Directory.GetFiles(appPath + "\\pdf2png").ToList().ForEach(File.Delete);
    Thread.Sleep(millisecondsTimeout: 1000);
    // Read text from text file here
    foreach (var textFile in Directory.GetFiles(appPath + "\\png2text", "*.txt",
        SearchOption.AllDirectories))
    {
        loggingInfo += textFile +
                       " In Reading Text from generated text file by Tesseract " +
                       Environment.NewLine;
        strBldr.Append(File.ReadAllText(textFile));
    }
    // Delete text file after reading text here
    Directory.GetFiles(appPath + "\\png2text").ToList().ForEach(File.Delete);
} while (extractor.GetNextImage()); // Advance image enumeration... 

设置可以在code.google.com上提供Tesseract OCR开源引擎。 - Kaushal B

0

诚然,这是一个较旧的问题,当时Tesseract 3是可用版本,但在寻找相关问题和答案时,我在搜索结果中发现了它,并且其他答案都强调了实际安装Tesseract的困难,更不用说配置它以正常工作。

有一个简单得多的解决方案(使用更新的Tesseract 5引擎),可以为您完成所有工作,在IronOcr中实现。

(免责声明:我确实为Iron Software工作,但我认为其他人可以从这些信息中受益,特别是涉及在C#中使用Tesseract OCR的问题,IronOcr非常擅长处理此类问题)。

using IronOcr;
var Ocr = new IronTesseract(); // nothing to configure
Ocr.Configuration.WhiteListCharacters = "0123456789"; // If digit only
using (var Input = new OcrInput(@"example.tiff"))
{
OcrResult Result = Ocr.Read(Input);
foreach (var Page in Result.Pages)
{
    // Page object
    int PageNumber = Page.PageNumber;
    string PageText = Page.Text;
    int PageWordCount = Page.WordCount;
    // null if we dont set Ocr.Configuration.ReadBarCodes = true;
    OcrResult.Barcode[] Barcodes = Page.Barcodes;
    System.Drawing.Bitmap PageImage = Page.ToBitmap(Input);
    int PageWidth = Page.Width;
    int PageHeight = Page.Height;
    foreach (var Paragraph in Page.Paragraphs)
    {
        // Pages -> Paragraphs
        int ParagraphNumber = Paragraph.ParagraphNumber;
        String ParagraphText = Paragraph.Text;
        System.Drawing.Bitmap ParagraphImage = Paragraph.ToBitmap(Input);
        int ParagraphX_location = Paragraph.X;
        int ParagraphY_location = Paragraph.Y;
        int ParagraphWidth = Paragraph.Width;
        int ParagraphHeight = Paragraph.Height;
        double ParagraphOcrAccuracy = Paragraph.Confidence;
        OcrResult.TextFlow paragrapthText_direction = Paragraph.TextDirection;
        foreach (var Line in Paragraph.Lines)
        {
            // Pages -> Paragraphs -> Lines
            int LineNumber = Line.LineNumber;
            String LineText = Line.Text;
            System.Drawing.Bitmap LineImage = Line.ToBitmap(Input); ;
            int LineX_location = Line.X;
            int LineY_location = Line.Y;
            int LineWidth = Line.Width;
            int LineHeight = Line.Height;
            double LineOcrAccuracy = Line.Confidence;
            double LineSkew = Line.BaselineAngle;
            double LineOffset = Line.BaselineOffset;
            foreach (var Word in Line.Words)
            {
                // Pages -> Paragraphs -> Lines -> Words
                int WordNumber = Word.WordNumber;
                String WordText = Word.Text;
                System.Drawing.Image WordImage = Word.ToBitmap(Input);
                int WordX_location = Word.X;
                int WordY_location = Word.Y;
                int WordWidth = Word.Width;
                int WordHeight = Word.Height;
                double WordOcrAccuracy = Word.Confidence;
                if (Word.Font != null)
                {
                    // Word.Font is only set when using Tesseract Engine Modes rather than LTSM
                    String FontName = Word.Font.FontName;
                    double FontSize = Word.Font.FontSize;
                    bool IsBold = Word.Font.IsBold;
                    bool IsFixedWidth = Word.Font.IsFixedWidth;
                    bool IsItalic = Word.Font.IsItalic;
                    bool IsSerif = Word.Font.IsSerif;
                    bool IsUnderLined = Word.Font.IsUnderlined;
                    bool IsFancy = Word.Font.IsCaligraphic;
                }
                foreach (var Character in Word.Characters)
                {
                    // Pages -> Paragraphs -> Lines -> Words -> Characters
                    int CharacterNumber = Character.CharacterNumber;
                    String CharacterText = Character.Text;
                    System.Drawing.Bitmap CharacterImage = Character.ToBitmap(Input);
                    int CharacterX_location = Character.X;
                    int CharacterY_location = Character.Y;
                    int CharacterWidth = Character.Width;
                    int CharacterHeight = Character.Height;
                    double CharacterOcrAccuracy = Character.Confidence;
                    // Output alternative symbols choices and their probability.
                    // Very useful for spellchecking
                    OcrResult.Choice[] Choices = Character.Choices;
                }
            }
        }
    }
}
}

1
确认 - 工作正常 - Stephanie

0

我曾经遇到同样的问题,现在已经解决了。我有tesseract2,在这个文件夹下有32位和64位的文件夹,我将64位文件夹中的文件(因为我的系统是64位)复制到主文件夹(“Tesseract2”)和bin/Debug文件夹下。现在我的解决方案运行良好。


0

在我的情况下,除了正确的字符识别之外,我已经做好了所有这些工作。

但你需要考虑以下几点:

  • 使用正确的tessnet2库
  • 使用正确的tessdata语言版本
  • tessdata应该放在应用程序文件夹之外的某个地方,您可以在init参数中输入完整路径。使用ocr.Init(@"c:\tessdata", "eng", true);
  • 调试会让你头疼。然后你需要更新你的app.config使用这个。(我不能把xml代码放在这里。给我你的电子邮件,我会把它发送给你)

希望这能帮到你


0

这是一个很好的工作示例项目; Tesseract OCR Sample (Visual Studio) with Leptonica Preprocessing Tesseract OCR Sample (Visual Studio) with Leptonica Preprocessing

Tesseract OCR 3.02.02 API 可能会让人感到困惑,因此本文将指导您如何将 Tesseract 和 Leptonica dll 包含到 Visual Studio C++ 项目中,并提供一个示例文件,该文件接受图像路径进行预处理和 OCR。Leptonica 中的预处理脚本将输入图像转换为黑白书籍样式的文本。

设置

要将此内容包含在您自己的项目中,您需要引用头文件和 lib 并复制 tessdata 文件夹和 dlls。

将 tesseract-include 文件夹复制到您项目的根文件夹中。现在在 Visual Studio 解决方案资源管理器中单击您的项目,然后转到 Project>Properties。

VC++ Directories>Include Directories:

..\tesseract-include\tesseract;..\tesseract-include\leptonica;$(IncludePath) C/C++>Preprocessor>Preprocessor Definitions:

_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) C/C++>Linker>Input>Additional Dependencies:

..\tesseract-include\libtesseract302.lib;..\tesseract-include\liblept168.lib;%(AdditionalDependencies) 现在您可以在项目文件中包含头文件:

#include

#include

现在将 tesseract-include 文件夹中的两个 dll 文件和 tessdata 文件夹中的内容复制到您的项目的输出目录中。

当您初始化 tesseract 时,如果 tessdata 文件夹不是可执行文件的当前目录,则需要指定其父文件夹(!重要)。您可以复制我的脚本,它假设 tessdata 已安装在可执行文件的文件夹中。

tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI(); api->Init("D:\tessdataParentFolder\", ... 示例

您可以编译提供的示例,该示例使用一个命令行参数来指定要使用的图像路径。preprocess() 函数使用 Leptonica 创建黑白书籍副本,使 tesseract 的准确度达到 90%。ocr() 函数展示了 Tesseract API 返回字符串输出的功能。toClipboard() 可用于在 Windows 上保存文本到剪贴板。您可以将这些复制到自己的项目中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接