跳至页脚内容
使用 IRONOCR

发票 OCR API(开发者教程)

发票 OCR API 利用机器学习技术自动提取发票数据,消除手动输入错误,同时准确地从电子文档和扫描文档中捕获供应商详细信息、发票号码和价格。 本教程演示如何使用 IronOCR 构建发票 OCR 解决方案。

通过利用机器学习和计算机视觉技术,发票 OCR 技术将发票数据转换为可供自动处理的格式。 您将学习如何应对常见的挑战,例如手动数据输入延迟、成本和错误,同时准确地从任何发票格式中提取供应商信息、发票号码和价格。

本文使用了IronOCR ,这是一款领先的面向 .NET 开发人员的发票 OCR API。

什么是 IronOCR?

IronOCR 由 Iron Software 开发,为开发人员提供全面的 OCR 工具。 它利用机器学习和计算机视觉从扫描的文档、图像和PDF中提取文本,实现自动化处理。 其 API 可与各种语言和平台无缝集成,减少人工数据输入错误,提高效率。 提取的数据直接流入现有系统进行分析和决策。 图像预处理条形码识别和灵活的文件解析等功能增强了其多功能性。 IronOCR 使开发人员能够将强大的文本识别功能集成到他们的应用程序中。

该库通过专门的语言包支持125 种国际语言,使其成为全球发票处理的理想选择。 高级功能包括计算机视觉技术,可自动查找文本,这对于布局各异的发票尤其有用。 此外,IronOCR 还提供多线程处理功能,可高效处理大量发票处理。

为什么我应该使用 IronOCR 进行发票处理?

IronOCR 为发票处理应用提供了显著优势。 首先,它通过其优化的Tesseract 5 引擎提供卓越的精度,该引擎专门针对 .NET 应用程序进行了增强。 图书馆可以处理各种发票格式,从扫描文档PDF 文件,甚至低质量扫描件

内置图像优化滤镜可在处理前自动增强图像质量,从而实现更准确的文本提取。 对于有特殊要求的发票,IronOCR 支持自定义语言训练,可以针对发票类型中常见的独特字体或格式进行优化。

IronOCR 与其他 OCR 库有何不同?

IronOCR 的独特之处在于其简单的单行 OCR 功能,同时又具备企业级功能。 与原始的 Tesseract 实现不同,IronOCR 提供了一个托管的 .NET API,可以无缝地处理复杂的操作。 该库为各种文档类型提供专门的文档读取方法,包括专门支持读取文档中的表格,这对于发票明细项目至关重要。

筛选向导会自动确定特定发票图像的最佳预处理设置,从而消除优化过程中的猜测。 IronOCR 还提供全面的调试功能,使开发人员能够可视化 OCR 引擎所看到的内容,并有效地排除提取问题。

我需要哪些先决条件?

在使用 IronOCR 之前,请确保满足以下先决条件:

  1. 已安装诸如 Visual Studio 之类的集成开发环境 (IDE),并具备合适的开发环境。
  2. 具备C#编程基础知识,能够有效地理解和修改代码示例。
  3. 通过 NuGet 包管理器或命令行将 IronOCR 库安装到您的项目中

满足这些先决条件后,您就可以成功地开始使用 IronOCR 了。

IronOCR 提供适用于WindowsLinuxmacOS的全面设置指南。 该库支持云部署,并针对AWS LambdaAzure Functions提供了专门的教程。

我应该使用哪个版本的 Visual Studio?

IronOCR 支持 Visual Studio 2017 及最新版本。 为了获得最佳兼容性并能使用最新的 C# 功能,建议使用 Visual Studio 2019 或 2022。 该库与.NET Framework、.NET Core 和 .NET 5+完全兼容,确保您的开发环境具有灵活性。

对于跨平台开发,带有 C# 扩展的 Visual Studio Code 效果很好。 移动开发人员可以利用 IronOCR 针对AndroidiOS实现的指导,使其适用于.NET MAUI 应用程序

我需要具备怎样的 C# 知识水平?

具备中级 C# 知识即可实现基本的发票 OCR 功能。 你应该能够适应:

IronOCR 直观的 API 设计意味着无需具备图像处理或机器学习方面的深厚专业知识。 该库在内部处理复杂的操作,让您可以专注于业务逻辑。 初学者可以从简单的OCR示例入手。

如何创建一个新的 Visual Studio 项目?

要开始使用 IronOCR,首先需要创建一个新的 Visual Studio 项目。

