热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅谈OCR之Onenote2010

原文:浅谈OCR之Onenote2010上一次我们讨论了TesseractOCR引擎的用法,作为一款老牌的OCR引擎,目前已经开源,最新版本3.0中更是加入了中文OCR功能,再加上Googl
原文: 浅谈OCR之Onenote 2010

上一次我们讨论了Tesseract OCR引擎的用法,作为一款老牌的OCR引擎,目前已经开源,最新版本3.0中更是加入了中文OCR功能,再加上Google的更新、维护,可以说是潜力很大,值得期待。由上一次的测试结果也可以看出,Tesseract的OCR结果还不是很理想,尤其是中英文混合的文字,其识别率有限。本次我们来关注下Office 2010中的Onenote,调用其API来测试OCR功能。

PS:在公司经理一直推荐使用MyBase来记录工作中遇到的问题、工作日志等,但是我一直坚持使用Onenote :)

测试代码下载

在Visual Studio 2010 Ultimate + Onenote 2010 x64中测试通过

转载请注明出处:http://www.cnblogs.com/brooks-dotnet/archive/2010/10/07/1845313.html

 

1、Onenote 2010 新特性:

New features in 2010:

Gather, organize, and search

Sharing and universal access

  • Organize page tabs better:
    • Multi-level subpages
    • Collapse subpages
  • Jump to any page with a quick search
  • Dock to Desktop
  • Link to other notes, like a wiki
  • Quick Styles for making headings
  • Auto-link notes to Web pages and documents
  • Insert Math
  • Notes on Outlook Tasks
  • Send content to any section in OneNote
  • Access from anywhere:
    • Share on the Web
    • View and edit in a browser
    • Sync notes to OneNote Mobile
  • Share notes:
    • Unread changes are highlighted
    • See author initials
    • Version history
    • Find recent edits
    • Find edits by author
    • Faster sync with SharePoint

   

   

Examples:

   

:
                        bp.Save(ms, ImageFormat.Jpeg);
                        
break ;
                    
case   " .jpeg " :
                        bp.Save(ms, ImageFormat.Jpeg);
                        
break ;
                    
case   " .gif " :
                        bp.Save(ms, ImageFormat.Gif);
                        
break ;
                    
case   " .bmp " :
                        bp.Save(ms, ImageFormat.Bmp);
                        
break ;
                    
case   " .tiff " :
                        bp.Save(ms, ImageFormat.Tiff);
                        
break ;
                    
case   " .png " :
                        bp.Save(ms, ImageFormat.Png);
                        
break ;
                    
case   " .emf " :
                        bp.Save(ms, ImageFormat.Emf);
                        
break ;
                    
default :
                        
this .labMsg.Content  =   " 不支持的图片格式。 " ;
                        
return ;
                }

                
byte [] buffer  =  ms.GetBuffer();
                
string  _Base64  =  Convert.ToBase64String(buffer);

 

 

  

2.7、构建插入图片后的Onenote XML代码:

 

准备工作
                var onenoteApp  =   new  Microsoft.Office.Interop.OneNote.Application();
                
string  notebookXml;

                onenoteApp.GetHierarchy(
null , Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages,  out  notebookXml);

                var doc 
=  XDocument.Parse(notebookXml);
                var ns 
=  doc.Root.Name.Namespace;
                var pageNode 
=  doc.Descendants(ns  +   " Page " ).FirstOrDefault();
                var existingPageId 
=  pageNode.Attribute( " ID " ).Value;

 

 

  

2.8、这里有一处小细节,就是Onenote XML中图片格式只支持如下几种:auto|png|emf|jpg,故需要将图片格式做一下处理:

 

图片格式处理
                     string  ImgExtension  =  file.Extension.ToLower().Substring( 1 );
                    
switch  (ImgExtension)
                    {
                        
case   " jpg " :
                            ImgExtension 
=   " jpg " ;
                            
break ;
                        
case   " png " :
                            ImgExtension 
=   " png " ;
                            
break ;
                        
case   " emf " :
                            ImgExtension 
=   " emf " ;
                            
break ;
                        
default :
                            ImgExtension 
=   " auto " ;
                            
break ;
                    }

 

 

  

2.9、下面这段是关键代码了,使用Linq to XML构造出插入图片后的Onenote XML:

