一款免费且离线的.NET使用的OCR,爱你又恨你!恨你来的太晚了。

PaddleOCRSharp

本项目是一个基于百度飞桨的PaddleOCR的C++代码修改并封装的.NET的类库。包含文本识别、文本检测、基于文本检测结果的统计分析的表格识别功能,同时针对小图识别不准的情况下,做了优化,提高识别准确率。项目封装极其简化,实际调用仅一行代码,极大的方便了中下游开发者的使用和降低了PaddleOCR的使用入门级别,同时提供不同的.NET框架使用,方便各个行业应用开发与部署。

其中PaddleOCR.dll文件是基于开源项目PaddleOCR的C++代码修改而成的C++动态库,基于opencv的x64编译而成的。

模型库支持轻量版(本项目)、服务器版模型库(更准确),可以自行更改模型库适用实际需求。

关于源码编译,建议采用vs2019及以上版本编译,如果遇到无法编译,请切换成release后再切换回debug即可。

本项目包含文本识别、文本检测、基于文本检测结果的统计分析的表格识别功能,同时针对小图识别不准的情况下,做了优化,提高识别准确率。项目封装极其简化,实际调用仅几行代码,极大的方便了中下游开发者的使用和降低了PaddleOCR的使用入门级别,同时提供不同的.NET框架使用,支持框架如下:

net40;net461;netstandard2.0;netcoreapp3.1;net5.0;

方便各个行业应用开发与部署。

C++示例代码

  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <tchar.h>
  4. #include "string"
  5. #include <include/Parameter.h>
  6. #include <string.h>
  7. using namespace std;
  8. #pragma comment (lib,"PaddleOCR.lib")
  9. extern "C" {
  10. /// <summary>
  11. /// PaddleOCREngine引擎初始化
  12. /// </summary>
  13. /// <param name="det_infer"></param>
  14. /// <param name="cls_infer"></param>
  15. /// <param name="rec_infer"></param>
  16. /// <param name="keys"></param>
  17. /// <param name="parameter"></param>
  18. /// <returns></returns>
  19. __declspec(dllimport) int* Initialize(char* det_infer, char* cls_infer, char* rec_infer, char* keys, OCRParameter parameter);
  20. /// <summary>
  21. /// 文本检测
  22. /// </summary>
  23. /// <param name="engine"></param>
  24. /// <param name="imagefile"></param>
  25. /// <param name="pOCRResult">返回结果</param>
  26. /// <returns></returns>
  27. __declspec(dllimport) int Detect(int* engine, char* imagefile, LpOCRResult* pOCRResult);
  28. /// <summary>
  29. /// 释放引擎对象
  30. /// </summary>
  31. /// <param name="engine"></param>
  32. __declspec(dllimport) void FreeEngine(int* engine);
  33. /// <summary>
  34. /// 释放文本识别结果对象
  35. /// </summary>
  36. /// <param name="pOCRResult"></param>
  37. __declspec(dllimport) void FreeDetectResult(LpOCRResult pOCRResult);
  38. };
  39.  
  40. std::wstring string2wstring(const std::string& s)
  41. {
  42. int len;
  43. int slength = (int)s.length() + 1;
  44. len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
  45. wchar_t* buf = new wchar_t[len];
  46. MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
  47. std::wstring r(buf);
  48. delete[] buf;
  49. return r;
  50. }
  51.  
  52. int main()
  53. {
  54. LpOCRResult lpocrreult;
  55. OCRParameter parameter;
  56. /*parameter.enable_mkldnn = false;*/
  57. char path[MAX_PATH];
  58.  
  59. GetCurrentDirectoryA(MAX_PATH, path);
  60.  
  61. string cls_infer(path);
  62. cls_infer += "\\inference\\ch_ppocr_mobile_v2.0_cls_infer";
  63. string rec_infer(path);
  64. rec_infer += "\\inference\\ch_PP-OCRv2_rec_infer";
  65. string det_infer(path);
  66. det_infer += "\\inference\\ch_PP-OCRv2_det_infer";
  67. string ocrkeys(path);
  68. ocrkeys += "\\inference\\ppocr_keys.txt";
  69. string imagefile(path);
  70. imagefile += "\\test.jpg";
  71.  
  72. int* pEngine = Initialize(const_cast<char*>(det_infer.c_str()),
  73. const_cast<char*>(cls_infer.c_str()),
  74. const_cast<char*>(rec_infer.c_str()),
  75. const_cast<char*>(ocrkeys.c_str()),
  76. parameter);
  77.  
  78. int cout = Detect(pEngine, const_cast<char*>(imagefile.c_str()), &lpocrreult);
  79. std::wcout.imbue(std::locale("chs"));
  80. for (size_t i = 0; i < cout; i++)
  81. {
  82. wstring ss = (WCHAR*)(lpocrreult->pOCRText[i].ptext);
  83. std::wcout << ss;
  84. }
  85. FreeDetectResult(lpocrreult);
  86. FreeEngine(pEngine);
  87. std::cin.get();
  88. }

.NET示例代码

  1. OpenFileDialog ofd = new OpenFileDialog();
  2. ofd.Filter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
  3. if (ofd.ShowDialog() != DialogResult.OK) return;
  4. var imagebyte = File.ReadAllBytes(ofd.FileName);
  5. Bitmap bitmap = new Bitmap(new MemoryStream(imagebyte));
  6.  
  7. OCRModelConfig config = null;
  8. OCRParameter oCRParameter = null;
  9. OCRResult ocrResult = new OCRResult();
  10. using (PaddleOCREngine engine = new PaddleOCREngine(config, oCRParameter))
  11. {
  12. ocrResult = engine.DetectText(bmp);
  13. }
  14. if (ocrResult != null)
  15. {
  16. MessageBox.Show(ocrResult.Text,"识别结果");
  17. }

