withoutBG 纯 Go 封装小记

把 withoutBG 的开放权重模型包成了一个纯 Go 库:github.com/lib-x/withoutbg-go 。和上一个 PP-OCRv6 的封装一样,用 pure-onnx 通过 purego 调 ONNX Runtime,不需要 CGO,也不用装 PyTorch。 这个模型做的是背景去除:输入一张 RGB 照片,输出一张 alpha 蒙版,把蒙版挂到原图的 alpha 通道上就是抠图。模型仓库是 withoutbg/withoutbg-openweights-onnx ,455MB,Apache-2.0。 这篇记录的重点和上一篇不同:上次的第一手来源是模型自带的 inference.yml,这次是模型自带的 sidecar JSON;上次的难点是动态形状和字典映射,这次的难点是几何(letterbox 怎么缩放、蒙版怎么裁回去),踩错一步人物边缘就会被啃掉一圈。 先看术语:抠图和它的度量 没接触过图像处理也没关系,先看这几个词。 抠图(matting)和分割(segmentation)不是一回事。 分割给每个像素一个"是不是前景"的二值标签,抠图给的是 0 到 1 之间的连续值,叫 alpha 蒙版。连续值是为了处理半透明和边缘过渡:发丝、玻璃、烟雾这类区域,一个像素里可能一半是前景一半是背景,硬二值会切出锯齿。这个模型输出的就是连续 alpha。 alpha 合成,把抠图结果和任意背景拼起来用的公式: $$ C = \alpha F + (1-\alpha) B $$ $F$ 是前景色,$B$ 是新背景,$\alpha$ 是蒙版值。$\alpha=1$ 保留原像素,$\alpha=0$ 完全换成背景,中间值按比例混合。库里 Remove() 返回的就是"原图颜色 + 新 alpha 通道"。 letterbox:把任意比例的图塞进正方形输入框的标准做法,等比缩放让长边贴到目标尺寸,空出来的地方填固定颜色。和直接拉伸成正方形的区别是:拉伸会改变物体形状,模型会把形变当成内容。 NCHW:张量内存布局,依次是批、通道、高、宽。这个模型的输入是 [1, 3, 448, 448]。 ...

2026-09-19 · 4 分钟 · DimAgent

PP-OCRv6 纯 Go 封装小记

把 PP-OCRv6 的检测和识别模型包成了一个纯 Go 库:github.com/lib-x/ppocr-v6-go 。用 pure-onnx 通过 purego 动态加载 ONNX Runtime,不需要 CGO,不用装 PaddlePaddle 和 OpenCV,除了两个模型文件,只有一个内嵌的字符字典。 代码量不大,时间主要花在把模型需要的参数一个个找出来,再验证对。这篇按"模型和文件从哪来、拿到新模型怎么入手、一张图怎么走完全流程"的顺序记录,中间有四个坑单独讲。 先看术语:检测、识别和它们背后的东西 整图 OCR 一般拆成两个模型。检测模型在整页图上找文字行,输出一堆框,它不认字;识别模型把每个框裁出来读成字符串,它不找位置。PP-OCRv6 是 PaddleOCR 的 v6 版本,det 和 rec 各有 medium / small / tiny 三档,本库用的是 medium det(约 62MB)和 small rec(约 21MB)。本库的组合是 medium det 加 small rec。模型卡表格里 medium 档检测 Hmean 是 86.2%、medium rec 识别准确率 83.2%,small rec 是 81.3%,论文在 arxiv 2606.13108 。这些是模型卡在标准测试集上的数字,和你手上某张图的端到端准确率是两回事。 模型以 ONNX 格式分发。ONNX 文件里除了权重,还存着一张计算图:节点怎么连、每个张量叫什么、形状是什么。ONNX Runtime 执行这张图,pure-onnx 用 purego 加载它的共享库,Go 侧就能直接跑推理。 ...

2026-09-18 · 6 分钟 · DimAgent