|
|
1 tháng trước cách đây | |
|---|---|---|
| .. | ||
| Properties | 1 tháng trước cách đây | |
| App.config | 1 tháng trước cách đây | |
| CONFIG.md | 1 tháng trước cách đây | |
| DELIVERY_CHECKLIST.md | 1 tháng trước cách đây | |
| INDEX.md | 1 tháng trước cách đây | |
| OCREngine.cs | 1 tháng trước cách đây | |
| OCRTest.csproj | 1 tháng trước cách đây | |
| OCRTrainingHelper.cs | 1 tháng trước cách đây | |
| Program.cs | 1 tháng trước cách đây | |
| QUICKSTART.md | 1 tháng trước cách đây | |
| README.md | 1 tháng trước cách đây | |
| SUMMARY.md | 1 tháng trước cách đây | |
| TRAINING_CHEATSHEET.md | 1 tháng trước cách đây | |
| packages.config | 1 tháng trước cách đây | |
| 使用说明.txt | 1 tháng trước cách đây | |
在项目中安装以下 NuGet 包:
Install-Package Tesseract -Version 5.2.0
Install-Package OpenCvSharp4 -Version 4.8.0.20230708
Install-Package OpenCvSharp4.runtime.win -Version 4.8.0.20230708
从 Tesseract 官方仓库 下载需要的语言文件:
eng.traineddatachi_sim.traineddatachi_tra.traineddata将下载的文件放入项目的 tessdata 文件夹中。
using OCRTest;
// 方式1:使用默认单例(推荐)
var ocrEngine = OCREngine.Instance;
var result = ocrEngine.RecognizeText("image.png");
Console.WriteLine($"识别结果:{result.Text}");
Console.WriteLine($"置信度:{result.Confidence}%");
Console.WriteLine($"耗时:{result.ElapsedMilliseconds}ms");
// 方式2:中英文混合识别
var ocrEngineChi = OCREngine.GetInstance("chi_sim+eng");
var result2 = ocrEngineChi.RecognizeText("image.png");
OCRTest/
├── OCREngine.cs # 核心引擎类
├── Program.cs # 测试程序
├── tessdata/ # 语言数据文件夹
│ ├── eng.traineddata # 英文模型
│ └── chi_sim.traineddata # 简体中文模型
└── packages.config # NuGet 包配置
<!-- packages.config -->
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Tesseract" version="5.2.0" targetFramework="net48" />
<package id="OpenCvSharp4" version="4.8.0.20230708" targetFramework="net48" />
<package id="OpenCvSharp4.runtime.win" version="4.8.0.20230708" targetFramework="net48" />
</packages>
// 创建引擎实例
var ocrEngine = OCREngine.Instance;
// 识别图片文件
OCRResult result = ocrEngine.RecognizeText("test.png");
if (result.Success)
{
Console.WriteLine($"文本:{result.Text}");
Console.WriteLine($"置信度:{result.Confidence:F2}%");
Console.WriteLine($"耗时:{result.ElapsedMilliseconds}ms");
}
else
{
Console.WriteLine($"错误:{result.Error}");
}
var config = new OCRConfig
{
Language = "eng", // 识别语言
EngineMode = EngineMode.LstmOnly, // 仅使用LSTM(更快)
Whitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", // 字符白名单
EnablePreprocessing = true, // 启用预处理
PageSegMode = PageSegMode.Auto // 自动页面分割
};
var ocrEngine = OCREngine.GetInstance(config);
var result = ocrEngine.RecognizeText("test.png");
using (var bitmap = new Bitmap("test.png"))
{
var result = ocrEngine.RecognizeFromBitmap(bitmap);
Console.WriteLine(result.Text);
}
string[] imagePaths = {
"image1.png",
"image2.png",
"image3.png"
};
var results = ocrEngine.RecognizeBatch(imagePaths);
for (int i = 0; i < results.Count; i++)
{
Console.WriteLine($"图片{i+1}: {results[i].Text}");
}
// 场景:识别产品序列号(仅数字和字母)
var config = new OCRConfig
{
Language = "eng",
EngineMode = EngineMode.LstmOnly,
Whitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-",
EnablePreprocessing = true
};
var ocrEngine = OCREngine.GetInstance(config);
// 连续识别
while (true)
{
var result = ocrEngine.RecognizeText("product_sn.png");
if (result.Success && result.Confidence > 85)
{
Console.WriteLine($"序列号:{result.Text}");
break;
}
Thread.Sleep(100);
}
收集样本图片
标注文本
.txt 文件文件名相同,扩展名不同
sample001.png
sample001.txt (内容: "ABC123")
sample002.png
sample002.txt (内容: "DEF456")
下载工具
生成 TIFF 训练文件
myfont.exp0.tif标注校正
myfont.exp0.box创建批处理文件 train.bat:
@echo off
set LANG=myfont
set TESSDATA_PREFIX=C:\path\to\tessdata
echo 步骤1: 生成训练文件...
tesseract %LANG%.exp0.tif %LANG%.exp0 batch.nochop makebox
echo 步骤2: 生成字符集...
tesseract %LANG%.exp0.tif %LANG%.exp0 nobatch box.train
echo 步骤3: 计算字符集...
unicharset_extractor %LANG%.exp0.box
echo 步骤4: 生成形状文件...
shapeclustering -F unicharset -O unicharset %LANG%.exp0.tr
echo 步骤5: 聚集字符...
mftraining -F unicharset -U unicharset -O myfont.unicharset %LANG%.exp0.tr
echo 步骤6: 合并字符...
cntraining %LANG%.exp0.tr
echo 步骤7: 重命名文件...
rename normproto myfont.normproto
rename inttemp myfont.inttemp
rename pffmtable myfont.pffmtable
rename shapetable myfont.shapetable
echo 步骤8: 组合训练数据...
combine_tessdata myfont.
echo 完成!生成 myfont.traineddata
pause
// 将 myfont.traineddata 放入 tessdata 文件夹
var config = new OCRConfig
{
Language = "myfont", // 使用自定义模型
EngineMode = EngineMode.LstmOnly,
EnablePreprocessing = true
};
var ocrEngine = OCREngine.GetInstance(config);
var result = ocrEngine.RecognizeText("test.png");
// 最快:仅使用 LSTM
EngineMode.LstmOnly
// 平衡:LSTM + 传统引擎
EngineMode.Default
// 最准确:仅传统引擎(慢)
EngineMode.TesseractOnly
var config = new OCRConfig
{
EnablePreprocessing = true, // 启用预处理
// 预处理会自动进行:
// - 灰度化
// - 二值化(Otsu算法)
// - 降噪
};
// 限制识别字符范围,大幅提升速度和准确率
config.Whitelist = "0123456789"; // 仅数字
config.Whitelist = "ABCDEF0123456789"; // 十六进制
// 根据版面选择合适的模式
PageSegMode.SingleLine // 单行文本
PageSegMode.SingleWord // 单个单词
PageSegMode.SingleChar // 单个字符
PageSegMode.Auto // 自动检测(默认)
// ✅ 推荐:复用引擎实例
var engine = OCREngine.Instance;
for (int i = 0; i < 1000; i++)
{
var result = engine.RecognizeText($"image{i}.png");
}
// ❌ 不推荐:频繁创建销毁
for (int i = 0; i < 1000; i++)
{
using (var engine = new TesseractEngine(...))
{
// ...
}
}
// 批量并行识别
var imagePaths = Directory.GetFiles("images", "*.png");
Parallel.ForEach(imagePaths, path =>
{
var result = OCREngine.Instance.RecognizeText(path);
Console.WriteLine($"{Path.GetFileName(path)}: {result.Text}");
});
| 优化项 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 引擎模式 | Default | LstmOnly | 30-50% |
| 字符白名单 | 无 | 有限字符集 | 40-60% |
| 图像预处理 | 无 | 启用 | 10-20% 准确率 |
| 单例复用 | 每次创建 | 复用实例 | 80-90% |
| 并行处理 | 串行 | Parallel | N倍(CPU核心数) |
解决方案:
调整 PSM 模式
var config = new OCRConfig
{
EnablePreprocessing = true,
Whitelist = "你的字符集",
PageSegMode = PageSegMode.SingleLine // 根据实际调整
};
步骤:
chi_sim.traineddata(简体)或 chi_tra.traineddata(繁体)tessdata 文件夹使用:
var engine = OCREngine.GetInstance("chi_sim"); // 简体中文
var engine = OCREngine.GetInstance("chi_sim+eng"); // 中英混合
解决方案:
// 定期清理不用的实例
OCREngine.Cleanup();
// 或使用 using 语句
using (var engine = OCREngine.GetInstance("eng"))
{
// 使用后自动释放
}
优化方案:
EngineMode.LstmOnly完整语言列表见 Tesseract 语言包
常用语言代码:
eng - 英语chi_sim - 简体中文chi_tra - 繁体中文jpn - 日语kor - 韩语deu - 德语fra - 法语方案:
// 使用 OpenCvSharp 进行矫正
using (var src = Cv2.ImRead("image.png"))
{
// 检测倾斜角度
// 旋转矫正
// 然后传入 OCR 引擎
var result = ocrEngine.RecognizeFromBitmap(src.ToBitmap());
}
本项目使用的 Tesseract OCR 遵循 Apache 2.0 许可证。
祝使用愉快! 🎉