微信公众号

PaddleOCRSharp项目地址: 
码云:https://gitee.com/raoyutian/paddle-ocrsharp
github:https://github.com/raoyutian/PaddleOCRSharp

QQ群:318860399

PaddleOCRSharp,2022年,你来的晚了些,一款.NET离线使用的高精度OCR的更多相关文章

  1. 全景VR视频外包公司:长年承接VR全景视频外包(技术分享YouTube的360全景视频)

    虽然比预期来得晚了些,但YouTube终于支持360度全景视频了,这应该会吸引不少VR(虚拟现实)爱好者.今年1月,Google就表示这一功能将在“接下来”的几周出现.现在YouTube上已经有了一些 ...

  2. 我所理解的 惠普云 (HP Cloud)

    HP (惠普)于2014年5月27日宣布了它的新的云产品线 HP Helion,并宣布在接下来的两年时间内向该产品线投资10亿美金.应该说这是一笔很大的投入,充分显示了HP 在云这个领域的决心.本文试 ...

  3. 【转】iOS 9自带苹果式省电模式 依然软硬兼施

    非本人总结,转自:http://news.91.com/apple/1506/21837672.html 说好的改善和优化,iOS 9真的带来了.且不说那些经过改善的功能,iOS 9 推出的低功耗模式 ...

  4. JMS开源比较

    Java开源JMS消息中间件 mom4j mom4j是一个完全实现JMS1.1规范的消息中间件并且向下兼容JMS1.0与1.02.它提供了自己的消息处理存储使它独立于关系数据与语言,所以它的客户端可以 ...

  5. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十八║Vue基础: 指令(下)+计算属性+watch

    回顾 今天来晚辣,给公司做了一个小项目,一个瀑布流+动态视频控制的DEMO,有需要的可以联系我,公司的项目就不对外展示了(一个后端程序员真的要干前端了哈哈哈). 书接上文,昨天正式的开始了Vue的代码 ...

  6. delphi 各版本的特性

    delphi 各新版本特性收集 Delphi XE6新增了一些特性并增强了原有的功能,主要有以下几个方面:   IDE(整合开发环境)   Internet XML(扩展标记语言) Compiler( ...

  7. 为什么需要提前撰写Spec文档

    Joel on Software(中文名叫<Joel软件随想录>)算得上是一本旧书了,但里面的建议和讨论,真的是历久弥新.特别是,Joel是个有趣.牛逼的家伙:前微软Excel的职员.St ...

  8. it's over | 2019 CSP-S 第二轮认证(超长预警)

    也许应该从Day -1(2019年11月14日周四)开始说起? 卑微的我们在学长的怂恿下终于...停课了(哇我们太菜了,只停一天半的课有个卵用 早读后我带头去办公室请假,飞哥很大方地答应了,同时免了我 ...

  9. anchor_based-anchor_free object detectors

    同步到知乎anchor_based-anchor_free object detectors 前言:最近关注了大量目标检测的论文,比较火的就是anchor based和anchor free两类问题: ...

随机推荐

  1. C语言程序设计:二分查找(折半查找)

    目录 C语言程序设计:二分查找(折半查找) 1.什么是二分查找 2.二分查找的优点 3.二分查找的缺点 4.二分查找原理 5.源代码实现 6.后话 C语言程序设计:二分查找(折半查找) 1.什么是二分 ...

  2. CF336A Vasily the Bear and Triangle 题解

    Content 一个矩形的顶点为 \((0,0)\),其对顶点为 \((x,y)\),现过 \((x,y)\) 作直线,分别交 \(x\) 轴和 \(y\) 轴于 \(A,B\) 两点,使得 \(\t ...

  3. CF254A Cards with Numbers 题解

    Content 有 \(2n\) 个数,让你找出两两相等的 \(n\) 对数的编号,或者方案不存在. 数据范围:\(1\leqslant n\leqslant 3\times 10^5,1\leqsl ...

  4. CF469A I Wanna Be the Guy 题解

    Content 小 A 和小 B 正在玩一个游戏,游戏一共有 \(n\) 关,而两个人各只能通过 \(p_A,p_B\) 个关卡.问他们能否通过合作通关这个游戏. 数据范围:\(1\leqslant ...

  5. 『学了就忘』Linux日志管理 — 90、Linux中日志介绍

    目录 1.日志相关服务 2.系统中常见的日志文件 1.日志相关服务 在CentOS 6.x中日志服务已经由rsyslogd取代了原先的syslogd服务.RedHat认为syslogd已经不能满足在工 ...

  6. qt5之设置无边窗口移动

    Note qt version: 5.12 qt creator: 4.13 本文将介绍 设置无边窗口和设置窗口的移动 你要知道: QDialog 和 QMainWindow都是 QWidget的派生 ...

  7. 【LeetCode】1402. 做菜顺序 Reducing Dishes

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 贪心 日期 题目地址:https://leetcode ...

  8. 【LeetCode】421. Maximum XOR of Two Numbers in an Array 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 依次遍历每一位 前缀树 日期 题目地址:https://lee ...

  9. 【自编教材】16万8千字的HTML+CSS基础 适合从0到1-可收藏

    [图片链接有点小问题,这几天更新,敬请期待!] 目 录 第一章HTML基础 1.1 HTML简介和发展史 1.1.1 什么是HTML 1.1.2 HTML的发展历程 1.1.3 web标准 1.2 开 ...

  10. docker容器跨主机网络overlay

    前提:已部署好docker服务服务预计部署情况如下10.0.0.134 Consul服务10.0.0.135 host1  主机名mcw510.0.0.134 host2  主机名mcw6host1与 ...