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

C# - 光学标记识别 (OMR) 引擎 1.0

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (34投票s)

2012 年 9 月 2 日

CPOL

6分钟阅读

viewsIcon

321034

downloadIcon

25516

一个读取来自相机拍摄/扫描仪扫描图像的 OMR 表格的 API。

[2015 年 3 月更新]

我发布了该引擎的一个重要更新,并就此撰写了一篇新文章。请在此链接 THIS 查看。

从现在起,我将不再回答关于本篇文章的任何问题,请参考另一个版本。V2 更好,您们报告的大部分 bug 都已清除。

介绍 

OMR(维基百科)是答案表格,并非供人类阅读。这个项目省去了购买 OMR 阅读机甚至扫描仪的费用。任何带有自动对焦功能的 >3MP 手机摄像头都可以胜任。

背景  

我搜索了 Google 以寻找一个好的 OMR 引擎,但徒劳无功,所以我决定自己做一个。通常在学校和大学里,他们使用专门的机器来读取 OMR 答题卡。在我的案例中,我需要省去购买 OMR 读取器机器,甚至扫描仪的费用!通过这个引擎可以读取用 3MP 手机摄像头(需要自动对焦)拍摄的照片。在初始阶段,我已经创建了自己的可读取的表格类型。

图像处理部分利用了 AForge.Net 的图像处理器(库包含在下载文件中)。 

[FAQ] Q: 1  它能用于其他 OMR 表格吗?

看起来很多人在反馈中反复问了同一个问题。 

"我们可以用其他 OMR 表格与这个引擎一起使用吗?" 。

答案是,"不能"。

为什么?因为在 ExtractPaperFromFlattened() 方法中使用的纸张图像提取算法。它通过查找纸张上位于纸张上的 4 个交叉圆形符号来识别扫描图像中的纸张。这些符号定义了纸张的边界,因此,可以估算出纸张的裁剪、缩放和倾斜信息。

所以,没有符号,就无法检测到纸张。

[FAQ] Q: 2  我可以创建自己的 OMR 表格吗?

在 V1 中,你不能。至少没有我的帮助,你是做不到的,除非你是超级极客。

在 V2 中,是的!查看此链接 THIS

Using the Code

在添加了所有引用(AForge 和 OMR)后,您可以使用最简单的重载方法从相机/扫描仪图像中提取 OMR 包装的表格。 

原始图像必须包含支持的表格格式的清晰视图(可打印 PDF 包含在下载文件中)。例如:

Bitmap unf = new Bitmap(panel1.BackgroundImage);
OpticalReader reader = new OpticalReader();
panel1.BackgroundImage = (System.Drawing.Image)reader.ExtractOMRSheet(unf, 
    "sheets.xml" , OMREnums.OMRSheet.A550);

这将提取表格,如下所示:

一旦表格被提取出来,您就可以使用以下方法对其进行处理:

OpticalReader rr = new OpticalReader();
MessageBox.Show(rr.getRegNumOfSheet(panel1.BackgroundImage, 
    OMREnums.OMRSheet.A550, "sheets.xml",false).ToString());

http://img33.imageshack.us/img33/3936/omr3a.jpg 

从相机/扫描仪图像中检测表格

检测表格的过程涉及检测表格的角点。在印刷文档中,角点用特定的二进制图像标记。我们检测到它们,就检测到了表格。

  1. 因此,首先,我们需要使用正确的对比度、填充、阈值和反转滤镜来展平图像。作为起点,没有对比度、亮度或填充校正的原始图像会被反转。给定一个阈值,图像然后被转换为二进制。这张图像被称为“展平图像”,是通过使用“OMR.OpticalReader.flatten”方法获得的。
  2. 一旦图像被展平,就开始进行斑点检测。在第一阶段,检测所有大小和类型的斑点,从最小斑点大小开始(这确保我们去除噪声颗粒斑点)。
  3. 首先检测左边缘,然后检测表格的右边缘。
  4. 在第一步过滤中,从图片中检测到的数百个斑点中,通过检查它们的大小与相机/扫描仪图像的尺寸比率来过滤掉大小不正确的斑点。
  5. 在第二次过滤中,过滤掉位于图像错误一侧的斑点。
  6. 在第三次过滤中,过滤掉具有异常错误纵横比的斑点(确保我们检测并拒绝由表格上的折痕/线产生的斑点)。
  7. 作为最后一个斑点过滤,所有斑点都与镜像的角点图像进行比较(之所以镜像,是因为我们在第一步中反转了图像)。
  8. 过滤后的斑点再次被重新验证,确保它们正好是四个并且位于表格的正确一侧。另外,左右边缘的长度差异不大。
  9. 验证过的斑点代表了图像坐标系中表格角点的真实位置。
  10. 图像可以从这些点从非展平图像中裁剪出来,并进行包裹以生成一个完美的矩形图像,称为 OMR 表格。
  11. 如果以上所有过滤器仅产生 4 个角点斑点,则过程继续,否则,对具有相同参数的同一函数进行递归调用,但要改变对比度校正,这可能会产生更好的结果值。

请查看带有逐行注释的“OMR.OpticalReader.ExtractOMRSheet”方法的代码。

读取提取的表格

主要的图像处理在于图像提取部分。现在下一个阶段是读取 OMR 表格。

通常,OMR 表格对一个问题有多个选项。同一问题的所有选项都打印在纸张的旁边,形成一个“块”。所有块的位置、大小和选项数量足以将其保存到 XML 文件中。位置是根据 .NET 通常遵循的坐标系记录的,即左上角为 O(0,0) (x,y),+ive x 轴朝右,+ive y 轴朝下。

要读取表格中的特定块(表格是指第一部分中提取的表格),可以调用 OMR.OpticalReader.getScoreOfSheet。此方法会重复执行上述过程,读取表格上打印的 4 个大型答案块中的所有行。

读取给定选项中的选定选项

当从文档中切出一个多项选择块时,就需要读取选定的选项。为了读取,该块被分成与其中包含的选项一样多的相等部分。然后,基于块的平均颜色,将图像转换为二进制。这就是我们将白纸转换为纯白色,并将超过一半的墨水填充像素转换为纯黑色的方法。

记录了每个子块中的黑色像素数量。

最黑的块与其他块进行比较,如果两个子划分之间存在显著差异,则将较黑的块记录为“已标记”。根据标记的选项数量,可以决定选择了哪个选项。

注意

还可以查看其他方法。这些方法可以在一次方法调用中读取单个纸张上的所有选项,并为提供的两种类型的表格创建 XML 规范表。

相机图像表格识别器的核心在于以下方法。

兴趣点 

接下来要做的是创建一个应用程序,该应用程序接受一个包含一堂课(50 名或更多学生)考试答题卡的文件夹。或者,提供一台连接到 PC 的扫描仪地址,并逐个处理图像。根据写在表格上的注册号,程序应创建一个 XLS 文件或 PDF,以便结果完全以电子方式编译。

© . All rights reserved.