打开 Visual Studio,转到"文件",将鼠标悬停在"新建"上,然后单击"项目"。

Visual Studio IDE 显示"文件"菜单已打开,"新建"和"项目"选项已高亮显示,演示了创建新的发票 OCR API 项目的第一步。 新项目

在新窗口中,选择"控制台应用程序",然后单击"下一步"。

Visual Studio 的"创建新项目"对话框显示了各种项目模板,其中"控制台应用程序"选项突出显示,用于创建适用于发票 OCR 处理的 .NET Core 命令行应用程序。 控制台应用程序

出现新窗口。 请输入项目名称和地点,然后单击"下一步"。

Visual Studio 新建项目配置窗口显示了名为"IronOCR"的控制台应用程序的项目设置,其中选择了 C# 语言和 Windows 目标平台,用于发票 OCR API 实现。 项目配置

最后,选择目标框架并单击"创建"。

Visual Studio 项目创建向导显示了"附加信息"步骤,其中已选择 .NET 5.0 框架,以便在发票处理应用程序中实现最佳的 IronOCR 兼容性。 目标框架

你的新 Visual Studio 项目已准备就绪。 让我们安装IronOCR。

哪种项目类型最适合 OCR 应用?

虽然本教程为了简单起见使用了控制台应用程序,但 IronOCR 支持多种项目类型:

-控制台应用程序:非常适合批量处理或命令行工具

  • Web 应用程序:非常适合构建 API 或基于 Web 的服务
  • Windows Forms/WPF :适用于带有图形用户界面的桌面应用程序
  • .NET MAUI 应用:用于跨平台解决方案

对于大批量处理,可以考虑在 Windows 服务或微服务架构中实现 IronOCR。 图书馆的进度跟踪功能使监控长时间运行的操作变得容易。

我应该选择哪个 .NET Framework 版本?

IronOCR与 .NET 版本具有广泛的兼容性。 对于新项目,建议使用 .NET 6.0 或更高版本以获得最佳性能和最新功能。 该库保持了出色的向后兼容性:

  • .NET Framework 4.6.2+ :适用于传统企业应用程序
  • .NET Core 3.1 :长期支持,实现稳定部署
  • .NET 5.0+ :性能提升的现代化框架
  • .NET Standard 2.0 :跨平台最大程度的兼容性

部署到Docker 容器时,.NET 6.0 或更高版本可提供更小的镜像大小和更好的性能。 Azure Functions同时支持 .NET 6.0 和 .NET Framework。

如何安装 IronOCR?

下载和安装 IronOCR 有两种简单的方法:

  1. 使用 Visual Studio NuGet 包管理器
  2. 使用 Visual Studio 命令行

何时应该使用 NuGet 包管理器,何时应该使用命令行?

根据您的工作流程,选择使用 NuGet 包管理器图形用户界面 (GUI) 还是命令行:

NuGet 包管理器 GUI在以下情况下效果最佳: 您是 NuGet 包的新手 您想浏览IronOCR 语言包 您更喜欢视觉确认 您管理多个包裹

命令行(软件包管理器控制台)在以下情况下表现出色: 您熟悉命令行界面

  • 您遵循脚本化部署 您需要快速获取特定版本。
  • 您使用了高级安装选项

两种方法都能达到相同的效果——根据舒适度和需求选择即可。

我可能还需要哪些额外的语言包?

IronOCR 通过专用软件包支持125 种国际语言。 发票处理时,请考虑以下事项:

-特定业务包:财务文档的财务语言包 -区域语言:根据发票来源而定(西班牙语、法语、德语) -多语言支持:适用于包含多种语言的发票 -自定义语言:用于特殊字体或自定义训练数据

语言包与 IronOCR 主程序包一起安装,可显著提高非英语文本的识别准确率。

使用 Visual Studio NuGet 软件包管理器

使用 Visual Studio NuGet 包管理器将 IronOCR 集成到您的 C# 项目中。

导航至"工具" > "NuGet 程序包管理器" > "管理解决方案的 NuGet 程序包"。

Visual Studio IDE 显示 NuGet 包管理器界面,其中包含 IronOCR 包的搜索结果,并显示用于设置发票 OCR 功能的安装选项和包详细信息NuGet 软件包管理器

搜索 IronOCR 并将其安装到您的项目中。

NuGet 包管理器界面显示 IronOCR v2022.1.0 及相关语言包,包括阿拉伯语、希伯来语和西班牙语 OCR 功能,并显示每个专用识别包的版本号和描述。 在NuGet包管理器UI中选择IronOCR包