目标格式
                /*Onenote 2010 中图片的XML格式
                   
< one:Image  format =""  originalPageNumber ="0"  lastModifiedTime =""  objectID ="" >
                        
< one:Position  x =""  y =""  z ="" />
                        
< one:Size  width =""  height ="" />
                        
< one:Data > Base64 one:Data >
                  
                        //以下标签由Onenote 2010自动生成,不要在程序中处理,目标是获取OCRText中的内容。
                        
< one:OCRData  lang ="en-US" >
                        
< one:OCRText >
                            
   OCR后的文字    ]]>
                        
one:OCRText >
                        
< one:OCRToken  startPos ="0"  region ="0"  line ="0"  x ="4.251968383789062"  y ="3.685039281845092"  width ="31.18110275268555"  height ="7.370078563690185" />
                        
< one:OCRToken  startPos ="7"  region ="0"  line ="0"  x ="39.40157318115234"  y ="3.685039281845092"  width ="13.32283401489258"  height ="8.78740119934082" />
                        
< one:OCRToken  startPos ="12"  region ="0"  line ="1"  x ="4.251968383789062"  y ="17.85826683044434"  width ="23.52755928039551"  height ="6.803150177001953" />
                        
< one:OCRToken  startPos ="18"  region ="0"  line ="1"  x ="32.031494140625"  y ="17.85826683044434"  width ="41.10236358642578"  height ="6.803150177001953" />
                        
< one:OCRToken  startPos ="28"  region ="0"  line ="1"  x ="77.66928863525391"  y ="17.85826683044434"  width ="31.46456718444824"  height ="6.803150177001953" />
                        ................
                   
one:Image >       
                */


                /*ObjectID格式
                  The representation of an object to be used for identification of objects on a page. Not unique through OneNote, but unique on the page and the hierarchy. 
                   
< xsd:simpleType  name ="ObjectID"  " >
                      
< xsd:restriction  base ="xsd:string" >
                         
< xsd:pattern  value ="\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}\{[0-9]+\}\{[A-Z][0-9]+\}"   />
                      
xsd:restriction >
                   
xsd:simpleType >
                */

 

 

 

Linq to XML构造图片所需XML
                    var page  =   new  XDocument( new  XElement(ns  +   " Page " ,
                                     
new  XElement(ns  +   " Outline " ,
                                       
new  XElement(ns  +   " OEChildren " ,
                                         
new  XElement(ns  +   " OE " ,
                                           
new  XElement(ns  +   " Image " ,
                                             
new  XAttribute( " format " , ImgExtension),  new  XAttribute( " originalPageNumber " " 0 " ),
                                             
new  XElement(ns  +   " Position " ,
                                                    
new  XAttribute( " x " " 0 " ),  new  XAttribute( " y " " 0 " ),  new  XAttribute( " z " " 0 " )),
                                             
new  XElement(ns  +   " Size " ,
                                                    
new  XAttribute( " width " , bp.Width.ToString()),  new  XAttribute( " height " , bp.Height.ToString())),
                                                
new  XElement(ns  +   " Data " , _Base64)))))));
                    page.Root.SetAttributeValue(
" ID " , existingPageId);
                    onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue);

 

 

  

2.10、线程休眠几秒钟,等待OCR完成,Onenote OCR根据图片大小需要消耗一些时间:

 

                     // 线程休眠时间,单位毫秒,若图片很大,则延长休眠时间,保证Onenote OCR完毕
                    System.Threading.Thread.Sleep(Int32.Parse(System.Configuration.ConfigurationManager.AppSettings[ " WaitTIme " ]));

 

 

  

2.11、为了便于提取OCR后的结果,将构造好的Onenote XML代码写入一个临时的XML文件:

 

