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

使用 LEADTOOLS 创建和处理 OMR 表单

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2013年8月1日

CPOL

5分钟阅读

viewsIcon

40428

downloadIcon

2382

使用 LEADTOOLS 创建和处理 OMR 表单

表单识别和处理在世界各地用于处理各种任务,包括分类、文档归档、光学字符识别和光学标记识别。在这些通用类别中,OMR因设置OMR表单所需的时间以及准确检测扫描文档中已填写OMR字段的难度而被低估和低度使用。创建和处理OMR表单可能是一场耗时的噩梦,这篇白皮书将讨论如何通过自动检测、分类和处理来缓解这些问题。

大多数表单包含少量OMR字段来捕获性别和婚姻状况等信息。由于需要处理的字段很少,因此这些字段几乎不会造成任何困难。另一方面,由于页面上可以容纳大量的问题,创建和处理以多项选择题为主的表单明显更加困难。此外,复选框、圆圈和其他OMR字段的小尺寸会产生潜在的过度敏感性,从而导致更多的假阴性或假阳性。

下面我们将更详细地探讨如何通过开发一个使用LEADTOOLS的OMR表单识别应用程序来缓解这两个常见问题。这个屡获殊荣的图像SDK包含将节省时间且对程序员友好的API与最先进的识别精度和速度相结合所需的所有工具,从而在您的最终解决方案中获得无与伦比的质量。

使用LEADTOOLS OCR为母版表单添加OMR字段

表单识别应用程序的第一步是构建母版表单。这些母版表单或空白表单模板有两个主要目的。首先,它用于识别扫描文档属于哪种类型的表单。其次,字段指示表单上将识别和提取数据的区域。

对于许多系统来说,创建基于OMR的表单可能是一个繁琐的过程,因为问卷、答题卡或测试涉及大量的重复性工作。人们可能会花费数小时手动在框周围绘制每一个OMR字段。幸运的是,LEADTOOLS能够通过其IOcrEngine.AutoZone函数自动检测所有OMR字段。在找到页面上的每个区域后,您可以遍历集合并为每个OMR区域添加一个新的OMR字段。

 FormPages formPages = currentMasterForm.ReadFields();