使用相同的方法安装其他语言包。

使用Visual Studio命令行

1.在 Visual Studio 中,转到 工具 > NuGet软件包管理器 > 软件包管理器控制台

  1. 在软件包管理器控制台中输入以下命令:

    Install-Package IronOcr

Visual Studio 包管理器控制台显示"Install-Package IronOCR"命令已成功执行,演示了 OCR 库的命令行安装方法。 包管理器控制台

该软件包将下载并安装到您当前的项目中,即可使用。

如何使用 IronOCR 从发票中提取数据?

使用 IronOCR,只需几行代码即可轻松提取发票数据。 它取代了手动数据录入,简化了您的工作流程。

以下是一个用于文本提取的发票示例:

示例发票文档,显示客户详细信息,发票编号 INV/2023/00039,包含三项清洁服务,总计 80.50 美元,展示了用于 OCR 提取的典型发票格式。 示例发票

让我们从这张发票中提取所有数据:

using IronOcr;
using System;

// Initialize a new instance of the IronTesseract class
// This is the main OCR engine that will process our invoice
var ocr = new IronTesseract();

// Configure OCR settings for better invoice processing
ocr.Configuration.BlackListCharacters = "~`$#^*_}{]___PROTECTED_LINK_48___ method from ___PROTECTED_LINK_49___ class. Key enhancements include:

- **Image preprocessing**: ___PROTECTED_LINK_50___ corrects tilted scans; ___PROTECTED_LINK_51___ removes artifacts
- **Resolution enhancement**: Setting ___PROTECTED_LINK_52___ improves recognition
- **Character blacklisting**: Prevents common OCR misinterpretations
- **Confidence scoring**: Assesses extraction reliability

!___PROTECTED_LINK_53___
**Invoice Parser**

<h3>How Do I Handle Different Invoice Formats?</h3>

Invoice formats vary between vendors, but IronOCR provides flexible solutions:

1. **Template-based**: Define ___PROTECTED_LINK_54___
2. **Computer vision**: Use ___PROTECTED_LINK_55___ to locate text
3. **Table extraction**: Leverage ___PROTECTED_LINK_56___ for line items
4. **Multi-format**: Process ___PROTECTED_LINK_57___, ___PROTECTED_LINK_58___, and ___PROTECTED_LINK_59___

For complex layouts, implement the ___PROTECTED_LINK_60___ which uses machine learning to identify structures automatically.

<h3>What Are Common Extraction Patterns for Invoice Data?</h3>

Invoice data follows recognizable patterns extractable using regular expressions with OCR results:

