PaddleOCR总共有三个模型, 我们现在已经学会了第一个文本检测模型的推理, 现在给小伙伴们汇报第二和第三个。
- det.onnx Detection 文本检测模型 ✔ 。
- cls.onnx Classification 文本方向分类模型 。
- rec.onnx Recognition 文本识别模型
先看结论


cls.onnx

模型结构非常简单, 输入就不说了, 输出为 n * 2 的二维数组, n表示批次, 举个例子 。
[
[0.9,0.1]
]
- 0.9 文本是横向的概率
- 0.1 文本是纵向的概率
推理代码
public bool Classification(Image<Rgb24> image)
{
var input = ImageToTensor(image);
List<NamedOnnxValue> inputs = [NamedOnnxValue.CreateFromTensor(INPUT_NAME, input)];
using IDisposableReadOnlyCollection<DisposableNamedOnnxValue> results = _clsSession.Run(inputs);
IEnumerable<float> output = results[0].AsEnumerable<float>();
Console.WriteLine(output.First() > output.Last() ? "vertical" : "horizontally");
return output.First() > output.Last();
}
rec.onnx

模型结构也非常简单, 输入就不说了,结构和上一篇文章一样, 输出为 n * s * 6625 的三维数组, n表示批次,s 表示序列, 6625表示文本总数, 举个例子 。
[
[
[ 0.001, 0.0002, 0.003 ...]
]
]
- 字典下载
- 0.001 文本是 字典[1] 的概率
- 0.002 文本是 字典[2] 的概率
- 0.003 文本是 字典[3] 的概率
推理代码
private static readonly string[] Dict = File.ReadAllLines("weights/ppocr_keys_v1.txt");
public string Recognition(Image<Rgb24> image)
{
using var modelWidth = 48 / image.Height * image.Width;
var modelImage = image.Clone(x => x.Resize(new ResizeOptions
{
Mode = ResizeMode.Stretch,
Size = new Size(modelWidth, 48)
}));
var input = ImageToTensor(modelImage);
List<NamedOnnxValue> inputs = [NamedOnnxValue.CreateFromTensor(INPUT_NAME, input)];
using IDisposableReadOnlyCollection<DisposableNamedOnnxValue> results = _recSession.Run(inputs);
Tensor<float> output = results[0].AsTensor<float>();
var sb = new StringBuilder();
int sequenceLength = output.Dimensions[1];
int numClasses = output.Dimensions[2]; // 6625
for (int t = 0; t < sequenceLength; t++)
{
int maxIndex = Enumerable.Range(0, numClasses)
.OrderByDescending(i => output[0, t, i])
.First();
if (maxIndex == 0) // 空白字符
{
continue;
}
sb.Append(Dict[maxIndex - 1]);
}
return sb.ToString();
}