Kernel Memory 中使用 PaddleSharp OCR

Kernel Memory 中进行文档处理的时候可以上传图片作为文档,这时候就需要使用到 OCR 技术来识别图片中的文字。

官方默认的库中,提供了 Azure Document Intelligence 的扩展服务,可以通过 Azure 的服务来进行 OCR。

方法也非常简单,只需要在构建 Kernel Memory 的时候,调用 WithAzureAIDocIntel 方法,提供相应的参数即可。

var _ = new KernelMemoryBuilder(appBuilder.Services)
//...
.WithAzureAIDocIntel(new AzureAIDocIntelConfig()) // <- register azure document intelligence
.Build();

如果没有Azure 服务的话,也可以使用自定义的 OCR 服务,例如 PaddleSharp OCR。

实现自定义的 OCR 服务,需要实现 IOcrEngine 接口,该接口的定义相对比较简单,其中只有一个ExtractTextFromImageAsync方法。


public interface IOcrEngine
{
Task<string> ExtractTextFromImageAsync(Stream imageContent, CancellationToken cancellationToken = default(CancellationToken));
}

使用 PaddleSharp 我们需要安装以下 Nuget 包:

Sdcb.PaddleInference
Sdcb.PaddleOCR
Sdcb.PaddleInference.runtime.win64.mkl
OpenCvSharp4.runtime.win
Sdcb.PaddleOCR.Models.Local

然后实现 IOcrEngine 接口:


public class PaddleSharpOcrEngine(FullOcrModel model) : IOcrEngine
{
private readonly FullOcrModel _model = model; public async Task<string> ExtractTextFromImageAsync(Stream imageContent, CancellationToken cancellationToken = default)
{
using var all = new PaddleOcrAll(_model, PaddleDevice.Mkldnn());
using var memoryStream = new MemoryStream();
await imageContent.CopyToAsync(memoryStream);
using Mat src = Cv2.ImDecode(memoryStream.ToArray(), ImreadModes.Color);
PaddleOcrResult result = all.Run(src);
return result.Text;
}
}

在构建 Kernel Memory 的时候,注册自定义的 OCR 服务:

var model = LocalFullModels.EnglishV3;
var memory = new KernelMemoryBuilder(appBuilder.Services)
//...
.AddSingleton<IOcrEngine>(new PaddleSharpOcrEngine(model))// <- register paddle ocr
.Build();

注册完成之后,后续处理图片文件的过程中,就会自动调用 PaddleSharp OCR 服务了。

await memory.ImportDocumentAsync("./kernel_memory_readme.png");

var question = "What's Kernel Memory?";

var answer = await memory.AskAsync(question);

Console.WriteLine($"Q: {question}");
Console.WriteLine($"A: {answer.Result}");

以上代码实现已经上传至 GitHub.

参考