```csharp
using IronOcr;
using System;
using System.Text.`RegularExpressions`;
using System.Collections.Generic;

public class `InvoiceDataExtractor`
{
    private readonly `IronTesseract` ocr;

    public `InvoiceDataExtractor`()
    {
        ocr = new `IronTesseract`();
        // Configure for optimal invoice reading
        `ocr.Configuration`.`ReadBarcodes` = true; // Many invoices include barcodes
        `ocr.Configuration`.`TesseractVersion` = `TesseractVersion`.Tesseract5;
    }

    public `InvoiceData` `ExtractInvoiceData`(string imagePath)
    {
        var invoiceData = new `InvoiceData`();

        using (var input = new `OcrInput`(imagePath))
        {
            // Apply filters for better accuracy
            input.`EnhanceResolution`(300);
            `input.Sharpen`();

            var result = `ocr.Read`(input);
            var text = `result.Text`;

            // Extract invoice number
            invoiceData.`InvoiceNumber` = `ExtractPattern`(text, 
                @"INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)");

            // Extract dates
            invoiceData.`InvoiceDate` = `ExtractDate`(text, 
                @"Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");
            invoiceData.`DueDate` = `ExtractDate`(text, 
                @"Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");

            // Extract amounts
            `invoiceData.Total` = `ExtractAmount`(text, 
                @"Total\s*:?\s*\$?\s*([\d,]+\.?\d*)");
            `invoiceData.Tax` = `ExtractAmount`(text, 
                @"Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)");

            // Extract vendor information
            invoiceData.`VendorName` = `ExtractVendorName`(text);

            // Extract line items using table detection
            invoiceData.`LineItems` = `ExtractLineItems`(result);

            // Extract any barcodes found
            if (`result.Barcodes`.Length > 0)
            {
                invoiceData.`BarcodeValues` = new List<string>();
                foreach (var barcode in `result.Barcodes`)
                {
                    invoiceData.`BarcodeValues`.Add(`barcode.Value`);
                }
            }
        }

        return invoiceData;
    }

    private string `ExtractPattern`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        return `match.Success` ? `match.Value` : `string.Empty`;
    }

    private `DateTime`? `ExtractDate`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            if (`DateTime`.`TryParse`(`match.Groups`[1].Value, out `DateTime` date))
                return date;
        }
        return null;
    }

    private decimal `ExtractAmount`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            var amountStr = `match.Groups`[1].Value.Replace(",", "");
            if (decimal.`TryParse`(amountStr, out decimal amount))
                return amount;
        }
        return 0;
    }

    private string `ExtractVendorName`(string text)
    {
        // Usually the vendor name appears in the first few lines
        var lines = `text.Split`('\n');
        if (`lines.Length` > 0)
        {
            // Simple heuristic: first non-empty line that's not a common header
            foreach (var line in lines)
            {
                var trimmed = `line.Trim`();
                if (!string.`IsNullOrEmpty`(trimmed) && 
                    !trimmed.`ToLower`().Contains("invoice") &&
                    `trimmed.Length` > 3)
                {
                    return trimmed;
                }
            }
        }
        return `string.Empty`;
    }

    private List<`LineItem`> `ExtractLineItems`(`OcrResult` result)
    {
        var lineItems = new List<`LineItem`>();

        // Use IronOCR's table detection capabilities
        if (`result.Tables` != null && `result.Tables`.Count > 0)
        {
            foreach (var table in `result.Tables`)
            {
                // Process each row as a potential line item
                for (int i = 1; i < table.`RowCount`; i++) // Skip header row
                {
                    var item = new `LineItem`
                    {
                        Description = table[i, 0]?.Text ?? "",
                        Quantity = `ParseQuantity`(table[i, 1]?.Text),
                        `UnitPrice` = `ParseAmount`(table[i, 2]?.Text),
                        Total = `ParseAmount`(table[i, 3]?.Text)
                    };

                    if (!string.`IsNullOrEmpty`(`item.Description`))
                        `lineItems.Add`(item);
                }
            }
        }

        return lineItems;
    }

    private int `ParseQuantity`(string text)
    {
        if (string.`IsNullOrEmpty`(text)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d]", "");
        return int.`TryParse`(cleaned, out int qty) ? qty : 0;
    }

    private decimal `ParseAmount`(string text)
    {
        if (string.`IsNullOrEmpty`(text)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d.]", "");
        return decimal.`TryParse`(cleaned, out decimal amt) ? amt : 0;
    }
}

// Data classes for structured invoice information
public class `InvoiceData`
{
    public string `InvoiceNumber` { get; set; }
    public `DateTime`? `InvoiceDate` { get; set; }
    public `DateTime`? `DueDate` { get; set; }
    public string `VendorName` { get; set; }
    public decimal Total { get; set; }
    public decimal Tax { get; set; }
    public List<`LineItem`> `LineItems` { get; set; }
    public List<string> `BarcodeValues` { get; set; }
}

public class `LineItem`
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal `UnitPrice` { get; set; }
    public decimal Total { get; set; }
}
using IronOcr;
using System;

// Initialize a new instance of the IronTesseract class
// This is the main OCR engine that will process our invoice
var ocr = new IronTesseract();

// Configure OCR settings for better invoice processing
ocr.Configuration.BlackListCharacters = "~`$#^*_}{]___PROTECTED_LINK_48___ method from ___PROTECTED_LINK_49___ class. Key enhancements include:

- **Image preprocessing**: ___PROTECTED_LINK_50___ corrects tilted scans; ___PROTECTED_LINK_51___ removes artifacts
- **Resolution enhancement**: Setting ___PROTECTED_LINK_52___ improves recognition
- **Character blacklisting**: Prevents common OCR misinterpretations
- **Confidence scoring**: Assesses extraction reliability

!___PROTECTED_LINK_53___
**Invoice Parser**

<h3>How Do I Handle Different Invoice Formats?</h3>

Invoice formats vary between vendors, but IronOCR provides flexible solutions:

1. **Template-based**: Define ___PROTECTED_LINK_54___
2. **Computer vision**: Use ___PROTECTED_LINK_55___ to locate text
3. **Table extraction**: Leverage ___PROTECTED_LINK_56___ for line items
4. **Multi-format**: Process ___PROTECTED_LINK_57___, ___PROTECTED_LINK_58___, and ___PROTECTED_LINK_59___

