【问题标题】:How to implement and do OCR in a C# project?如何在 C# 项目中实现和执行 OCR?
【发布时间】:2012-06-12 10:15:43
【问题描述】:

我已经搜索了一段时间,并且我看到了一些 OCR 库请求。我想知道如何实现最纯粹、易于安装和使用带有详细信息的 OCR 库以安装到 C# 项目中。

如果可能的话,我只想像通常的 dll 引用一样实现它...

例子:

using org.pdfbox.pdmodel;
using org.pdfbox.util;

还有一点 OCR 代码示例也不错,例如:

public string OCRFromBitmap(Bitmap Bmp)
{
    Bmp.Save(temppath, System.Drawing.Imaging.ImageFormat.Tiff);
    string OcrResult = Analyze(temppath);
    File.Delete(temppath);
    return OcrResult;
}

所以请考虑到我对 OCR 项目不熟悉,并给我一个像与假人交谈一样的答案。

编辑: 我猜人们误解了我的要求。我想知道如何将这些开源 OCR 库实现到 C# 项目以及如何使用它们。作为 dup 给出的链接根本没有给出我要求的答案。

【问题讨论】:

    标签: c# ocr


    【解决方案1】:

    如果有人对此进行调查,我一直在尝试不同的选择,以下方法产生了非常好的结果。以下是获取工作示例的步骤:

    1. .NET Wrapper for tesseract 添加到您的项目中。可以通过 NuGet 包 Install-Package Tesseract(https://github.com/charlesw/tesseract) 添加。
    2. 转到官方Tesseract 项目的Downloads 部分(https://code.google.com/p/tesseract-ocr/ 编辑:现在位于此处:https://github.com/tesseract-ocr/langdata)。
    3. 下载首选语言数据,例如:tesseract-ocr-3.02.eng.tar.gz English language data for Tesseract 3.02
    4. 在您的项目中创建tessdata 目录并将语言数据文件放入其中。
    5. 转到新添加文件的Properties 并将它们设置为在构建时复制。
    6. 添加对System.Drawing的引用。
    7. 从 .NET Wrapper 存储库中,将 Samples 目录中的示例 phototest.tif 文件复制到您的项目目录中,并将其设置为在构建时复制。
    8. 在您的项目中创建以下两个文件(只是为了开始):

    Program.cs

    using System;
    using Tesseract;
    using System.Diagnostics;
    
    namespace ConsoleApplication
    {
        class Program
        {
            public static void Main(string[] args)
            {
                var testImagePath = "./phototest.tif";
                if (args.Length > 0)
                {
                    testImagePath = args[0];
                }
    
                try
                {
                    var logger = new FormattedConsoleLogger();
                    var resultPrinter = new ResultPrinter(logger);
                    using (var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.Default))
                    {
                        using (var img = Pix.LoadFromFile(testImagePath))
                        {
                            using (logger.Begin("Process image"))
                            {
                                var i = 1;
                                using (var page = engine.Process(img))
                                {
                                    var text = page.GetText();
                                    logger.Log("Text: {0}", text);
                                    logger.Log("Mean confidence: {0}", page.GetMeanConfidence());
    
                                    using (var iter = page.GetIterator())
                                    {
                                        iter.Begin();
                                        do
                                        {
                                            if (i % 2 == 0)
                                            {
                                                using (logger.Begin("Line {0}", i))
                                                {
                                                    do
                                                    {
                                                        using (logger.Begin("Word Iteration"))
                                                        {
                                                            if (iter.IsAtBeginningOf(PageIteratorLevel.Block))
                                                            {
                                                                logger.Log("New block");
                                                            }
                                                            if (iter.IsAtBeginningOf(PageIteratorLevel.Para))
                                                            {
                                                                logger.Log("New paragraph");
                                                            }
                                                            if (iter.IsAtBeginningOf(PageIteratorLevel.TextLine))
                                                            {
                                                                logger.Log("New line");
                                                            }
                                                            logger.Log("word: " + iter.GetText(PageIteratorLevel.Word));
                                                        }
                                                    } while (iter.Next(PageIteratorLevel.TextLine, PageIteratorLevel.Word));
                                                }
                                            }
                                            i++;
                                        } while (iter.Next(PageIteratorLevel.Para, PageIteratorLevel.TextLine));
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.ToString());
                    Console.WriteLine("Unexpected Error: " + e.Message);
                    Console.WriteLine("Details: ");
                    Console.WriteLine(e.ToString());
                }
                Console.Write("Press any key to continue . . . ");
                Console.ReadKey(true);
            }
    
    
    
            private class ResultPrinter
            {
                readonly FormattedConsoleLogger logger;
    
                public ResultPrinter(FormattedConsoleLogger logger)
                {
                    this.logger = logger;
                }
    
                public void Print(ResultIterator iter)
                {
                    logger.Log("Is beginning of block: {0}", iter.IsAtBeginningOf(PageIteratorLevel.Block));
                    logger.Log("Is beginning of para: {0}", iter.IsAtBeginningOf(PageIteratorLevel.Para));
                    logger.Log("Is beginning of text line: {0}", iter.IsAtBeginningOf(PageIteratorLevel.TextLine));
                    logger.Log("Is beginning of word: {0}", iter.IsAtBeginningOf(PageIteratorLevel.Word));
                    logger.Log("Is beginning of symbol: {0}", iter.IsAtBeginningOf(PageIteratorLevel.Symbol));
    
                    logger.Log("Block text: \"{0}\"", iter.GetText(PageIteratorLevel.Block));
                    logger.Log("Para text: \"{0}\"", iter.GetText(PageIteratorLevel.Para));
                    logger.Log("TextLine text: \"{0}\"", iter.GetText(PageIteratorLevel.TextLine));
                    logger.Log("Word text: \"{0}\"", iter.GetText(PageIteratorLevel.Word));
                    logger.Log("Symbol text: \"{0}\"", iter.GetText(PageIteratorLevel.Symbol));
                }
            }
        }
    }
    

    FormattedConsoleLogger.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Tesseract;
    
    namespace ConsoleApplication
    {
        public class FormattedConsoleLogger
        {
            const string Tab = "    ";
            private class Scope : DisposableBase
            {
                private int indentLevel;
                private string indent;
                private FormattedConsoleLogger container;
    
                public Scope(FormattedConsoleLogger container, int indentLevel)
                {
                    this.container = container;
                    this.indentLevel = indentLevel;
                    StringBuilder indent = new StringBuilder();
                    for (int i = 0; i < indentLevel; i++)
                    {
                        indent.Append(Tab);
                    }
                    this.indent = indent.ToString();
                }
    
                public void Log(string format, object[] args)
                {
                    var message = String.Format(format, args);
                    StringBuilder indentedMessage = new StringBuilder(message.Length + indent.Length * 10);
                    int i = 0;
                    bool isNewLine = true;
                    while (i < message.Length)
                    {
                        if (message.Length > i && message[i] == '\r' && message[i + 1] == '\n')
                        {
                            indentedMessage.AppendLine();
                            isNewLine = true;
                            i += 2;
                        }
                        else if (message[i] == '\r' || message[i] == '\n')
                        {
                            indentedMessage.AppendLine();
                            isNewLine = true;
                            i++;
                        }
                        else
                        {
                            if (isNewLine)
                            {
                                indentedMessage.Append(indent);
                                isNewLine = false;
                            }
                            indentedMessage.Append(message[i]);
                            i++;
                        }
                    }
    
                    Console.WriteLine(indentedMessage.ToString());
    
                }
    
                public Scope Begin()
                {
                    return new Scope(container, indentLevel + 1);
                }
    
                protected override void Dispose(bool disposing)
                {
                    if (disposing)
                    {
                        var scope = container.scopes.Pop();
                        if (scope != this)
                        {
                            throw new InvalidOperationException("Format scope removed out of order.");
                        }
                    }
                }
            }
    
            private Stack<Scope> scopes = new Stack<Scope>();
    
            public IDisposable Begin(string title = "", params object[] args)
            {
                Log(title, args);
                Scope scope;
                if (scopes.Count == 0)
                {
                    scope = new Scope(this, 1);
                }
                else
                {
                    scope = ActiveScope.Begin();
                }
                scopes.Push(scope);
                return scope;
            }
    
            public void Log(string format, params object[] args)
            {
                if (scopes.Count > 0)
                {
                    ActiveScope.Log(format, args);
                }
                else
                {
                    Console.WriteLine(String.Format(format, args));
                }
            }
    
            private Scope ActiveScope
            {
                get
                {
                    var top = scopes.Peek();
                    if (top == null) throw new InvalidOperationException("No current scope");
                    return top;
                }
            }
        }
    }
    

    【讨论】:

    • 我希望我能投票不止一次,因为这是一个很好的指导,可以让这件事运行起来。
    • @BloodyRain2k 很高兴您发现它很有用。谢谢你的好话。
    • 我使用了您上面提到的链接。在 eng 文件夹 (github.com/tesseract-ocr/langdata/tree/master/eng) 中缺少一个文件,即 eng.traineddata。请也添加此文件。
    • @MugheesMusaddiq 他们不断地更改文件,这就是为什么我不愿意放置任何链接,因为不能保证它们是相同的。这更多地是作为如何开始的指南,缺乏链接保证是我在这里粘贴这么多代码的原因。
    • 可以在此处下载旧版本的语言数据:sourceforge.net/projects/tesseract-ocr-alt/files(例如,因为目前 NuGet 包的版本是 3.02,而链接网站上唯一可用的语言数据是 3.04;或者可以使用Wayback Machine)
    【解决方案2】:

    这是一个:(查看http://hongouru.blogspot.ie/2011/09/c-ocr-optical-character-recognition.htmlhttp://www.codeproject.com/Articles/41709/How-To-Use-Office-2007-OCR-Using-C 了解更多信息)

    using MODI;
    static void Main(string[] args)
    {
        DocumentClass myDoc = new DocumentClass();
        myDoc.Create(@"theDocumentName.tiff"); //we work with the .tiff extension
        myDoc.OCR(MiLANGUAGES.miLANG_ENGLISH, true, true);
    
        foreach (Image anImage in myDoc.Images)
        {
            Console.WriteLine(anImage.Layout.Text); //here we cout to the console.
        }
    }
    

    【讨论】:

    • 如何获得 MODI?我确实安装了 Microsoft Office 2010 和 2013。
    • 我有 MS office,但无法解析引用(它们有黄色警告三角形),因此项目不会构建)。
    【解决方案3】:

    我正在使用带有 TessNet2 的 tesseract OCR 引擎(一个 C# 包装器 - http://www.pixel-technology.com/freeware/tessnet2/)。

    一些基本代码:

    using tessnet2;
    

    ...

    Bitmap image = new Bitmap(@"u:\user files\bwalker\2849257.tif");
                tessnet2.Tesseract ocr = new tessnet2.Tesseract();
                ocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,$-/#&=()\"':?"); // Accepted characters
                ocr.Init(@"C:\Users\bwalker\Documents\Visual Studio 2010\Projects\tessnetWinForms\tessnetWinForms\bin\Release\", "eng", false); // Directory of your tessdata folder
                List<tessnet2.Word> result = ocr.DoOCR(image, System.Drawing.Rectangle.Empty);
                string Results = "";
                foreach (tessnet2.Word word in result)
                {
                    Results += word.Confidence + ", " + word.Text + ", " + word.Left + ", " + word.Top + ", " + word.Bottom + ", " + word.Right + "\n";
                }
    

    【讨论】:

    • 在您的链接中,还有另一个链接“在此处下载二进制文件”,但它不起作用。事实上,这个链接在许多网站上都没有,但在其中任何一个网站上都不起作用。有谁知道 tessnet2.dll 可以从哪里下载?
    • 我实际上在 NuGet 中找到了 tessnet2,不知道为什么我没有先看那里。当我运行它时它停在 ocr.Init 行上。该目录中是否有特定的东西? tessnet2_32.dll 和我的应用程序 exe 文件一样位于我的“tessdata”文件夹中。知道为什么会停止吗?它根本没有做任何事情。
    【解决方案4】:

    一些在线 API 运行良好:ocr.spaceGoogle Cloud Vision。只要您每月执行的 OCR 少于 1000 个,这两个都是免费的。您可以拖放图像以进行快速手动测试,以了解它们对您的图像的性能。

    我发现 OCR.space 更易于使用(不会乱用 nuget 库),但就我的目的而言,Google Cloud Vision 提供的结果略好于 OCR.space。

    谷歌云视觉示例:

    GoogleCredential cred = GoogleCredential.FromJson(json);
    Channel channel = new Channel(ImageAnnotatorClient.DefaultEndpoint.Host, ImageAnnotatorClient.DefaultEndpoint.Port, cred.ToChannelCredentials());
    ImageAnnotatorClient client = ImageAnnotatorClient.Create(channel);
    Image image = Image.FromStream(stream);
    
    EntityAnnotation googleOcrText = client.DetectText(image).First();
    Console.Write(googleOcrText.Description);
    

    OCR.space 示例:

    string uri = $"https://api.ocr.space/parse/imageurl?apikey=helloworld&url={imageUri}";
    string responseString = WebUtilities.DoGetRequest(uri);
    OcrSpaceResult result = JsonConvert.DeserializeObject<OcrSpaceResult>(responseString);
    if ((!result.IsErroredOnProcessing) && !String.IsNullOrEmpty(result.ParsedResults[0].ParsedText))
      return result.ParsedResults[0].ParsedText;
    

    【讨论】:

    • 什么是 GoogleCredential?什么是 json 变量??
    猜你喜欢
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多