关于 matlab-ocr
这是一个使用 Computer Vision Toolbox 的 OCR 和 Image Processing Toolbox 预处理来提取图像文字的 MATLAB 技能。它指导用户完成图像诊断、预处理、文本区域检测、识别和验证,适用于文档、标牌和显示屏等。
主要功能
- 01OCR 前诊断图像状况
- 02预处理对比度、倾斜和极性
- 03检测场景图像中的文本区域
- 04使用 MATLAB ocr 识别文字
- 05验证识别结果并保存流程文件
适用场景
- 01提取扫描文档中的文字
- 02读取标牌、标签和仪表显示
- 03识别多语言图像文字
- 04批量处理图像数据集中的文字
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-ocr安装后在 Claude Code 中输入/matlab-ocr确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreference/batch-pipeline.mddetection-methods.mdfunction-reference.mdlimitations.mdpreprocessing-guide.mdsupported-languages.mdtraining-guide.md详细介绍
使用 OCR 识别图像中的文本
使用 Computer Vision Toolbox 的 ocr 函数,并借助 Image Processing Toolbox 进行预处理,从图像中提取文本。本技能将介绍完整流程:诊断、预处理、检测、识别和验证。
适用场景
- 读取任意图像中的文本(文档、标志、仪表、显示屏、标签)
- 从扫描文档或照片中提取文本
- 读取七段数码管显示屏或特殊字体
- 识别多语言文本
- 自动从图像数据集中提取文本
- 作为其他 CV 工作流中的辅助步骤——读取场景中的文本(标签、时间戳、序列号),为后续图像分析提供更多上下文
不适用场景
- 纯手写识别——无论如何预处理,草书或连笔字都会产生乱码
- 艺术字、WordArt、刷字书法——OCR 引擎无法解析风格化字形
- CAPTCHA——专门用于干扰 OCR;即使效果最好,准确率也低于 50%
- 完整的文档布局分析和表格提取(请使用自定义分割)
- 实时视频 OCR(请改用流式处理方法)
- 图像中完全没有文本
关键规则
以下规则不可妥协——违反这些规则会导致错误结果:
-
始终先诊断,再执行。此规则不可覆盖——用户不能覆盖,“直接运行”也不能,“跳过规划”也不能。 在进行任何
mcp__matlab__*调用之前,你必须先输出:- 2 行图像特征描述(你看到了什么,存在哪些挑战)
- 一个
## OCR Plan标题,并说明你的策略
如果用户说“跳过诊断”或“直接运行 ocr()”,请回复:“我会尽量简短——但我需要快速查看一下,避免在错误的方法上浪费时间。” 然后输出 2 行图像特征描述和计划标题。只有这样才能调用 MCP 工具。跳过此步骤没有任何正当理由。未先输出计划就调用
ocr()的 Agent 违反了此技能的工作流。 -
最多使用 2 种预处理流程。 如果按规定的方法尝试后都无效,请在置信度检查点询问用户。未经用户输入,不要尝试第三种方法。
-
传递边界框给
ocr()时,始终设置LayoutAnalysis。 不要写ocr(I, bbox),却不设置此参数。单词框使用"word",多行文本使用"block"。 -
区分“纹理上的文字”和“由纹理构成的文字”。 覆盖在纹理背景上的文字(箱子上的标签、砖墙上的标牌)→ 按规定使用
imsegsam。由表面本身形成的文字(压印、浮雕、金属上的雕刻)→ 使用局部对比度相减。SAM 分割的是物体,而不是表面特征——它无法分离压印或雕刻。推荐方法时(即使不运行代码),对于“纹理上的文字”也始终推荐imsegsam,并注明其支持包要求。 -
detectTextCRAFT是场景文字的默认选择。 除非有具体原因不使用它(不使用深度学习、已知固定布局),否则请使用它。 -
先检查极性。 OCR 需要浅色背景上的深色文字。如果极性相反,先运行
imcomplement。 -
写入文件前,绝不要向用户展示 OCR 结果。 在
ocr_pipeline_<descriptor>.m和decision_log.txt写入磁盘之前,不要以任何形式呈现提取出的文字——无论是项目符号列表、引用块、行内文本、对话摘要,还是## MATLAB OCR Pipeline结果块。文件才是交付物,不是聊天消息。先写入文件,再报告结果。 -
使用附加功能前,先检查其可用性。 调用
detectTextCRAFT、imsegsam或非英语ocr模型之前,必须通过 MCP 运行exist('<functionName>','file'),确认该功能已安装。始终在decision_log.txt中记录检查结果:- 已安装:
"Add-on check: <function> — INSTALLED" - 缺失:停止,告知用户需要安装哪个支持包(参见下表),并等待用户确认后再重试。不要默默回退到其他方法,也不要跳过此步骤。
- 仅解释模式(用户说“不要运行代码”):将附加功能推荐为首选方法,并注明所需支持包。无法在不执行代码的情况下运行
exist()检查,因此请明确说明依赖项。
函数 支持包名称 detectTextCRAFT"Text Detection Using Deep Learning" imsegsam"Image Processing Toolbox Automated Visual Inspection Library" 非英语 ocr模型(例如"japanese")"OCR Language Data" 缺少支持包时的模板: “此步骤需要
<function>函数,该函数需要 支持包。请通过 MATLAB Add-On Explorer(Home → Add-Ons → Get Add-Ons)安装该支持包,并在准备就绪后告知我。” - 已安装:
反模式——切勿这样做
- 陷入反复试错: 尝试 5 次以上临时预处理实验,希望其中某种方法能奏效。如果视觉分类结果是“冲压金属”,就使用冲压金属流程。就是这样。
- 跳过计划:“我先快速试一种方法吧。”不行。诊断 → 计划 → 执行。
- 开放式研究: 路径已经指定——根据诊断选择一种,执行并评估。这不是探索性研究。
- 未保存文件就展示结果: 在
## MATLAB OCR Pipeline结果块之前,以项目符号列表、对话摘要或任何其他形式展示 OCR 文本。只有将文件写入磁盘后,才能显示该结果块。如果你正要向用户展示 OCR 识别出的内容,请立即停下,先写入文件。
工作流
进度报告 + 输出模板
视觉诊断后立即呈现 ## OCR Plan(关键规则 #1)。然后执行流程。文件保存后,呈现 ## MATLAB OCR Pipeline 结果块(关键规则 #7)。
OCR 计划(运行任何 MATLAB 代码之前输出)
## OCR Plan
**Image:** 800x600, stamped metal, ~22° skew, text ~40px
**Difficulty:** Complex (textured surface + significant rotation)
**Strategy:** deskew → local contrast subtraction → CRAFT detection → ocr()
对于简单图像:
## OCR Plan
**Image:** 1200x800, clean scanned document, no skew
**Difficulty:** Simple
**Strategy:** binarize → ocr() directly
结果块(仅在文件写入磁盘后输出)
## MATLAB OCR Pipeline: SUCCESS
**Pipeline:** deskew (22.6°) → local contrast subtraction → CRAFT detection → ocr() per region
| Read by Claude (ground truth) | MATLAB OCR Output |
|-------------------------------|-------------------|
| 07 A11 | 07 A11 |
| XTPR 27338-2 | XTPR 27338-2 |
**Metrics** (via `evaluateOCR`): CER 0.00 | WER 0.00
**Files written:**
- `ocr_pipeline_stamped_metal.m` — Re-runnable MATLAB script reproducing the full pipeline
- `decision_log.txt` — Diagnosis, routing decisions, and confidence scores
对于失败情况:
## MATLAB OCR Pipeline: FAILED
**Pipeline attempted:** binarize → ocr()
**Reason:** Cursive handwriting — OCR engine cannot parse connected script
**Evidence:** CER 0.91 | WER 1.00
| Read by Claude (ground truth) | MATLAB OCR Output |
|-------------------------------|------------------------|
| Meeting at 3pm Tuesday | Mcciivj a 3pn Tuarlay |
**Recommendation:** Manual transcription or handwriting-specific ML model
**No files written.**
GATE(关键规则 #7)
文件确认已写入磁盘之前,切勿呈现 ## MATLAB OCR Pipeline 结果块。不得使用项目符号列表、引文或摘要——在文件写入之前,不得透露任何已提取的文本。
步骤 1:诊断
务必从这里开始。 查看图像,目视读取文本(以此作为事实依据),对图像进行分类,并呈现 ## OCR Plan——所有这些都必须在运行任何 MATLAB 代码之前完成。
你的视觉分类决定预处理路线:
| 视觉分类 | 预处理路线 |
|---|---|
| 文档干净,倾斜极小 | 二值化 → 直接进行 OCR(跳至步骤 4) |
| 对比度低/光照不均 | imtophat 或 adapthisteq → 二值化 |
| 印章/压印/雕刻(文字就是表面纹理) | 局部对比度减法(步骤 2) |
| 文字叠加在纹理背景上(板条箱上的标签、墙上的标牌) | imsegsam SAM 分割(步骤 3) |
| 倾斜明显(>10°) | 先校正倾斜,再预处理 |
| 文字过小(<50px) | 先使用 imresize 放大 4-8 倍 |
分类后,通过 MATLAB 确认:检查二值化效果、测量倾斜角度并进行快速实验。
% TEMPLATE — not executable
I = imread("yourImage.png");
Igray = im2gray(I);
BW = imbinarize(Igray);
imshowpair(Igray, BW, "montage")
title("Original vs. What OCR Sees")
倾斜角度测量必须具有确定性。 质心拟合方法对纳入计算的连通块很敏感。为确保结果可复现:
- 使用所有符合文字尺寸的连通块(按面积范围筛选,例如 50-5000px),不要只选“面积最大的前 N 个”
- 或者,在边缘上使用霍夫变换(
hough+houghpeaks+houghlines),稳健地估算角度 .m流水线脚本在重新运行时必须复现完全相同的倾斜角度——否则,校正倾斜的方法不可靠,必须更换
二值化诊断:
- 文字清晰可读 → 跳至步骤 4
- 文字模糊/粘连/有噪点 → 预处理(步骤 2)
- 黑底白字 →
imcomplement - 文字过小(<50px)→ 使用
imresize放大 4-8 倍 - 图像旋转/倾斜 → 先校正倾斜,再进行其他预处理
- 字符太粗/有渗墨现象 →
imerode(BW, strel("disk",1)) - 字符太细/有断裂 →
imdilate(BW, strel("disk",1)) - 边框/扫描边缘过暗 → 使用
imclearborder(BW)或裁剪 - 金属纹理过于显眼 → 局部对比度减法
升级处理规则: 如果尝试 2 次或更多预处理后,结果仍然乱码或置信度低于 80%,请找出根本原因:
- 图像过小(不足 50px)? → 使用
imresize放大 4-8 倍即可解决 - 文字叠加在纹理背景上? → 使用
imsegsam(SAM) - 文字由表面纹理构成(印章/压印)? → 局部对比度减法
- 字体无法识别(手写、书法)? → OCR 引擎的局限;考虑使用
trainOCR
置信度警告(必须遵守): 置信度高并不保证结果正确。OCR 即使对完全错误的文本,也可能报告 >0.9 的置信度,尤其是遇到小图像或不常见图像时。务必根据预期内容验证结果。
步骤 2:预处理图像
根据诊断结果应用预处理。完整代码示例请参阅 reference/preprocessing-guide.md。
流水线路由:
| 分类 | 方法 | 关键函数 |
|---|---|---|
| 光照不均 | 顶帽光照校正 | imtophat + imreconstruct |
| 印章/压印/雕刻 | 局部对比度减法 | imgaussfilt(Igray,30) - Igray |
| 倾斜 >10° | 先通过质心拟合校正倾斜 | imrotate |
| 文字过小 <50px | 放大 4-8 倍 | imresize |
| 极性反转 | 取反 | imcomplement |
关键规则:
- 先校正倾斜,再进行其他预处理——旋转会使形态学操作失效
- OCR 需要浅色背景上的深色文字——如果极性反转,请使用
imcomplement - 对干净的小图像,先尝试对放大后的灰度图进行 OCR,再进行二值化——抗锯齿有助于识别
- 如果文字紧贴边缘,请使用
padarray(BW, [10 10], 1)添加10px 白色边框
步骤 3:检测文本区域(关键)
对于自然场景(街道标牌、产品标签、仪表盘),在调用 ocr 前隔离文本区域至关重要。 这类图像的背景复杂,容易干扰 OCR 引擎。对于背景均匀的扫描文档,这一步不那么重要——ocr 内置的页面布局分析能够自动处理格式良好的文档。
默认选择:detectTextCRAFT。 除非有特定理由使用其他方法(没有深度学习支持、布局固定且已知等),否则始终优先使用 CRAFT 检测场景文本。它在复杂背景上的表现优于 MSER。
使用 CRAFT 或 SAM 前必须执行: 通过 MCP 运行 exist('detectTextCRAFT','file') 或 exist('imsegsam','file')。如果结果为 0,请停止并要求用户安装所需的支持包(关键规则 #8)。未经确认,请勿继续。
根据图像类型选择检测方法:
| 图像类型 | 方法 | 使用时机 |
|---|---|---|
| 自然场景(标牌、产品) | detectTextCRAFT | 复杂背景下的首选方法 |
| 文本稀疏的文档 | detectMSERFeatures | 经典方法,无需深度学习 |
| 位置固定且已知 | 手动 ROI [x y w h] | 图像布局一致(例如,仪表盘始终位于同一位置) |
| 均匀背景上的文本 | 对二值图像使用 regionprops | 按面积/宽高比查找连通区域 |
| 颜色鲜明的文本 | 颜色分割 | 通过颜色通道阈值分割文本 |
| 纹理背景上的文本 | imsegsam(SAM) | 箱子上的标签、砖墙上的标牌(文本是独立对象) |
| 简单、干净的文档 | 无(直接使用 ocr) | 背景均匀的干净扫描件 |
SAM 警告: 请勿对盖印、压印、雕刻或蚀刻的文本使用 SAM——这些是表面特征,而不是对象。请改用局部对比度相减(步骤 2)。SAM 大约需要 60-120 秒,并且需要完整分辨率(切勿缩小图像)。
请参阅 reference/detection-methods.md,查看各方法(CRAFT、MSER、SAM、手动 ROI、连通区域、颜色分割)的代码示例。
步骤 4:识别文本
规则:将边界框传递给 ocr() 时,始终设置 LayoutAnalysis。 不要在未设置该参数的情况下调用 ocr(I, bbox)——默认值 "auto" 在小区域上会失败。单词框使用 "word",多行区域使用 "block"。
常见模式:ocr(I)、ocr(I, bbox, LayoutAnalysis="word")、ocr(BW, CharacterSet="0123456789")、ocr(I, roi, Model="seven-segment", LayoutAnalysis="word")。完整示例请参阅 reference/function-reference.md。
如果检测成功但识别结果杂乱无章: 问题出在预处理或倾斜,而非检测。请返回步骤 2:
- 倾斜角度 >10° 时,即使是干净的二值图像也会完全识别失败
- 如果图像有纹理,请尝试局部对比度相减
- 尝试对预处理后的灰度图像而非二值图像进行 OCR——抗锯齿有助于识别
步骤 5:验证结果
筛选 results.WordConfidences > 0.7 的结果。检查 results.CharacterConfidences 中可疑的字符。验证代码模式请参阅 reference/function-reference.md。
强制操作:使用真实文本运行 evaluateOCR。
必须使用 evaluateOCR 计算 OCR 指标。真实文本可以是:
- 你(Claude)从图像中目视读取的文本——默认使用此项
- 用户提供的文本——如果用户提供预期文本或纠正了你的读取结果,则使用此项
识别后通过 MCP 运行:
% evaluateOCR signature:
% metrics = evaluateOCR(ocrTextObj, groundTruthCellArray)
% - ocrTextObj: the ocrText object returned directly by ocr()
% - groundTruthCellArray: cell array of strings, one per expected text region
metrics = evaluateOCR(results, {"07 A11"; "XTPR 27338-2"});
fprintf("Character Error Rate (CER): %.2f\n", metrics.CharacterErrorRate);
fprintf("Word Error Rate (WER): %.2f\n", metrics.WordErrorRate);
始终通过 MCP 运行 evaluateOCR,并报告实际的 CER 和 WER 值。
强制操作:置信度检查点——何时询问用户:
如果满足以下任意一项,请向用户展示识别结果并请其确认或更正:
- 平均词置信度 < 0.6
- CER > 0.10 或 WER > 0.20
- 尝试了 2 种或更多预处理方法,结果仍然看起来不正确
- 识别出的文本在语义上不通,而且你无法从图像中自行读出内容
- OCR 返回的词数少于你目视统计的图像中的词数
清楚地询问:“我对这个结果没有把握。OCR 返回了 [text](CER:0.12,WER:0.20)。你能告诉我文本实际写的是什么吗?我会用它来调整处理流程。”
如果用户提供了真实文本,请使用更正后的真实文本重新运行 evaluateOCR,并调整预处理以尽量降低 CER/WER。
验证后,立即继续步骤 6——在文件写入磁盘之前,不要展示结果。
步骤 6:保存处理流程 + 日志
将处理流程保存为 .m 脚本,使其能够对不同图像重复运行。切勿硬编码交互式计算出的值——要包含所有检测代码(倾斜角测量、阈值选择、ROI 检测)。
命名: ocr_pipeline_<descriptor>.m(例如:ocr_pipeline_stamped_metal.m)
强制要求:
- 添加注释,解释每项决策的原因(为什么采用这种方法,而不只是说明做了什么)
- 始终显示诊断图(用于边界框的
imshowpair、insertShape,以及用于框和文本的insertObjectAnnotation) - 对于纹理复杂的图像,使用
detectTextCRAFT+ 按区域调用ocr(),并设置CharacterSet和LayoutAnalysis="word"(不要使用会导致置信度较低的整幅图像LayoutAnalysis="block") - 始终包含文件创建时间戳,并添加注释:“Created using matlab-ocr Skill”。
还要生成
decision_log.txt——每个决策点占一行,格式为:[step] TYPE: description。类型包括:VISUAL、EXPERIMENT、DECISION、RESULT、GAP。示例:
[1] VISUAL: Stamped metal, ~20° skew, embossed characters
[2] DECISION: Local contrast subtraction (stamped text confirmed)
[3] EXPERIMENT: Centroid fitting → skew angle = 22.6°
[4] RESULT: "07 AN / XTPR 27338-2" — confidence 0.74 mean
[5] GAP: "A11" misread as "AN" — thin stamps merge at this resolution
如果该技能未能完全奏效,用户会将此文件发回。
快速参考
**LayoutAnalysis 规则:**传递 ROI 框时,始终设置 LayoutAnalysis("word"、"block" 或 "none")。默认值 "auto" 在小区域上会失败。
关键函数:ocr、detectTextCRAFT、imsegsam、imbinarize、imtophat、imcomplement、imresize、bwareaopen、imrotate。请参阅 reference/function-reference.md 和 reference/batch-pipeline.md。
自定义模型训练
**强制要求:推荐训练之前,先列出准入检查清单。**只有以下条件全部满足时才进行训练:(1) 预处理和参数调优仍然失败;(2) 内置模型中没有所需字体/字符集;(3) 你拥有标注好的真实文本;(4) 使用场景涉及大量或重复处理。请先尝试:Model="seven-segment"、Model="french"、CharacterSet、LayoutAnalysis。
编程 API(始终使用这些 API,不要使用 ocrTrainer 应用):trainOCR、ocrTrainingOptions、ocrTrainingData。完整工作流程请参阅 reference/training-guide.md。
多语言支持
使用非英语模型前必须执行: 通过 MCP 运行 exist('ocrLanguageData','dir')。如果结果为 0,请停止并要求用户安装“OCR Language Data”支持包(关键规则 #8)。未获得确认前请勿继续。
使用 Model="japanese"(量化模型请使用 "french-fast")。需要 OCR Language Data 支持包。请参阅 reference/supported-languages.md。
故障排除
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 结果为空 | 深色背景上的浅色文本 | imcomplement(imbinarize(Igray)) |
| 字符乱码 | 未进行预处理 | 二值化、裁剪至 ROI,并使用 CharacterSet |
| 将“O”识别为“0”或将“l”识别为“1” | 字形模糊 | 使用 CharacterSet 排除不可能的字符 |
| 七段显示识别错误 | 布局分析拆分了文本行 | LayoutAnalysis="word" |
| 文本太小 | 高度 <20px | OCR 前使用 imresize(I, 3) |
| 单词被异常拆分 | 文本倾斜 | 通过质心拟合进行倾斜校正,并使用 imrotate |
| OCR 失败时,请返回第 1 步,重新检查二值化后的输出。对于无法解决的情况(草书手写、CAPTCHA、<30px 的文本、弯曲/弧形文本),不要反复尝试——请尽早告知用户。请参阅 reference/limitations.md。 |
Copyright 2026 The MathWorks, Inc.