Kernel Memory 中使用 PaddleSharp OCR的更多相关文章

  1. [Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中?

    [Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中? 以如下方法来查看 POPULATE_STATUS 是不行的. SQL> select ins ...

  2. Kernel Memory Layout on ARM Linux

    这是内核自带的文档,讲解ARM芯片的内存是如何布局的!比较简单,对于初学者可以看一下!但要想深入理解Linux内存管理,建议还是找几本好书看看,如深入理解Linux虚拟内存,嵌入系统分析,Linux内 ...

  3. kernel memory code learn

    mem alloc page Noticeble: 1. there are two kind of page: virtual page, physical page. 2. the page st ...

  4. #define barrier() __asm__ __volatile__("": : :"memory") 中的memory是gcc的东西

    gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...

  5. 【CCS仿真】如何将CCS仿真时memory中的数据以Hex、Integer、 Long 、Float、 Addressable Unit类型保存到PC

    2013-12-04 19:07:05 将在CCS中仿真的数据导入电脑上时,可以选择不同的数据类型,以便分析,具体方法如下: 在CCS菜单中,选择File—>Data—>Save,弹出以下 ...

  6. RPA中房产证的 OCR 识别

    客户需求,识别一些证件内容,包括身份证.户口本.营业执照.银行卡以及房产证,前四个比较容易实现,不管是艺赛旗的 RPA 还是百度的 OCR 都有接口,直接调用即可,但是都没有房产证的 OCR 识别,只 ...

  7. 在Mac上 python中使用tesseract OCR (Pytesser) 识别图片中的文字

    仓库地址:https://github.com/RobinDavid/Pytesser brew install tesseract sudo pip install opencv-python 安装 ...

  8. laravel App\Kernel.php中的middleware、middlewareGroups、routeMiddleware

    万事万物总逃不出一个理字,程序尤其如此,你之所以活得轻松,是因为有人替你负重前行,帮你屏蔽掉了很多乱七八糟的事情,但总有一天你要直面这些事情.程序亦是如此,某个框架你用的很轻松,那是因为底层逻辑已经有 ...

  9. 【语义分割】large kernel matters中GCN模块的pytorch实现

    GCN模块的实现比较简单,在giuhub上看到两种实现,轻微不同 实现一:https://github.com/ycszen/pytorch-segmentation/blob/master/gcn. ...

  10. Linux Context , Interrupts 和 Context Switching 说明

    一. 进程Context 定义 当一个进程在执行时, CPU的所有寄存器中的值.进程的状态以及堆栈中的内容,比如各个变量和数据,包括所有的寄存器变量.进程打开的文件.内存信息等.这些信息被称为该进程的 ...

随机推荐

  1. Solution -「BZOJ 3771」Triple

    Description Link. 给你一个序列,你每次可以取 \(1\sim3\) 个数然后计算和,问你对于每一种和,方案数是多少. Solution 设一个 OGF \(A(x)=\sum_{i= ...

  2. Solution Set -「ABC 192」

    「ABC 113A」Star Link. 略. #include<cstdio> int x; int main() { scanf("%d",&x); for ...

  3. 【RocketMQ】DLedger模式下的选主流程分析

    RocketMQ 4.5版本之前,可以采用主从架构进行集群部署,但是如果master节点挂掉,不能自动在集群中选举出新的Master节点,需要人工介入,在4.5版本之后提供了DLedger模式,使用R ...

  4. Redis系列之——Redis-Sentinel

    文章目录 一 主从复制高可用 二 架构说明 三 安装配置 四 客户端连接 一 主从复制高可用 #主从复制存在的问题: #1 主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave ...

  5. torch.nn.ReLU(inplace=True)的具体含义:

    首先根据源文档中的ReLU(x)=max(0,x),得出结论.大于0的数值不变,小于0的数据变成0. 补充:这里需要注意的是 ReLU并没有限制数据的大小. 这是对应的文档链接:https://pyt ...

  6. java算法之排序算法大全

    ①排序 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方 ...

  7. Kafka的零拷贝技术Zero-Copy

    传统的拷贝过程 流程步骤: (1)操作系统将数据从磁盘文件中读取到内核空间的页面缓存: (2)应用程序将数据从内核空间读入用户空间缓冲区: (3)应用程序将读到数据写回内核空间并放入socket缓冲区 ...

  8. Java开发面试--群面专区

    目录 一.群面背景 二.群面流程 三.群面角色 四.群面细节 五.群面礼仪 六.群面话术 七.个人演讲 八.群面题型 群面也称无领导小组~ 候选人们被要求在一个相对自由的环境中展示他们的能力,并在没有 ...

  9. Android Kotlin 协程初探

    1 它是什么(协程 和 Kotlin协程) 1.1 协程是什么 维基百科:协程,英文Coroutine [kəru'tin] (可入厅),是计算机程序的一类组件,推广了协作式多任务的子程序,允许执行被 ...

  10. Kubernetes跨StorageClass迁移,切换Rainbond默认SC

    基于主机安装或基于Kubernetes安装的 Rainbond 集群(均使用默认参数安装),默认使用的共享文件存储是 NFS ,以 Pod 方式运行在 Kubernetes 中,但这种方式也有一些无法 ...