OCR识别推荐两个软件:

1.       Tesseract:一个开源的,由谷歌维护的OCR软件。

2.       Onenote:微软Office附带或者可以自己独立安装。

3.       ONOM:别人封装的onenote api接口

这次讲Onenote实现的OCR识别。github地址:https://github.com/everywan/Extraction.OCR

注:2010版及其以后版本OCR实现方式类似:office将其转换为特定xm格式,然后提取想要的节点就ok了;onenote2007识别比较简单:通过MODI API接口直接之别。

我这里是实现了 office2007和office2010的ocr识别函数。

源程序下载:坚果云连接(.net4.5,vs2017RC。本机环境:windows10)

  1 public class ExtractionOCR
2     {
3         #region
4         private static readonly ExtractionOCR instance = new ExtractionOCR();
5         public static ExtractionOCR Instance { get { return instance; } }
6         public static string section_path { get; set; }
7         public static int waitTime = 3 * 1000;
8         #endregion
9         /// <summary>
10         /// office2007 MODI组件OCR识别
11         /// </summary>
12         /// <param name="imgPath"></param>
13         /// <returns></returns>
14         public string Ocr_2007(string imgPath)
15         {
16             try
17             {
18                 var imgType = imgPath.Substring(imgPath.Length - 3);
19                 var data = File.ReadAllBytes(imgPath);
20                 string imgInfo = "";
21                 int i = 0;
22                 var localimgFile = AppDomain.CurrentDomain.BaseDirectory + @"\" + Guid.NewGuid().ToString() + "." + imgType;
23                 while (!imgInfo.Equals("转换成功") && i < 3)
24                 {
25                     ++i;
26                     imgInfo = this.GetBase64(data, imgType, localimgFile);
27                 }
28                 MODI.Document doc = new MODI.Document();
29                 doc.Create(localimgFile);
30                 MODI.Image image;
31                 MODI.Layout layout;
32                 doc.OCR(MODI.MiLANGUAGES.miLANG_CHINESE_SIMPLIFIED, true, true);
33                 StringBuilder sb = new StringBuilder();
34                 image = (MODI.Image)doc.Images[0];
35                 layout = image.Layout;
36                 sb.Append(layout.Text);
37                 doc = null;
38                 var localFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\" + Guid.NewGuid().ToString() + ".txt";
39                 File.WriteAllText(localFilePath, sb.ToString());
40                 Console.WriteLine(sb.ToString());
41                 return localFilePath;
42             }
43             catch (Exception e)
44             {
45                 File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\log.txt", e.ToString());
46                 return "";
47             }
48             finally
49             {
50                 GC.Collect();
51             }
52         }
53         /// <summary>
54         /// onenote 2010,注意需要先在onenote中创建笔记本,并且将至转换为onenote2007格式
55         /// 推荐使用onenote2016(个人版即可),API与2010类似,(去掉XMLSchema.xs2007参数即可)其他可参考API参数命名。
56         /// 注意1:一定要将dll属性中的“嵌入互操作类型”属性关闭
57         /// </summary>
58         /// <param name="imgPath"></param>
59         /// <returns></returns>
60         public string Ocr_2010(string imgPath)
61         {
62             try
63             {
64                 #region 确定section_path存在
65                 section_path = @"C:\Users\zhensheng\Desktop\打杂\ocr\ocr.one";
66                 if (string.IsNullOrEmpty(section_path))
67                 {
68                     Console.WriteLine("请先建立笔记本");
69                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\log.txt", "需要先在onenote中创建笔记本,并且将至转换为onenote2007格式,且将.one文件得路径赋值给section_path");
70                     return "";
71                 }
72                 #endregion
73                 #region 准备数据
74                 //后缀
75                 var imgType = Path.GetExtension(imgPath);
76                 imgPath = imgPath.Replace(".", "");
77                 var data = File.ReadAllBytes(imgPath);
78                 //根据大小确定重试次数
79                 int fileSize = Convert.ToInt32(data.Length / 1024 / 1024); // 文件大小 单位M
80                 string guid = Guid.NewGuid().ToString();
81                 string pageID = "{" + guid + "}{1}{B0}";  // 格式 {guid}{tab}{??}
82                 string pageXml;
83                 XNamespace ns;
84                 var onenoteApp = new Microsoft.Office.Interop.OneNote.Application();  //onenote提供的API
85                 if (onenoteApp == null)
86                 {
87                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\log.txt", "Microsoft.Office.Interop.OneNote.Application()创建失败");
88                     return "";
89                 }
90                 //重试使用
91                 XmlNode xmlNode;
92                 int retry = 0;
93                 #endregion
94                 do
95                 {
96                     #region 创建页面并返回pageID
97                     string sectionID;
98                     onenoteApp.OpenHierarchy(section_path, null, out sectionID, CreateFileType.cftSection);
99                     onenoteApp.CreateNewPage(sectionID, out pageID);
100                     #endregion
101                     #region 获取onenote页面xml结构格式
102                     string notebookXml;
103                     onenoteApp.GetHierarchy(null, HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2007);
104                     var doc = XDocument.Parse(notebookXml);
105                     ns = doc.Root.Name.Namespace;
106                     #endregion
107                     #region 将图片插入页面
108                     Tuple<string, int, int> imgInfo = this.GetBase64(data, imgType);
109                     var page = new XDocument(new XElement(ns + "Page",
110                                                     new XElement(ns + "Outline",
111                                                     new XElement(ns + "OEChildren",
112                                                         new XElement(ns + "OE",
113                                                         new XElement(ns + "Image",
114                                                             new XAttribute("format", imgType), new XAttribute("originalPageNumber", "0"),
115                                                             new XElement(ns + "Position",
116                                                                 new XAttribute("x", "0"), new XAttribute("y", "0"), new XAttribute("z", "0")),
117                                                             new XElement(ns + "Size",
118                                                                 new XAttribute("width", imgInfo.Item2), new XAttribute("height", imgInfo.Item3)),
119                                                             new XElement(ns + "Data", imgInfo.Item1)))))));
120                     page.Root.SetAttributeValue("ID", pageID);
121                     onenoteApp.UpdatePageContent(page.ToString(), DateTime.MinValue, XMLSchema.xs2007);
122                     #endregion
123                     #region 通过轮询访问获取OCR识别的结果,轮询超时次数为6次
124                     int count = 0;
125                     do
126                     {
127                         System.Threading.Thread.Sleep(waitTime * (fileSize > 1 ? fileSize : 1)); // 小于1M的都默认1M
128                         onenoteApp.GetPageContent(pageID, out pageXml, PageInfo.piBinaryData, XMLSchema.xs2007);
129                     }
130                     while (pageXml == "" && count++ < 6);
131                     #endregion
132                     #region 删除页面
133                     onenoteApp.DeleteHierarchy(pageID, DateTime.MinValue);
134                     //onenoteApp = null;
135                     #endregion
136                     #region 从xml中提取OCR识别后的文档信息,然后输出到string中
137                     XmlDocument xmlDoc = new XmlDocument();
138                     xmlDoc.LoadXml(pageXml);
139                     XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
140                     nsmgr.AddNamespace("one", ns.ToString());
141                     xmlNode = xmlDoc.SelectSingleNode("//one:Image//one:OCRText", nsmgr);
142                     #endregion
143                 }
144                 //如果OCR没有识别出信息,则重试三次(个人测试2010失败率为0.2~0.3)
145                 while (xmlNode == null && retry++ < 3);
146                 if (xmlNode == null)
147                 {
148                     File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\log.txt", "OCR没有识别出值");
149                     return "";
150                 }
151                 var localFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\" + Guid.NewGuid().ToString() + ".txt";
152                 File.WriteAllText(localFilePath, xmlNode.InnerText.ToString());
153                 Console.WriteLine(xmlNode.InnerText.ToString());
154                 return localFilePath;
155             }
156             catch (Exception e)
157             {
158                 File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"\log.txt", e.ToString());
159                 return "";
160             }
161         }
162         private string GetBase64(byte[] data, string imgType, string filePath)
163         {
164             using (MemoryStream ms = new MemoryStream())
165             {
166                 MemoryStream ms1 = new MemoryStream(data);
167                 Bitmap bp = (Bitmap)Image.FromStream(ms1);
168                 switch (imgType.ToLower())
169                 {
170                     case "jpg":
171                         bp.Save(ms, ImageFormat.Jpeg);
172                         break;
173                     case "jpeg":
174                         bp.Save(ms, ImageFormat.Jpeg);
175                         break;
176                     case "gif":
177                         bp.Save(ms, ImageFormat.Gif);
178                         break;
179                     case "bmp":
180                         bp.Save(ms, ImageFormat.Bmp);
181                         break;
182                     case "tiff":
183                         bp.Save(ms, ImageFormat.Tiff);
184                         break;
185                     case "png":
186                         bp.Save(ms, ImageFormat.Png);
187                         break;
188                     case "emf":
189                         bp.Save(ms, ImageFormat.Emf);
190                         break;
191                     default:
192                         return "不支持的图片格式。";
193                 }
194                 byte[] buffer = ms.ToArray();
195                 File.WriteAllBytes(filePath, buffer);
196                 ms1.Close();
197                 ms.Close();
198                 return "转换成功";
199                 //return new Tuple<string, int, int>(Convert.ToBase64String(buffer), bp.Width, bp.Height);
200             }
201         }
202         private Tuple<string, int, int> GetBase64(byte[] data, string imgType)
203         {
204             using (MemoryStream ms = new MemoryStream())
205             {
206                 MemoryStream ms1 = new MemoryStream(data);
207                 Bitmap bp = (Bitmap)Image.FromStream(ms1);
208                 switch (imgType.ToLower())
209                 {
210                     case "jpg":
211                         bp.Save(ms, ImageFormat.Jpeg);
212                         break;
213                     case "jpeg":
214                         bp.Save(ms, ImageFormat.Jpeg);
215                         break;
216                     case "gif":
217                         bp.Save(ms, ImageFormat.Gif);
218                         break;
219                     case "bmp":
220                         bp.Save(ms, ImageFormat.Bmp);
221                         break;
222                     case "tiff":
223                         bp.Save(ms, ImageFormat.Tiff);
224                         break;
225                     case "png":
226                         bp.Save(ms, ImageFormat.Png);
227                         break;
228                     case "emf":
229                         bp.Save(ms, ImageFormat.Emf);
230                         break;
231                     default:
232                         return new Tuple<string, int, int>("不支持的图片格式。", 0, 0);
233                 }
234                 byte[] buffer = ms.ToArray();
235                 ms1.Close();
236                 ms.Close();
237                 return new Tuple<string, int, int>(Convert.ToBase64String(buffer), bp.Width, bp.Height);
238             }
239         }
240     }

