)
摘要在前几篇文章中我们已经完成了 模板资源构建tft_fetch_assets.py、英雄识别与装备识别tft_screen_capture.py中的模板匹配链路。这些能力解决的是在已知头像区域的前提下判断“这是谁、带了什么装备”。但真实使用时用户上传的并不只有 DataTFT 棋盘图还可能是 结算横排图、大厅阵容羁绊八人表、战绩回顾双棋盘 等完全不同版式。若仍用同一套六边形边框检测 棋盘逻辑就会出现框检不到、玩家行数错乱、英雄大面积漏检等问题。本文聚焦tft_screen_capture.py中的 截图模式路由层detect_screenshot_mode()与统一入口recognize(modeauto)。说明项目如何在毫秒级内判断这是哪种游戏界面再分发到四条识别管线并结合一次 金铲铲手游阵容羁绊截图 的实测区分路由对了与识别对了两个层次体现当前技术进度与后续优化方向。一、在整条项目链路里路由层处在什么位置把 TFT 阵容顾问项目串起来截图相关链路可以写成tft_data_manager.py↓tft_champion_db.json / tft_item_db.json↓tft_fetch_assets.py → tft_assets/champions、items↓tft_screen_capture.py├─ detect_screenshot_mode() ← 本文判断界面类型├─ recognize_board / lineup / global / duel└─ identify_champion / identify_items↓tft_converter.py → 羁绊、摘要、装备问题↓tft_web_ui.py / tft_rag_agent.py → 展示与 AI 分析与前几篇的关系可以这样理解篇序主题解决的问题第 1 篇tft_fetch_assets.py模板从哪来、如何标准化第 2 篇LLMClient分析层如何调模型第 3 篇英雄识别头像区域里是谁第 4 篇装备识别英雄框下方带什么装备第 5 篇截图模式路由整张图该用哪套认图逻辑英雄识别和装备识别都假设你已经站在正确的战场上。路由层的职责就是在进战场之前选对地图。二、为什么不能让一张recognize_from_array打天下第 3 篇里棋盘模式的核心是detect_hero_boxes()用 HSV 检测青/紫/金/蓝六边形边框再裁剪头像做直方图 NCC。这套逻辑在 DataTFT 模拟器、对局棋盘上很合适。但另外三类界面版式差异是结构性的不是调阈值能解决的模式典型画面头像从哪来若误用棋盘逻辑的后果board4×7 六边形格、模拟器窄图彩色边框轮廓—lineup结算简略横排图标间距约 1px等间距推算 stride六边形检测为空或极少global八人阵容羁绊表小图标密排左侧头像定行 行内滑窗把表格当棋盘框全错duel上下两个棋盘先切分上下区域再当 board中间 UI 干扰、重复识别因此项目在recognize()里做了 策略模式式分发模式判断与模式执行分离而不是在一个函数里堆满if-else。统一入口核心逻辑如下if mode auto: mode detect_screenshot_mode(img) if mode lineup: return recognize_lineup(...) if mode global: return recognize_global(...) if mode duel: return recognize_duel(...) return recognize_from_array(...) # board设计取舍路由层用可解释的启发式宽高比、HSV 紫色占比、导航栏亮度而不是再训一个四分类 CNN。对个人项目而言误判时对着一张图改阈值、加--mode强制覆盖比黑盒模型更易维护真正耗时的滑动窗口、Hough 圆检测放在各子模式里执行。三、detect_screenshot_mode()决策树函数不到 50 行逻辑是 分层排除不是多特征加权打分。理解它最好画成决策树读入图像 (h, w)│├─ aspect w/h 2.1 且 h 500 ?│ └─ 是 → board模拟器/窄棋盘│├─ 统计 HSV 紫色像素占比 purple_density│ └─ 0.05 → lineup深蓝结算背景少紫色 UI│└─ 裁顶部导航中间条带统计高亮像素 mid_bright├─ 800 → global阵容羁绊Tab 居中高亮└─ 否则 → duel战绩回顾等中间不亮1. 第一层用几何特征切出boardif aspect 2.1 and h 500: return board依据来自实际样张DataTFT 导出图宽高比约 1.92.1高度往往只有几百像素手机全屏截图普遍更高、更宽。2. 第二层用大厅紫区分lineup与global/duelpurple_mask cv2.inRange(hsv, [130,25,20], [175,200,120]) purple_density purple_mask.sum() / 255 / (h * w) if purple_density 0.05: return lineup工程意图结算简略图背景偏深蓝饱和紫色 UI 很少而阵容羁绊和战绩回顾等大图带有明显紫色/粉色面板。用色相区间而不是整体亮度是为了避免都很暗却属于不同界面。3. 第三层用导航栏亮度区分global与duelmid_nav img[0:60, int(w * 0.40):int(w * 0.65)] mid_bright (cv2.cvtColor(mid_nav, cv2.COLOR_BGR2GRAY) 180).sum() return global if mid_bright 800 else duelGlobal 页阵容羁绊Tab 在中间Duel 页高亮往往在战绩回顾等偏右 Tab中间条带相对暗。四、四种模式分别走哪条识别管线路由只负责选路怎么找头像框仍由各recognize_*独立完成。这和第 3、4 篇的同一套identify_champion不同定位方式是一致的。模式入口函数定位思路macro输出特点boardrecognize_from_array六边形边框 可选横排降级单队、站位、装备lineuprecognize_lineup面部条带推 stride失败则降级 board_source: cv_lineupglobalrecognize_global左侧 Hough 圆定玩家行 行内小图滑窗含players多队duelrecognize_duel行亮度找中间暗带切上下棋盘对战双方board内的二级补救即使路由判定为boardrecognize_from_array()里还有一层 micro-layout 判断boxes detect_hero_boxes(img) if not boxes or is_horizontal_layout(boxes): h_boxes detect_horizontal_lineup(img) if len(h_boxes) len(boxes): boxes h_boxes layout_mode lineup路由说是棋盘但版式像横排则在同一函数内换横排框检测。这与detect_screenshot_mode → lineup不是重复——前者是 board 路径上的降级后者是整条管线切换。五、与项目其他模块如何衔接1.tft_converter.pyconvert(bytes)只根据 Python 类型把字节流交给from_image() → recognize()不会二次判断界面。截图分拣完全在tft_screen_capture内完成。2.tft_web_ui.py/api/input/screenshot读取上传文件后直接recognize(img_bytes)默认modeauto。前端若增加“我这是羁绊表”下拉框只需传mode即可绕过脆弱启发式。3. 与第 3、4 篇识别核心的关系模板加载RGBA 灰底合成、64×64、直方图缓存各模式共用。identify_champion/identify_items在框定 ROI 之后共用Global 小图路径里直方图阈值更严如 0.55再 NCC 融合。_source字段cv_template、cv_lineup、cv_global等便于日志里区分路由对了但子管线失败。六、CLI 与可观测性设计主入口支持的模式参数python tft_screen_capture.py screenshot.png # 默认 auto python tft_screen_capture.py screenshot.png --mode global --debug参数作用--mode auto调用detect_screenshot_mode并打印检测结果--mode board/lineup/global/duel跳过自动检测用于误判排查--debug输出tft_debug.png查看行框与小图标框建议调试顺序先看[自动检测] 截图模式是否符合肉眼界面不对则--mode强制指定验证是否为路由问题模式正确但英雄仍错用--debug/--diagnose进入第 3 篇流程查框与匹配分。七、当前技术进度仅路由与子管线分工路由层已完成四种模式枚举与recognize()统一分发detect_screenshot_mode三层启发式几何 → 紫色密度 → 导航亮度CLI / Web 默认auto与--mode覆盖board内横排布局二级降级八、总结TFT 阵容顾问的截图识别不是一个模板匹配函数处理所有图片而是 先路由、再识别 的两段式架构解码图像→ detect_screenshot_mode界面类型→ recognize_board / lineup / global / duel版式与 ROI→ identify_champion / identify_items内容与置信度→ tft_converter / Agent业务分析detect_screenshot_mode()用宽高比、HSV 紫色占比、顶部导航亮度完成分流刻意保持 可解释、可覆盖、低开销四条子管线则承接第 3、4 篇中的英雄与装备匹配能力在不同版式下用不同方式找到头像再匹配。结合金铲铲阵容羁绊实测路由层已能稳定识别为global