[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-96031":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},96031,"SimdPaddleOCR","sdcb\u002FSimdPaddleOCR","sdcb","纯 C# PP-OCRv6 推理库：多平台 SIMD 优化、较低内存占用、高正确率。","",null,"C#",217,34,106,0,111,54.63,"Apache License 2.0",false,"main",[],"2026-09-20 04:01:32","# Sdcb.SimdPaddleOCR [![test](https:\u002F\u002Fgithub.com\u002Fsdcb\u002FSimdPaddleOCR\u002Factions\u002Fworkflows\u002Ftest.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fsdcb\u002FSimdPaddleOCR\u002Factions\u002Fworkflows\u002Ftest.yml) [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR) [![License: Apache-2.0](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-Apache--2.0-blue.svg)](LICENSE) [![QQ](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FQQ_Group-579060605-52B6EF?style=social&logo=tencent-qq&logoColor=000&logoWidth=20)](https:\u002F\u002Fqm.qq.com\u002Fq\u002FbPw5jAK4qk)\n\n**中文** | [English](README_EN.md)\n\n纯 C# PP-OCRv6 推理库：多平台 SIMD 优化、较低内存占用、高正确率。\n自带托管 ONNX 解释器，不依赖 Paddle Inference、ONNX Runtime 或 OpenCV 原生库。\n\n核心 API 只接收 BGR8 内存，不负责图片解码，因此不会强制引入 ImageSharp、SkiaSharp 或 OpenCvSharp。\n\n## 快速开始\n\n安装核心包和 tiny 模型（tiny 会传递引用 CLS 与 `ModelProvider`）：\n\n```powershell\ndotnet add package Sdcb.SimdPaddleOCR\ndotnet add package Sdcb.SimdPaddleOCR.Models.ChineseV6Tiny\ndotnet add package SixLabors.ImageSharp --version 3.1.11\n```\n\n模型从程序集嵌入资源直接加载，不会解压或写入临时文件。输入为 8-bit BGR，`stride = 0` 表示紧密排列（`width * 3`）。\n\n### ImageSharp 3（推荐）\n\n```csharp\nusing Sdcb.SimdPaddleOCR;\nusing Sdcb.SimdPaddleOCR.Models.ChineseV6Tiny;\nusing SixLabors.ImageSharp;\nusing SixLabors.ImageSharp.PixelFormats;\n\nusing PaddleOcrAll ocr = await PaddleOcrAll.LoadAsync(ChineseV6TinyModels.Default);\nusing Image\u003CBgr24> image = await Image.LoadAsync\u003CBgr24>(\"sample.jpg\");\nbyte[] bgr = new byte[image.Width * image.Height * 3];\nimage.CopyPixelDataTo(bgr);\nPaddleOcrResult result = ocr.Run(bgr, image.Width, image.Height);\nConsole.WriteLine(result.Text);\n```\n\n后续三个示例只演示如何解码到 BGR，加载与 `Run` 与上面相同。\n\n### SkiaSharp\n\n```csharp\nusing SkiaSharp;\n\nSKBitmap bitmap = SKBitmap.Decode(\"sample.jpg\")\n    ?? throw new InvalidDataException(\"无法读取图片\");\nint stride = bitmap.Width * 3;\nbyte[] bgr = new byte[stride * bitmap.Height];\nfor (int y = 0; y \u003C bitmap.Height; y++)\n{\n    for (int x = 0; x \u003C bitmap.Width; x++)\n    {\n        SKColor color = bitmap.GetPixel(x, y);\n        int offset = y * stride + x * 3;\n        bgr[offset] = color.Blue;\n        bgr[offset + 1] = color.Green;\n        bgr[offset + 2] = color.Red;\n    }\n}\n```\n\n### OpenCvSharp5\n\n```csharp\nusing System.Runtime.InteropServices;\nusing OpenCvSharp;\n\nusing Mat image = Cv2.ImRead(\"sample.jpg\", ImreadModes.Color);\nif (image.Empty()) throw new InvalidDataException(\"无法读取图片\");\nint rowBytes = image.Width * image.Channels();\nbyte[] bgr = new byte[rowBytes * image.Height];\nfor (int y = 0; y \u003C image.Height; y++)\n    Marshal.Copy(IntPtr.Add(image.Data, (int)(y * image.Step())), bgr, y * rowBytes, rowBytes);\n```\n\n### Bitmap\n\n```csharp\nusing System.Drawing;\nusing System.Drawing.Imaging;\nusing System.Runtime.InteropServices;\n\nusing Bitmap bitmap = new(\"sample.jpg\");\nint stride = bitmap.Width * 3;\nbyte[] bgr = new byte[stride * bitmap.Height];\nRectangle rectangle = new(0, 0, bitmap.Width, bitmap.Height);\nBitmapData data = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);\ntry\n{\n    for (int y = 0; y \u003C bitmap.Height; y++)\n        Marshal.Copy(new IntPtr(data.Scan0.ToInt64() + y * (long)data.Stride), bgr, y * stride, stride);\n}\nfinally\n{\n    bitmap.UnlockBits(data);\n}\n```\n\n## NuGet 包\n\n| NuGet 包 | 版本 | 说明 |\n| --- | --- | --- |\n| `Sdcb.SimdPaddleOCR` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR) | 纯托管推理核心（`net10.0;netstandard2.0`） |\n| `Sdcb.SimdPaddleOCR.ModelProvider` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.ModelProvider.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR.ModelProvider) | 模型契约（`IPaddleOcrModelProvider` \u002F `PaddleOcrModelBundle`），通常被传递引用 |\n| `Sdcb.SimdPaddleOCR.Models.ChineseV6Tiny` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Tiny.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Tiny) | PP-OCRv6 tiny DET+REC+字典；`ChineseV6TinyModels.Default` 含 CLS |\n| `Sdcb.SimdPaddleOCR.Models.ChineseV6Small` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Small.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Small) | PP-OCRv6 small；`ChineseV6SmallModels.Default` |\n| `Sdcb.SimdPaddleOCR.Models.ChineseV6Medium` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Medium.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR.Models.ChineseV6Medium) | PP-OCRv6 medium；`ChineseV6MediumModels.Default` |\n| `Sdcb.SimdPaddleOCR.Models.TextLineOrientation` | [![NuGet](https:\u002F\u002Fimg.shields.io\u002Fnuget\u002Fv\u002FSdcb.SimdPaddleOCR.Models.TextLineOrientation.svg)](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FSdcb.SimdPaddleOCR.Models.TextLineOrientation) | PP-LCNet 文本行方向 CLS，被三个中文模型包传递引用 |\n\n每个 `IPaddleOcrModelProvider` 提供 `Name`、`Kind`、`Format`、语言和版本元数据以及 `OpenRead()` \u002F `OpenReadAsync()`。完整 OCR 组合由 `PaddleOcrModelBundle` 表达（DET、REC、字典和可选 CLS）。当前语言代码为 `zh`。单个模型也可被其他推理实现消费，例如 `ChineseV6TinyModel.Detection.OpenReadAsync()`。`Model`、`PaddleOcrDetector`、`PaddleOcrClassifier`、`PaddleOcrRecognizer` 和 `PaddleOcrAll` 均提供 Stream 加载入口；解析完成后不会继续保留完整的 ONNX 原始字节。\n\n## 使用本地模型\n\n核心不下载模型。使用本地 DET、CLS、REC 和字典文件时：\n\n```csharp\nusing Sdcb.SimdPaddleOCR;\n\nusing PaddleOcrAll ocr = await PaddleOcrAll.LoadAsync(\n    detectionPath: \"models\u002Fdet.onnx\",\n    classificationPath: \"models\u002Fcls.onnx\",\n    recognitionPath: \"models\u002Frec.onnx\",\n    dictionaryPath: \"models\u002Fppocr_keys.txt\");\n```\n\n`PaddleOcrOptions` 里两套并行不要混用：`DetIntraOpThreads` 是检测图内的卷积线程\n（一份 session，默认最多 8）；`LineWorkerCount` 是一行一组的 CLS\u002FREC worker 路数\n（每路一个 session，上限，实际 `min(请求, ProcessorCount)`；`0` 为\n`min(ProcessorCount, 4)`）。检测阈值、边界长度、方向分类、\n动态识别宽度和 Session 缓存上限等也在同一组 options 里。\n\n## 示例\n\n四个示例共用 `examples\u002Fsample.jpg`，图片由示例负责解码并转换为 BGR：\n\n- `examples\u002FImageSharp.AspNetCore`：ASP.NET Core + ImageSharp 3，可上传体验与 `POST \u002Fapi\u002Focr` JSON API。\n- `examples\u002FSkiaSharp.Avalonia`：Avalonia 桌面示例，SkiaSharp 解码。\n- `examples\u002FOpenCvSharp5.Wpf`：WPF 示例，OpenCvSharp5 解码。\n- `examples\u002FSystemDrawing.WinForms`：.NET 10 Windows \u002F .NET Framework 4.8 双目标 WinForms 示例，使用 `Bitmap`\u002F`LockBits`；运行 `net48` 前请安装 .NET Framework 4.8 Developer Pack，项目平台选择 x64。\n\n```powershell\ndotnet run --project examples\u002FImageSharp.AspNetCore\ndotnet run --project examples\u002FOpenCvSharp5.Wpf -- path\u002Fto\u002Fimage.jpg\ndotnet run --project examples\u002FSkiaSharp.Avalonia -- path\u002Fto\u002Fimage.jpg\ndotnet run --project examples\u002FSystemDrawing.WinForms --framework net10.0-windows\n```\n\nWeb 示例打开站点即可上传；API 为 `POST \u002Fapi\u002Focr`（`multipart\u002Fform-data` 字段 `file`、`model`），文档在 `\u002Fscalar`。\n\n## 常见问题\n\n### 为什么调试时 OCR 识别特别慢？\n\n调试器可能会在模块加载时取消 JIT 优化，使 OCR 的计算密集型代码无法获得应有的运行时优化，从而导致识别明显变慢。\n\n请关闭该选项，然后重新启动调试会话：\n\n- Visual Studio：`工具 > 选项 > 调试 > 常规`，取消勾选`在模块加载时取消 JIT 优化`。\n- Rider：`构建、执行、部署 > 调试器 > JIT`，取消勾选`在加载模块时禁用 JIT 优化`。\n- VS Code：打开`设置 (JSON)`，添加 `\"csharp.debug.suppressJITOptimizations\": false`。\n\n## 支持范围\n\n| | 说明 |\n| --- | --- |\n| 目标框架 | 核心 `net10.0;netstandard2.0`；`ModelProvider` 与全部模型包为 `netstandard2.0` |\n| 推荐运行时 | .NET 10：完整 x86 SIMD 与 NativeAOT（`IsAotCompatible`） |\n| 兼容运行时 | `netstandard2.0` 可在 .NET Framework 4.8 等环境使用；编译时去掉 AVX \u002F AVX-512 \u002F VNNI 源，走 `System.Numerics.Vector` \u002F 标量 |\n| CI 架构 | Windows x64 \u002F x86 \u002F ARM64，Linux x64 \u002F ARM64，macOS x64 \u002F ARM64 |\n| SIMD | .NET 10 运行时探测 AVX → AVX2 → AVX-512 \u002F VNNI；无对应指令集或 ARM 时用 Vector\u002F标量 |\n| 输入 | 8-bit BGR 内存；无图片路径、文件或图片库 API |\n| 设备 | CPU only，无 GPU |\n| NativeAOT | 裁剪发布时请保留核心程序集和所用模型程序集 |\n\n## 许可证与第三方组件\n\n本仓库中由本项目编写的源代码和文档采用 [Apache License 2.0](LICENSE) 发布。\nApache-2.0 提供明确的专利授权条款，更适合公开发布的库和 NuGet 包。\n\n模型资源和第三方代码不因本项目许可证而被重新授权：\n\n- PP-OCRv6 DET\u002FREC、TextLineOrientation CLS 及字典来自 PaddleOCR 生态，来源资料标记为\n  Apache-2.0；发布模型包时请保留来源和许可证说明。\n- 示例依赖遵循各自上游许可证；特别是 ImageSharp 3.x 使用 Six Labors Split License，\n  不是普通 MIT 许可证。\n\n完整的第三方归属和分发说明见\n[`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md)。PaddleOCR、PP-OCR 及相关名称归其\n各自权利人所有，本项目不代表官方，也不构成官方背书。\n\n## 性能\n\nGitHub-hosted runner、PP-OCRv6 tiny、去掉首张 warmup 后的中位墙钟（2026-09，4 次 CI 合计）：\n\n| 平台 | CPU | ISA | 中位 ms\u002F图 | 工作集峰值 | 简评 |\n| --- | --- | --- | ---: | ---: | --- |\n| win-x64 | AMD EPYC 7763（4 vCPU） | AVX2 | **238** | ~790 MB | 默认路径；正确率跨 ISA 不变 |\n| win-x64 `netstandard2.0` | 同上 | AVX2（`Vector`） | 373 | ~785 MB | 约为 net10 AVX2 的 1.56× |\n| linux-arm64 | Neoverse N2 | AdvSimd | **273** | ~847 MB | replica 间几乎一条直线 |\n\n同机引擎对比（win-x64 \u002F EPYC 7763，tiny 4 worker；与上表不是同一批 VM，只看相对关系）：\n\n| 引擎 | 中位 ms\u002F图 | 工作集峰值 | 行精确 | CER |\n| --- | ---: | ---: | --- | ---: |\n| 本库 | **224** | **~790 MB** | **757\u002F1022** | **3.53%** |\n| [lw.PPOCR.C](https:\u002F\u002Fgithub.com\u002Flxw112190\u002Flw.PPOCR.C) | 281 | ~586 MB | 759\u002F1022 | 4.18% |\n| [OpenVINO.NET](https:\u002F\u002Fgithub.com\u002Fsdcb\u002FOpenVINO.NET) | 214 | ~2600 MB | 698\u002F1022 | 3.63% |\n\nlw.PPOCR.C 用的是 **2026 年 8 月底**的一份构建，不代表该项目最新版本。\n\n简评：墙钟接近 OpenVINO.NET、比这份 lw.PPOCR.C 快约 26%；工作集约 OpenVINO.NET 的 1\u002F3，比 C 高一截。正确率跨 Windows \u002F Linux \u002F macOS 与 scalar 都是 757\u002F1022、CER 3.53%；CER 好于该份 C，行精确高于 OpenVINO.NET。\n\n完整环境、ISA 阶梯和读数规则见 [`docs\u002Fperf.md`](docs\u002Fperf.md)。\n\n## 性能复现\n\n[GitHub Actions `test` 工作流](https:\u002F\u002Fgithub.com\u002Fsdcb\u002FSimdPaddleOCR\u002Factions\u002Fworkflows\u002Ftest.yml)\n会跑单元测试，并在 Windows \u002F Linux \u002F macOS 多架构上对 tiny \u002F small \u002F medium 做 bench\n（含关闭 AVX-512 \u002F AVX2 \u002F AVX \u002F 全部硬件加速，以及 `netstandard2.0` 库）。汇总报告写入 job summary 与 `perf-report` artifact。\n\n## 微信群\n\n![](https:\u002F\u002Fio.starworks.cc:88\u002Fcv-public\u002F2026\u002Focr-wxg-qr.png?0908)\n\n如果微信群二维码过期了，请加入 QQ 群 [C#\u002F.NET计算机视觉技术交流 579060605](https:\u002F\u002Fqm.qq.com\u002Fq\u002FbPw5jAK4qk)。\n","这是一个纯 C# 实现的 PP-OCRv6 文字识别推理库，专为高性能、低资源消耗场景设计。核心功能包括基于 SIMD 指令集的跨平台（Windows\u002FmacOS\u002FLinux\u002FARM64）加速推理、内置托管 ONNX 解释器（零原生依赖）、内存紧凑型 BGR8 原生输入接口，以及对中文 OCR 的高准确率支持。不依赖 Paddle Inference、ONNX Runtime 或 OpenCV 原生库，模型以嵌入资源方式加载，避免临时文件和解压开销。适用于 .NET 生态下的桌面应用、边缘设备、服务端 OCR 微服务及对部署简洁性与内存敏感度要求较高的自动化文档处理场景。",2,"2026-09-08 02:30:11","CREATED_QUERY"]