# 卡牌区域 OCR 内容指南 > **状态:2026-08-11 起,card_no 抽取逻辑已废弃** > 最终编号改走检测裁剪 + rec-only + 单次宽容。 > 后处理规则见:**`卡牌区域OCR_rec宽容政策.md`** --- ## 一、新链路(当前生效) ```text 原图 → card_seg_v2 分割 + warp + ensure_portrait → yolo26s_card_no 检测(conf=0.3;多框取最高 conf) → 裁剪编号区域 → PP-OCRv6_medium_rec(仅 rec,不走 det) → apply_leniency(单次) → 若 rec_score≤0.9 且不合规格式 → card_no 置空(blur_unreadable) → 最终 card_no ``` | 步骤 | 实现 | |------|------| | 检测裁剪 | `pokemon/flat_card_no_detect.py` | | OCR + 宽容 + 低分置空 | `pokemon/flat_card_no_ocr.py` | | 宽容/格式判定 | `modules/card_no_leniency.py` | **空结果展示两类:** | blank_type | 对应 empty_reason | 含义 | |------------|-------------------|------| | **无编号** | `no_detection` 或 `rec_empty` | 无检测框,或有框但 rec 空 → 视同无编号 | | **模糊不可读** | `blur_unreadable` | 有框,但 rec_score≤0.9 且不合规 → 图模糊 | **说明:** rarity_short / element 不由 OCR 猜,由独立 yolo26s 检测模型输出。 --- ## 二、合法 card_no 格式清单(验收口径) > 以下用于**判断 rec 结果是否属于合法编号形态**。 > 新链路**不再**用这套规则从整段 OCR 里“选号”;仅作格式对照与验收。 ### 1. 斜杠式 `左/右`(最常见) | 项 | 规则 | |----|------| | 形态 | `左侧/右侧` | | 位数 | 两侧各 **1~5** 位(含字母数字) | | 内容 | 优先数字,也可字母数字混合;至少一侧含数字 | | 右侧连字符促销码 | 允许,如 `270/SM-P`、`144/S-P`、`337/S-P` | | 右侧中点促销码 | 允许,如 `137/SM·P` | | 右侧更长促销码 | 允许,如 `002/30th-P` | | 稀有度后缀 | 右侧粘连 `RR/AR/SR/CHR/SAR/MA/RRR/SSR/PR/UR…` 时剥离后再看编号 | | 示例 | `148/172`、`TG18/TG30`、`SV107/SV122`、`002/30th-P`、`137/SM·P` | ### 2. `No.` 式 | 项 | 规则 | |----|------| | 形态 | `No.` + **1~4 位数字** | | 容忍 | 大小写;句点/空格;`o/O` 误读为 `a/A`(`Na 128`);`mo.` 误读 | | 输出 | 统一 `No.XXX` | | 示例 | `No.128`、`No. 249` → `No.249`;`Na 128` → `No.128`;`mo.066` → `No.066` | ### 3. 长码式(无斜杠) | 项 | 规则 | |----|------| | 形态 | **大写字母开头**,字母 + 数字混合,**总长 ≥3** | | 约束 | 一般不带连字符(防伪长串排除) | | 示例 | `AR5`、`XY17`、`XY44`、`DP09`、`SWSH144`、`SWSH261` | ### 4. 短纯数字 | 项 | 规则 | |----|------| | 形态 | **≤3 位**纯数字(可 `0` 开头) | | 黑名单 | `999`、`000`(多是版权年/噪声,不作为有效编号) | | 示例 | `5`、`24`、`001`、`023`、`123` | ### 5. 井号式 | 项 | 规则 | |----|------| | 形态 | **3~4 位**字母 + `#` + 数字(≥1 位) | | 输出 | 字母统一大写 | | 示例 | `ABC#12`、`DPBP#299`、`DPBP#480` | --- ## 三、相对旧文档的格式补全(2026-08-11) 在 `rec_score > 0.9` 实测(识别正确)中发现、旧 1~4 位斜杠/≥4 长码未写清的合法形态: | 补全项 | 旧口径 | 新口径 | 示例 | |--------|--------|--------|------| | 斜杠位数 | 两侧 1~4 | **两侧 1~5** | `SV107/SV122` | | 促销码长度 | 右侧约 ≤4 | **右侧可更长** | `002/30th-P` | | 促销码分隔符 | 仅 `-` | **另含中点 `·`** | `137/SM·P` | | 长码最短长度 | ≥4 | **≥3** | `AR5` | **不算新格式(勿写入格式表):** | 结果 | 原因 | |------|------| | `001/SM-`(如 8321194) | 检测框偏短,真值多为 `001/SM-P` | | `7/SV122` | 左侧被裁断的 SV 码 | | `opponent` / `retreat` / `80 HP` | 框到非编号区域 | | `168132` / `2293` | 纯数字长串,靠宽容政策尝试还原,不是独立编号格式 | --- ## 四、已废弃的旧选号逻辑(仅归档) 旧链路: ```text 固定 ROI 裁 seq_left / seq_right → PaddleOCR(det+rec) → 用五种格式从文本里“猜”card_no → 左右框按 格式优先级 > 左框优先 > OCR conf 选定唯一结果 ``` 旧附加规则中,**仍有用、已并入新宽容政策**的: - `No.` / `Na` / `mo.` 归一 - 稀有度后缀剥离 **不再需要**的: - 从左右两框猜哪个是编号 - 斜杠两侧类型一致性 + 边缘噪点字母删除(`F148/172`→`148/172`)——检测框已基本消掉这类串扰 --- ## 五、相关文档 | 文档 | 用途 | |------|------| | `卡牌区域OCR_rec宽容政策.md` | **当前唯一后处理规则**(单次宽容) | | `modules/card_no_leniency.py` | 宽容政策代码实现 |