注意:

1.       office2007需要安装office sp2补丁。

2.       谨记 关闭onenote.dll的 嵌入互操作类型 关闭

3.       如果是在服务器上使用office/onenote,需要开启 桌面体验 功能。

4.       如果是在服务器上使用onenote 2007,需要注意的是该组件是32位的,也就是说直接调用这个接口的必须是32位程序。

5.       如果是在服务器上使用onenote 2010,出现了(Retrieving the COM class factory for component with CLSID {D7FAC39E-7FF1-49AA-98CF-A1DDD316337E} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)))这个异常,请在调用此dll的服务登陆身份修改为管理员账号,并且用此账号创建onenote笔记本,另外,本示例代码需要笔记本格式为onenote2007

a.

6.       如果有其他异常,参阅微软文档: 错误代码

参考:

1.       onenote 2010 ocr实现

2.       浅谈OCR之onenote 2010

3.       Creating OneNote 2010 Extensions with the OneNote Object Model

4.       64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

5.       ONOM :封装的onenote api类

Onenote实现OCR识别图片的更多相关文章

  1. 【转】Python OCR识别图片验证码

    转载自:博客 对于某些网站登录的时候,往往需要输入验证码才能实现登录.如果要爬虫这类网站,往往总会比这个验证码导致无法爬取数据.以下介绍一种比较折中的方法,也是比较可行的方法: 实现思想: 1.通过截 ...

  2. C++调用Asprise OCR识别图片

    在一个识别软件中发现了Asprise OCR的"身影",上官网查了一下相关信息,发现功能挺强大的,识别印刷体应该不错,遗憾的是好像不能识别中文,不过不知道它对扭曲后的英文识别能力怎 ...

  3. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇一:WPF常用知识以及本项目设计总结

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  4. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇二:基于OneNote难点突破和批量识别

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  5. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇四:关于OneNote入库处理以及审核

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  6. 你知道OneNote的OCR功能吗?office lens为其增大威力,中文也识别

    原文:[原创]你知道OneNote的OCR功能吗?office lens为其增大威力,中文也识别 OneNote提供了强大的从图片中取出文字的功能,大家只要装上了桌面版OneNote(本人用的2013 ...

  7. 以API方式调用C# dll,使用OneNote2013 sp1实现OCR识别本地图片

    http://www.cnblogs.com/Charltsing/p/OneNoteOCRAPI.html OneNote2013 OCR API调用使用说明2019.4.17 使用说明:1.安装干 ...

  8. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇三:批量处理后的txt文件入库处理

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  9. 图片文字OCR识别-tesseract-ocr

    帮助文件:https://github.com/tesseract-ocr/tesseract/blob/master/doc/tesseract.1.asc 下载地址:https://github. ...

随机推荐

  1. ASP.NET中Textbox后的必填验证控件RequiredFieldValidator的使用方法。

    制作效果如下: 实现方法: 1. 拖动RequiredFieldValidator控件到相应的textbox后位置,点击属性面板,输入ErroMessage相应信息,更改ForeColor为红色 设置 ...

  2. [源码解析]机器学习参数服务器ps-lite(4) ----- 应用节点实现

    [源码解析]机器学习参数服务器ps-lite(4) ----- 应用节点实现 目录 [源码解析]机器学习参数服务器ps-lite(4) ----- 应用节点实现 0x00 摘要 0x01 基础类 1. ...

  3. 自学linux——11.shell入门

    shell 基础 1.shell介绍(内置脚本) 程序开发的效率非常高,依赖于功能强大的命令可以迅速地完成开发任务(批处理) 语法简单,代码写起来比较轻松,简单易学 (1)什么是shell shell ...

  4. Linux--文件描述符、文件指针、索引节点

    Linux -- 文件描述符 文件描述符 Fd 当进程打开文件或创建新文件时,内核会返回一个文件描述符(非负整数),用来指向被打开的文件,所有执行I/O操作的系统调用(read.write)都会通过文 ...

  5. CentOS 8.0 安装docker 报错:Problem: package docker-ce-3:19.03.4-3.el7.x86_64 requires containerd.io >= 1

    1.错误内容 package docker-ce-3:19.03.2-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of th ...

  6. Python 和 C/C++ 拓展程序如何性能优化?看这一篇文就够

    作者:王璐璐 | 旷视 MegEngine 架构师 一. 背景 在 MegEngine imperative runtime 的早期开发中,我们面临着一些的性能优化问题.除了一些已知需要重构的地方(早 ...

  7. Jetpack MVVM 实战项目,附带源码+视频,收藏!

    从读者的反馈来看,近期大部分安卓开发已跳出舒适圈,开始尝试认识和应用 Jetpack MVVM 到实际的项目开发中. 只可惜,关于 Jetpack MVVM,网上多是 东拼西凑.人云亦云.通篇贴代码  ...

  8. 1549页Android最新面试题含答案

    在今年年初的疫情中,成了失业人员之一,于是各种准备面试,发现面试题网上很多,但是都是很凌乱的,而且一个地方一点,没有一个系统的面试题库,有题库有的没有答案或者是答案很简洁,没有达到面试的要求.所以一直 ...

  9. 最全总结 | 聊聊 Python 数据处理全家桶(PgSQL篇)

    1. 前言 大家好,我是安果! Python 数据处理全家桶,截止到现在,一共写过 6 篇文章,有兴趣的小伙伴可以去了解一下! 最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇) 最全 ...

  10. pthread_cleanup_push与pthread_cleanup_pop的理解

    一.为什么会有pthread_cleanup_push与pthread_cleanup_pop: 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit( ...