65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 LEADTOOLS 自动分类扫描文档

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2013年7月2日

CPOL

4分钟阅读

viewsIcon

28212

downloadIcon

791

使用 LEADTOOLS 自动分类扫描文档

引言

文档成像无疑在节约树木和物理存储空间方面发挥了作用,但在某些情况下,它并未能节省多少时间和精力。选择无纸化账单或自行手动扫描纸质文档是归档所有账单、发票、财务报表等内容的好方法。然而,要仔细地组织好您的数字文件柜,仍然需要花费大量的时间和精力。毕竟,如果将来几乎找不到数字化归档的文档,那它还有什么意义呢?

对于记忆力好、习惯良好的人来说,这种情况可能不会太令人不知所措,但对于每天处理数千份文档、有数百人使用同一个数字档案的中大型企业和公司来说呢?如果没有某种自动化,您将承担巨大的人力成本,而且——更令人烦恼的是——会为人为错误提供广阔的机会。

想象一下,能够将所有扫描的文档放入一个文件夹,并且自动完成以逻辑、一致的方式移动和重命名文件的所有工作。 LEADTOOLS 表单识别与处理凭借其高级、灵活且强大的图像处理库,完美地满足了这一需求。使用 LEADTOOLS 构建的应用程序可以将扫描文档与已知模板进行比较,并正确地分类文档类型。在正确识别文档后,LEADTOOLS 就可以从表单的指定位置提取 OCR、OMR、条形码等信息。

处理文档存储库

解决这一难题的第一步是处理和管理一个中心位置,所有扫描的文档都放置在此进行分类。有多种方法可以实现这一点,例如使用 Web 服务、Windows 服务,或者让一只猴子按按钮。本示例中选择的方法是一个简单的控制台应用程序,然后通过 Windows 任务计划程序进行调度运行。

管理存储库的代码相对简单,因为它主要使用 `System.IO` 命名空间进行基本的文件和文件夹操作。然而,应用程序中最关键的部分已委托给 `DocumentClassifier`,该类封装了 LEADTOOLS 表单识别功能,以返回用于移动和重命名文档的数据。

// Check the scanned document repository for new documents
string[] newDocuments = Directory.GetFiles(docRepositoryNewDocs);
DocumentClassifier docClassifier = new DocumentClassifier(docRepositoryMasterForms);
string movedDocumentName, masterFormSubFolder;
foreach (string currentDoc in newDocuments)
{
   movedDocumentName = null;
   // Try to match this document against known document types
   ClassifiedDocument classifiedDoc = docClassifier.ClassifyDocument(currentDoc);
   if (classifiedDoc.MasterFormName != null)
   {
      // Add the subfolder for the master form if it doesn't exist
      masterFormSubFolder = string.Format(@"{0}{1}\", 
         docRepositoryRoot,classifiedDoc.MasterFormName);
      if (!Directory.Exists(masterFormSubFolder))
         Directory.CreateDirectory(masterFormSubFolder);

      // rename the file according to the date found
      if (classifiedDoc.DocumentDate != DateTime.MinValue)
      {
         movedDocumentName = string.Format("{0}{1}{2}", 
            masterFormSubFolder,
            classifiedDoc.DocumentDate.ToString("yyyyMMdd"),
            currentDoc.Substring(currentDoc.LastIndexOf('.'), 
                currentDoc.Length - currentDoc.LastIndexOf('.')));
      }
      else
      {
         // Didn't find a date to rename with, so just move it
         movedDocumentName = currentDoc.Replace(docRepositoryNewDocs, masterFormSubFolder);
      }
   }
   else
   {
      movedDocumentName = currentDoc.Replace(docRepositoryNewDocs, 
          docRepositoryUnclassifiedDocs);
   }

   if (!string.IsNullOrEmpty(movedDocumentName))
      File.Move(currentDoc, movedDocumentName);
}

使用 LEADTOOLS 表单识别

在 LEADTOOLS 开始分类文档之前,它必须知道如何分类它们,这通过创建一组主表单模板来完成。LEADTOOLS 提供了一个主表单编辑器演示,我们将使用它为两个不同的发票添加一个主表单,其中包含一个 OCR 字段,用于提取发票日期,该日期可用于重命名文件。

图 1:使用主表单编辑器定义主表单模板

现在我们的主表单已定义,我们可以开始处理文档了。我们已经扫描了两个基于主表单填写的发票,以及一张没有已知模板的税务表。对于“New”文件夹中的每个文件,LEADTOOLS 都会将其与主表单进行比较。如果找到匹配项,它将处理文档的字段,并返回表单的名称和日期字段。

// Create an OCR Engine for each processor on the machine. This 
// allows for optimal use of thread during recognition and processing.
ocrEngines = new List<IOcrEngine>();
for (int i = 0; i < Environment.ProcessorCount; i++)
{
   ocrEngines.Add(OcrEngineManager.CreateEngine(OcrEngineType.Advantage, false));
   ocrEngines[i].Startup(formsCodec, null, String.Empty, String.Empty);
}
// Point repository to directory with existing master forms 
formsRepository = new DiskMasterFormsRepository(formsCodec, _MasterFormFolder);
autoEngine = new AutoFormsEngine(formsRepository, ocrEngines, null, AutoFormsRecognitionManager.Default | AutoFormsRecognitionManager.Ocr, 30, 70, true);

// Run the forms recognition on this document
AutoFormsRunResult runResult = autoEngine.Run(document, null);
if (runResult != null)
{
   // In this example we use two pieces of information to organize the classified forms:
   // 1. Form name is used for the sub folder
   // 2. "ClassificationRenameDate" field for the file name
   retClassifiedDocument.MasterFormName = runResult.RecognitionResult.MasterForm.Name;

   // Process the recognized form and extract desired info
   foreach (FormPage formPage in runResult.FormFields)
   {
      foreach (FormField field in formPage)
      {
         if (field != null && field.Name == "ClassificationRenameDate")
         {
            retClassifiedDocument.DocumentDate = DateTime.Parse((
                field.Result as TextFormFieldResult).Text);
         }
      }
   }
}

图 2:分类前的表单存储库和子文件夹

图 3:分类后的表单存储库和子文件夹

正如您所见,这两张发票已正确匹配到其主表单,并根据日期字段进行了重命名。此外,未分类文档文件夹充当了故障安全机制,使应用程序能够以最小的努力进行扩展和适应。当您遇到不在主表单集合中的新文档类型时,只需将其中一个图像用作模板,添加要提取的字段,然后将未分类文档移回“New”文件夹,以便在应用程序下次运行时重新处理。

更进一步

这个简单的解决方案具有巨大的扩展和适应潜力。例如,您可以轻松地通过连接到 Google Docs、SkyDrive 或 iCloud 等云服务来在线管理您的文档。同样,企业可以将其改编为监控和组织收到的传真和电子邮件附件,或者使用识别的字段数据并将其直接存储到数据库中。最重要的是,LEADTOOLS 表单识别可以处理您想要的扫描文档中的信息量,无论多少,将其用途远远扩展到仅仅是组织和归档。表单字段、复选框、发票金额等都可以提取,以加快任何工作流程。

下载完整的表单识别示例

您可以下载包含上述功能的完整功能演示。要运行此示例,您需要以下条件:

支持

需要帮助才能使此示例正常工作吗? 联系我们的支持团队以获得免费技术支持!有关定价或许可问题,您可以联系我们的销售团队(sales@leadtools.com)或致电 704-332-5532。

© . All rights reserved.