写入临时XML文件
                     string  pageXml;
                    onenoteApp.GetPageContent(existingPageId, 
out  pageXml, Microsoft.Office.Interop.OneNote.PageInfo.piAll);

                    
// 获取OCR后的内容
                    FileStream tmpXml  =   new  FileStream(System.Configuration.ConfigurationManager.AppSettings[ " tmpPath " +   @" \tmp.xml " , FileMode.Create, FileAccess.ReadWrite);
                    StreamWriter sw 
=   new  StreamWriter(tmpXml);
                    sw.Write(pageXml);
                    sw.Flush();
                    sw.Close();
                    tmpXml.Close();

 

 

  

2.12、使用Linq to XML和XPath表达式提取OCR后的结果:

 

提取 OCR 后的结果
                    FileStream tmpOnenote  =   new  FileStream(System.Configuration.ConfigurationManager.AppSettings[ " tmpPath " +   @" \tmp.xml " , FileMode.Open, FileAccess.ReadWrite);
                    XmlReader reader 
=  XmlReader.Create(tmpOnenote);
                    XElement rdlc 
=  XElement.Load(reader);

                    XmlNameTable nameTable 
=  reader.NameTable;
                    XmlNamespaceManager mgr 
=   new  XmlNamespaceManager(nameTable);
                    mgr.AddNamespace(
" one " , ns.ToString());

                    StringReader sr 
=   new  StringReader(pageXml);
                    XElement onenote 
=  XElement.Load(sr);

                    var xml 
=  from o  in  onenote.XPathSelectElements( " //one:Image " , mgr)
                              select o.XPathSelectElement(
" //one:OCRText " , mgr).Value;
                    
this .txtOCRed.Text  =  xml.First().ToString();

 

 

  

2.13、释放占用的资源:

 

                    sr.Close();
                    reader.Close();
                    tmpOnenote.Close();

 

 

  

2.14、最后将OCR后的结果写入到输出文件中:

 

写入输出文件
                FileStream fs  =   new  FileStream( this .__OutputFileName, FileMode.Create, FileAccess.ReadWrite);
                StreamWriter sw 
=   new  StreamWriter(fs);
                sw.Write(
this .txtOCRed.Text);
                sw.Flush();
                sw.Close();
                fs.Close();

                
this .labMsg.Content  =   " OCR成功。 " ;

 

 

  

由于我安装的是Onenote 2010 x64英文版,未找到中文语言包,故先测试下英文OCR。

2.15、本地图片测试结果:

 

2.16、网络图片测试结果:

网络图片是先下载到本地,后面步骤和本地图片一样。

 

小结

此方法的优点是效率很高,可扩展性强,只要改改配置文件、Linq to XML代码就可以完成很多附加工作。

缺点是,要求客户端必须要安装Onenote,且至少要有一个打开的Page,OCR时无法判断哪一个图片是正在OCR的,若连续操作则显示结果混乱。

此外,我没有找到编程建立Onenote文档的方法,以及对Onenote XML架构了解的还不够多,对一些元素不知道如何编程生成,如ObjectID等。

综上所述,Onenote 2010的OCR水平还是很高的,和Tesseract相比,OCR的准确率与效率均提高了不止一个档次,但是鉴于Onenote 2010 API十分简陋,远不及Word、Excel等操作方便,且官方文档对于Onenote 2010 XML架构的介绍还不是很详细,缺少示例。希望Office 15、Onenote 2014能有所改进吧。关于OCR的介绍到此告一段落,欢迎感兴趣的朋友继续讨论。


推荐阅读
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • REVERT权限切换的操作步骤和注意事项
    本文介绍了在SQL Server中进行REVERT权限切换的操作步骤和注意事项。首先登录到SQL Server,其中包括一个具有很小权限的普通用户和一个系统管理员角色中的成员。然后通过添加Windows登录到SQL Server,并将其添加到AdventureWorks数据库中的用户列表中。最后通过REVERT命令切换权限。在操作过程中需要注意的是,确保登录名和数据库名的正确性,并遵循安全措施,以防止权限泄露和数据损坏。 ... [详细]
  • 本文详细介绍了使用 SQL Load 和 Excel 的 Concatenate 功能将数据导入 ORACLE 数据库的方法和步骤,同时介绍了使用 PL/SQL tools 将数据导入临时表的方法。此外,还提供了一个转链接,可参考更多相关内容。摘要共计XXX字。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了使用jQuery实现图片预加载和等比例缩放的方法,同时提供了演示和相关代码。该方法可以重置图片的宽度和高度,并使图片在水平和垂直方向上居中显示。 ... [详细]
  • 本文介绍了Hive常用命令及其用途,包括列出数据表、显示表字段信息、进入数据库、执行select操作、导出数据到csv文件等。同时还涉及了在AndroidManifest.xml中获取meta-data的value值的方法。 ... [详细]
author-avatar
李明hallo_766
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有