// Create OCR Engine
using (IOcrEngine ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.Advantage, false))
{
   ocrEngine.Startup(null, null, null, null);
   ocrEngine.SettingManager.SetEnumValue("Recognition.Zoning.Options", "Detect Text, 
       Detect Graphics, Use Text Extractor, Detect Checkbox");
 
   using (IOcrDocument ocrDocument = ocrEngine.DocumentManager.CreateDocument())
   {
      // Auto zone
      ocrDocument.Pages.AddPages(rasterImageViewer1.Image, 1, 1, null);
      ocrDocument.Pages.AutoZone(OcrZoneParser.Leadtools, OcrZoneFillMethod.Omr, 
         LogicalUnit.Pixel, 0, 0, null);
 
      // Add a form field for each OMR zone
      FormField newField;
      IOcrZoneCollection zones = ocrDocument.Pages[0].Zones;
      for (int i = 0; i < zones.Count; i++)
      {
         if (zones[i].FillMethod == OcrZoneFillMethod.Omr)
         {
            newField = new OmrFormField();
            newField.Bounds = zones[i].Bounds;
            newField.Name = string.Format("OMR Field {0}", i);
            formPages[oldSelectedPageIndex].Add(newField);
         }
      }
   }
 
   currentMasterForm.WriteFields(formPages);
}

图1:OMR字段检测后的母版表单编辑器

OCR引擎的AutoZone方法用于获取每个区域的位置,但命名它们的方式有很多种。这个简单的示例为区域提供了基本名称,但您可以通过检查FormField.Bounds属性来确定哪些区域在同一行或同一列,从而扩展此逻辑并更智能地命名区域。此外,您还可以使用母版表单编辑器演示或手动编辑存储字段数据的XML文件。

使用LEADTOOLS表单识别和处理

大多数扫描文档处理系统必须处理不止一种类型的表单。一个可行但效率不高的解决方案可能会为每种需要处理的表单类型使用一个不同的应用程序、按钮或对话框。这当然可以用来自动化数据处理,但它受限于需要手动告知应用程序使用哪个表单模板来处理扫描图像的要求。一个理想的解决方案是能够自动识别或分类表单,然后根据这些发现进行处理。LEADTOOLS提供可靠且灵活的表单识别功能,包括标志、深浅区域、OCR、条形码等多种分类数据。

// 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, masterFormsFolder);
autoEngine = new AutoFormsEngine(formsRepository, ocrEngines, null, 
    AutoFormsRecognitionManager.Default | AutoFormsRecognitionManager.Ocr, 30, 80, true);
 
string[] formsToRecognize = Directory.GetFiles(filledFormsFolder);
progressBar1.Maximum = formsToRecognize.Length;
for (int i = 0; i < formsToRecognize.Length; i++)
{
   // Recognize (Classify) the form
   lblStatus.Text = string.Format("Recognizing form {0} of {1}", i + 1, 
       formsToRecognize.Length);
   AutoFormsRunResult runResult = autoEngine.Run(formsToRecognize[i], null);
   if (runResult != null)
   {
      // Recognition was successful
      lblStatus.Text = string.Format("Processing form {0} of {1}", i + 1, 
          formsToRecognize.Length);
      ProcessResults(runResult);
   }
 
   progressBar1.Value++;
}

从已填写的OMR表单中提取答案

一旦表单成功识别,就可以处理字段以从填写的文档中提取OMR数据。在选择OMR解决方案时,一个重要的考虑因素是它在处理填写风格差异方面的准确性。即使向填写表单的人传达了严格的规则,人们填写OMR字段的方式仍然会存在差异。LEADTOOLS在OMR准确性方面表现出色,能够区分已填写和未填写的框,而不管填写风格如何。例如,请看以下三个已填写的调查问卷中同一问题的屏幕截图。

图2:OMR字段填写方式的差异

如果您还记得图1,您可以看到字段是按问题编号和列编号用连字符分隔命名的。有了这个命名范例,我们就可以轻松确定每个列中填写的复选框,并将其添加到我们的数据源中。

int nNewRowIndex = dataGridView1.Rows.Add();
foreach (FormPage formPage in runResult.FormFields)
{
   foreach (FormField field in formPage)
   {
      if (field.Result.GetType() == typeof(OmrFormFieldResult))
      {
         // Was this checkbox filled?
         if ((field.Result as OmrFormFieldResult).Text == "1")
         {
            // Get the question number and value (column number) of this checkbox
            string[] strQuestionValue = field.Name.Split('-');
            dataGridView1.Rows[nNewRowIndex].Cells[string.Format("col{0}", 
                strQuestionValue[0])].Value = strQuestionValue[1];
         }
      }
   }
}

图3:已填写调查问卷的结果

当然,有许多方法可以命名字段并将答案关联到您的数据源。通过在应用程序的早期阶段进行一些规划,您可以使用LEADTOOLS设计您的OMR表单识别解决方案,以适应任何母版表单和数据源,从而获得可靠、灵活且最重要的是准确的解决方案。

下载完整的表单识别示例

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

支持

需要帮助来设置并运行此示例吗?请联系我们的支持团队以获得免费技术支持!有关定价或许可问题,您可以联系我们的销售团队(sales@leadtools.com)或致电704-332-5532。

关于 LEADTOOLS

LEAD Technologies自1990年以来一直是数字成像工具的领先提供商。其屡获殊荣的LEADTOOLS工具包系列帮助开发人员快速轻松地将光栅、文档、医疗、多媒体、矢量和Internet成像集成到他们的应用程序中。使用LEADTOOLS满足您的成像需求,可以让您将更多时间花在用户界面和应用程序特定代码上,从而加快开发周期并提高投资回报率。

© . All rights reserved.