For complex layouts, implement the ___PROTECTED_LINK_60___ which uses machine learning to identify structures automatically.

<h3>What Are Common Extraction Patterns for Invoice Data?</h3>

Invoice data follows recognizable patterns extractable using regular expressions with OCR results:

```csharp
using IronOcr;
using System;
using System.Text.`RegularExpressions`;
using System.Collections.Generic;

public class `InvoiceDataExtractor`
{
    private readonly `IronTesseract` ocr;

    public `InvoiceDataExtractor`()
    {
        ocr = new `IronTesseract`();
        // Configure for optimal invoice reading
        `ocr.Configuration`.`ReadBarcodes` = true; // Many invoices include barcodes
        `ocr.Configuration`.`TesseractVersion` = `TesseractVersion`.Tesseract5;
    }

    public `InvoiceData` `ExtractInvoiceData`(string imagePath)
    {
        var invoiceData = new `InvoiceData`();

        using (var input = new `OcrInput`(imagePath))
        {
            // Apply filters for better accuracy
            input.`EnhanceResolution`(300);
            `input.Sharpen`();

            var result = `ocr.Read`(input);
            var text = `result.Text`;

            // Extract invoice number
            invoiceData.`InvoiceNumber` = `ExtractPattern`(text, 
                @"INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)");

            // Extract dates
            invoiceData.`InvoiceDate` = `ExtractDate`(text, 
                @"Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");
            invoiceData.`DueDate` = `ExtractDate`(text, 
                @"Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");

            // Extract amounts
            `invoiceData.Total` = `ExtractAmount`(text, 
                @"Total\s*:?\s*\$?\s*([\d,]+\.?\d*)");
            `invoiceData.Tax` = `ExtractAmount`(text, 
                @"Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)");

            // Extract vendor information
            invoiceData.`VendorName` = `ExtractVendorName`(text);

            // Extract line items using table detection
            invoiceData.`LineItems` = `ExtractLineItems`(result);

            // Extract any barcodes found
            if (`result.Barcodes`.Length > 0)
            {
                invoiceData.`BarcodeValues` = new List<string>();
                foreach (var barcode in `result.Barcodes`)
                {
                    invoiceData.`BarcodeValues`.Add(`barcode.Value`);
                }
            }
        }

        return invoiceData;
    }

    private string `ExtractPattern`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        return `match.Success` ? `match.Value` : `string.Empty`;
    }

    private `DateTime`? `ExtractDate`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            if (`DateTime`.`TryParse`(`match.Groups`[1].Value, out `DateTime` date))
                return date;
        }
        return null;
    }

    private decimal `ExtractAmount`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            var amountStr = `match.Groups`[1].Value.Replace(",", "");
            if (decimal.`TryParse`(amountStr, out decimal amount))
                return amount;
        }
        return 0;
    }

    private string `ExtractVendorName`(string text)
    {
        // Usually the vendor name appears in the first few lines
        var lines = `text.Split`('\n');
        if (`lines.Length` > 0)
        {
            // Simple heuristic: first non-empty line that's not a common header
            foreach (var line in lines)
            {
                var trimmed = `line.Trim`();
                if (!string.`IsNullOrEmpty`(trimmed) && 
                    !trimmed.`ToLower`().Contains("invoice") &&
                    `trimmed.Length` > 3)
                {
                    return trimmed;
                }
            }
        }
        return `string.Empty`;
    }

    private List<`LineItem`> `ExtractLineItems`(`OcrResult` result)
    {
        var lineItems = new List<`LineItem`>();

        // Use IronOCR's table detection capabilities
        if (`result.Tables` != null && `result.Tables`.Count > 0)
        {
            foreach (var table in `result.Tables`)
            {
                // Process each row as a potential line item
                for (int i = 1; i < table.`RowCount`; i++) // Skip header row
                {
                    var item = new `LineItem`
                    {
                        Description = table[i, 0]?.Text ?? "",
                        Quantity = `ParseQuantity`(table[i, 1]?.Text),
                        `UnitPrice` = `ParseAmount`(table[i, 2]?.Text),
                        Total = `ParseAmount`(table[i, 3]?.Text)
                    };

                    if (!string.`IsNullOrEmpty`(`item.Description`))
                        `lineItems.Add`(item);
                }
            }
        }

        return lineItems;
    }

    private int `ParseQuantity`(string text)
    {
        if (string.`IsNullOrEmpty`(text)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d]", "");
        return int.`TryParse`(cleaned, out int qty) ? qty : 0;
    }

    private decimal `ParseAmount`(string text)
    {
        if (string.`IsNullOrEmpty`(text)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d.]", "");
        return decimal.`TryParse`(cleaned, out decimal amt) ? amt : 0;
    }
}

// Data classes for structured invoice information
public class `InvoiceData`
{
    public string `InvoiceNumber` { get; set; }
    public `DateTime`? `InvoiceDate` { get; set; }
    public `DateTime`? `DueDate` { get; set; }
    public string `VendorName` { get; set; }
    public decimal Total { get; set; }
    public decimal Tax { get; set; }
    public List<`LineItem`> `LineItems` { get; set; }
    public List<string> `BarcodeValues` { get; set; }
}

public class `LineItem`
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal `UnitPrice` { get; set; }
    public decimal Total { get; set; }
}
Imports IronOcr
Imports System
Imports System.Text.RegularExpressions
Imports System.Collections.Generic

Public Class InvoiceDataExtractor
    Private ReadOnly ocr As IronTesseract

    Public Sub New()
        ocr = New IronTesseract()
        ' Configure for optimal invoice reading
        ocr.Configuration.ReadBarcodes = True ' Many invoices include barcodes
        ocr.Configuration.TesseractVersion = TesseractVersion.Tesseract5
    End Sub

    Public Function ExtractInvoiceData(imagePath As String) As InvoiceData
        Dim invoiceData As New InvoiceData()

        Using input As New OcrInput(imagePath)
            ' Apply filters for better accuracy
            input.EnhanceResolution(300)
            input.Sharpen()

            Dim result = ocr.Read(input)
            Dim text = result.Text

            ' Extract invoice number
            invoiceData.InvoiceNumber = ExtractPattern(text, "INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)")

            ' Extract dates
            invoiceData.InvoiceDate = ExtractDate(text, "Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})")
            invoiceData.DueDate = ExtractDate(text, "Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})")

            ' Extract amounts
            invoiceData.Total = ExtractAmount(text, "Total\s*:?\s*\$?\s*([\d,]+\.?\d*)")
            invoiceData.Tax = ExtractAmount(text, "Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)")

            ' Extract vendor information
            invoiceData.VendorName = ExtractVendorName(text)

            ' Extract line items using table detection
            invoiceData.LineItems = ExtractLineItems(result)

            ' Extract any barcodes found
            If result.Barcodes.Length > 0 Then
                invoiceData.BarcodeValues = New List(Of String)()
                For Each barcode In result.Barcodes
                    invoiceData.BarcodeValues.Add(barcode.Value)
                Next
            End If
        End Using

        Return invoiceData
    End Function

    Private Function ExtractPattern(text As String, pattern As String) As String
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        Return If(match.Success, match.Value, String.Empty)
    End Function

    Private Function ExtractDate(text As String, pattern As String) As DateTime?
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        If match.Success AndAlso match.Groups.Count > 1 Then
            Dim dateValue As DateTime
            If DateTime.TryParse(match.Groups(1).Value, dateValue) Then
                Return dateValue
            End If
        End If
        Return Nothing
    End Function

    Private Function ExtractAmount(text As String, pattern As String) As Decimal
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        If match.Success AndAlso match.Groups.Count > 1 Then
            Dim amountStr = match.Groups(1).Value.Replace(",", "")
            Dim amount As Decimal
            If Decimal.TryParse(amountStr, amount) Then
                Return amount
            End If
        End If
        Return 0
    End Function

    Private Function ExtractVendorName(text As String) As String
        ' Usually the vendor name appears in the first few lines
        Dim lines = text.Split(ControlChars.Lf)
        If lines.Length > 0 Then
            ' Simple heuristic: first non-empty line that's not a common header
            For Each line In lines
                Dim trimmed = line.Trim()
                If Not String.IsNullOrEmpty(trimmed) AndAlso
                   Not trimmed.ToLower().Contains("invoice") AndAlso
                   trimmed.Length > 3 Then
                    Return trimmed
                End If
            Next
        End If
        Return String.Empty
    End Function

    Private Function ExtractLineItems(result As OcrResult) As List(Of LineItem)
        Dim lineItems As New List(Of LineItem)()

        ' Use IronOCR's table detection capabilities
        If result.Tables IsNot Nothing AndAlso result.Tables.Count > 0 Then
            For Each table In result.Tables
                ' Process each row as a potential line item
                For i As Integer = 1 To table.RowCount - 1 ' Skip header row
                    Dim item As New LineItem With {
                        .Description = If(table(i, 0)?.Text, ""),
                        .Quantity = ParseQuantity(table(i, 1)?.Text),
                        .UnitPrice = ParseAmount(table(i, 2)?.Text),
                        .Total = ParseAmount(table(i, 3)?.Text)
                    }

                    If Not String.IsNullOrEmpty(item.Description) Then
                        lineItems.Add(item)
                    End If
                Next
            Next
        End If

        Return lineItems
    End Function

    Private Function ParseQuantity(text As String) As Integer
        If String.IsNullOrEmpty(text) Then Return 0
        Dim cleaned = Regex.Replace(text, "[^\d]", "")
        Dim qty As Integer
        Return If(Integer.TryParse(cleaned, qty), qty, 0)
    End Function

    Private Function ParseAmount(text As String) As Decimal
        If String.IsNullOrEmpty(text) Then Return 0
        Dim cleaned = Regex.Replace(text, "[^\d.]", "")
        Dim amt As Decimal
        Return If(Decimal.TryParse(cleaned, amt), amt, 0)
    End Function
End Class

' Data classes for structured invoice information
Public Class InvoiceData
    Public Property InvoiceNumber As String
    Public Property InvoiceDate As DateTime?
    Public Property DueDate As DateTime?
    Public Property VendorName As String
    Public Property Total As Decimal
    Public Property Tax As Decimal
    Public Property LineItems As List(Of LineItem)
    Public Property BarcodeValues As List(Of String)
End Class

Public Class LineItem
    Public Property Description As String
    Public Property Quantity As Integer
    Public Property UnitPrice As Decimal
    Public Property Total As Decimal
End Class
$vbLabelText   $csharpLabel

发票处理:从发票中提取特定数据

使用以下代码提取特定发票数据,例如客户发票号码:

using IronOcr;
using System;
using System.Text.`RegularExpressions`;

// Initialize a new instance of the `IronTesseract` class
var ocr = new `IronTesseract`();

// Use the `OcrInput` object to load the image file
using (var input = new `OcrInput`(@"`r2.png`"))
{
    // Perform OCR on the image
    var result = `ocr.Read`(input);

    // Define a regular expression pattern for the invoice number
    var linePattern = @"INV\/\d{4}\/\d{5}";

    // Match the pattern in the extracted text
    var lineMatch = Regex.Match(`result.Text`, linePattern);

    // Check if the pattern matches any part of the text
    if (`lineMatch.Success`)
    {
        // If a match is found, print the invoice number
        var lineValue = `lineMatch.Value`;
        Console.`WriteLine`("Customer Invoice number: " + lineValue);
    }
}
using IronOcr;
using System;
using System.Text.`RegularExpressions`;

// Initialize a new instance of the `IronTesseract` class
var ocr = new `IronTesseract`();

// Use the `OcrInput` object to load the image file
using (var input = new `OcrInput`(@"`r2.png`"))
{
    // Perform OCR on the image
    var result = `ocr.Read`(input);

    // Define a regular expression pattern for the invoice number
    var linePattern = @"INV\/\d{4}\/\d{5}";

    // Match the pattern in the extracted text
    var lineMatch = Regex.Match(`result.Text`, linePattern);

    // Check if the pattern matches any part of the text
    if (`lineMatch.Success`)
    {
        // If a match is found, print the invoice number
        var lineValue = `lineMatch.Value`;
        Console.`WriteLine`("Customer Invoice number: " + lineValue);
    }
}
Imports IronOcr
Imports System
Imports System.Text.RegularExpressions

' Initialize a new instance of the IronTesseract class
Dim ocr As New IronTesseract()

' Use the OcrInput object to load the image file
Using input As New OcrInput("r2.png")
    ' Perform OCR on the image
    Dim result = ocr.Read(input)

    ' Define a regular expression pattern for the invoice number
    Dim linePattern As String = "INV/\d{4}/\d{5}"

    ' Match the pattern in the extracted text
    Dim lineMatch As Match = Regex.Match(result.Text, linePattern)

    ' Check if the pattern matches any part of the text
    If lineMatch.Success Then
        ' If a match is found, print the invoice number
        Dim lineValue As String = lineMatch.Value
        Console.WriteLine("Customer Invoice number: " & lineValue)
    End If
End Using
$vbLabelText   $csharpLabel

Visual Studio 调试控制台显示已成功创建 PDF 文件,其中客户发票号 INV/2023/00039 已使用 IronOCR 提取,确认 OCR 过程已完成且无错误发票扫描

对于复杂的提取场景,请使用专门的 OCR 配置来优化您的发票类型。OcrResult提供有关每个已识别元素的详细信息,包括坐标和用于验证的置信度分数。

发票OCR API的主要优势是什么?

IronOCR 的发票 OCR API 通过机器学习和计算机视觉技术改变了发票处理方式。 这项技术将发票文本转换为机器可读格式,简化了数据提取,便于分析、集成和流程改进。 它为发票处理提供强大的自动化功能,提高准确性并优化应付账款等工作流程。

IronOCR 利用优化的 Tesseract 结果,无需额外配置即可提供卓越的精度。 它支持 多页框架 TIFFPDF 文件 和所有流行的图像格式。 从图像中读取条形码增加了另一个提取维度。

发票处理的主要优势:

1.节省时间:将数小时缩短至数秒 2.准确性:通过置信度评分最大限度地减少误差 3.可扩展性:利用多线程处理数千个进程 4.集成:导出为可搜索的 PDF结构化格式 5.降低成本:降低运营成本

该库部署灵活,可集成到现有系统中——本地部署、云端部署或混合部署。 IronOCR 支持DockerAzureAWS ,可根据您的需求进行扩展。

生产环境可受益于 IronOCR 的许可选项,包括专门的支持和定期更新。 库中的故障排除指南工程支持可确保顺利实施。

访问主页了解更多关于IronOCR的信息。 有关发票 OCR 的更多教程,请参阅这份详细的发票 OCR 指南。 要了解如何使用计算机视觉技术识别发票字段,请查看这篇计算机视觉教程

常见问题解答

如何通过OCR自动化发票数据处理?

您可以使用IronOCR通过利用其机器学习算法来自动化发票数据处理。IronOCR从数字和扫描的发票中提取诸如供应商信息、发票号码和价格等细节,减少手动输入错误并提高效率。

设置发票OCR API涉及哪些步骤?

要使用IronOCR设置发票OCR API,请首先通过Visual Studio的NuGet包管理器下载并安装库。接下来,创建一个新的C#项目,集成IronOCR,并使用其方法加载和读取图像文件以进行文本提取。

IronOCR可以提取如发票号码之类的特定数据吗?

是的,IronOCR可以提取如发票号码之类的特定数据。它利用正则表达式来匹配提取文本中的模式,让您可以从发票中提取特定信息。

IronOCR有什么发票处理受益功能?

IronOCR包括图像预处理、条形码识别和文件解析等功能。这些功能提高了准确提取和处理各种发票格式文本的能力,改善数据采集和工作流程效率。

图像预处理如何提高OCR结果?

IronOCR中的图像预处理通过在文本提取之前优化图像质量来提高OCR结果。这包括像对比度调整和噪声减少这样的操作,可以从发票中提取更准确的数据。

是否可以将IronOCR用于数字和扫描的发票?

是的,IronOCR能够处理数字和扫描的发票。它使用先进的机器学习和计算机视觉技术从各种格式和图像质量中准确提取文本。

IronOCR如何处理多页格式和文件类型?

IronOCR支持多页格式和流行的图像和PDF文件类型。它能够有效地从复杂文档中提取文本,使其在各种发票处理应用中具有多样性。

开发人员在哪里可以找到使用IronOCR的教程?

开发人员可以在IronOCR网站上找到教程和其他资源。该网站提供了一系列学习材料,包括如何指南和博客文章,适用于在不同情境中应用IronOCR。

Kannaopat Udonpant
软件工程师
在成为软件工程师之前,Kannapat 在日本北海道大学完成了环境资源博士学位。在攻读学位期间,Kannapat 还成为了车辆机器人实验室的成员,隶属于生物生产工程系。2022 年,他利用自己的 C# 技能加入 Iron Software 的工程团队,专注于 IronPDF。Kannapat 珍视他的工作,因为他可以直接从编写大多数 IronPDF 代码的开发者那里学习。除了同行学习外,Kannapat 还喜欢在 Iron Software 工作的社交方面。不撰写代码或文档时,Kannapat 通常可以在他的 PS5 上玩游戏或重温《最后生还者》。