
简介这份压缩包围绕麻将图像识别与自动化打牌AI调用SDK展开面向对棋牌AI、计算机视觉及自动化决策感兴趣的开发者或进阶学习者解决从牌面识别到智能出牌流程落地的需求。包内共29个文件涵盖8个Python源码、12张图像资源、2份说明文档以及proto、pkl、model、json、license、md等辅助文件配置与目录结构较完整便于按模块理解工程组织。其中Python代码与模型文件支撑图像识别和AI决策调用图像与文档则用于训练、测试及上手参考。资源包大小约8.74MB轻量易用已有314人学习浏览。通过阅读简介与说明文件使用者可快速掌握SDK的调用方式结合liqi、sdk等模块搭建自动化打牌流程并借助示例图像和模型进行识别效果验证。对于想研究麻将AI策略或构建图像识别决策系统的开发者这份集成封装提供了可直接上手的基础工具与思路参考。 最近整理旧硬盘翻出来一个熟悉又陌生的包麻将_图像识别_自动化打牌_AI调用SDK_1743961947.zip。看时间戳是今年4月打包的里面装着我折腾了一个多月的“视觉识别 AI决策 自动操作”麻将实验工程。所谓自动化打牌不是拿脚本去线上打牌而是把整条链路跑通摄像头或录屏抓到画面用图像识别把牌面变成结构化数据交给AI大模型的SDK出决策最后模拟鼠标点击完成出牌动作。这个项目对想入门图像识别工程化、SDK集成、自动化操作的朋友来说参考价值比看单点教程高得多因为它是真正踩过坑之后沉淀下来的完整闭环。1. 项目整体设计一条“感知-决策-执行”的流水线1.1 核心需求拆解拿到这种需求第一件事不是急着写代码而是把“自动化打牌”拆成几个独立的子问题。整个链路可以分成四层画面采集层从摄像头、录屏文件或视频流里拿到一帧一帧的牌桌画面。牌面识别层从画面里定位每张牌的位置识别花色和点数输出结构化数据。决策层把当前手牌、河牌、别家出的牌喂给AI模型让模型给出“打哪张/碰不碰/胡不胡”的动作。控制执行层把AI输出翻译成屏幕上的鼠标点击操作。这个拆法最大的好处是每一层可以独立测试。识别层不行就单独调识别控制层失灵就单独调控制不用每次都在完整链路上排错。这里必须先把边界说清楚整个工程我只在自建的测试环境里跑过用于个人学习演示、离线牌局复盘和AI决策推演。这个方案不应该也从来没有被用于任何线上牌局或涉及财物的场景。把它当工程练习题价值很大拿去动歪脑筋只会吃亏。下面所有分享都基于这个前提。1.2 技术选型为什么是OpenCV Tess4J AI SDK技术选型上我纠结过一阵最后定为OpenCV做图像处理Tess4J做OCR兜底识别大模型SDK出决策。核心原因有三点OpenCV成熟稳定找轮廓、模板匹配、边缘检测这些经典算法足够处理固定机位下的麻将牌识别。当时也考虑过YOLOv8直接训练一个目标检测模型但训练数据要人工标注几百张图项目周期撑不住。OpenCV零训练成本规则写清楚一样能干活。Tess4J解决“文字类牌面”麻将里的字牌、花牌、东西南北中发白纯模板匹配在角度和光照变化时容易翻车OCR反而稳定。Tess4J是Java生态里最顺手的OCR库集成简单离线可用。大模型SDK省掉写牌型算法传统做法是写一套完整的胡牌判断、出牌策略、概率计算代码工程量大得惊人。既然手边有大模型SDK我只需要把牌局状态编码成文字请求模型就能给出合理决策这本质上是搭了一个简单的视觉AI Agent。1.3 打包目录结构这个zip包解压之后大概是这样的麻将_图像识别_自动化打牌_AI调用SDK/ ├── src/ │ ├── main/java/com/mjauto/ │ │ ├── capture/ # 视频采集 │ │ ├── vision/ # 图像识别、OCR │ │ ├── ai/ # 大模型SDK封装 │ │ ├── control/ # 自动点击控制 │ │ └── Main.java # 主循环 │ ├── main/resources/ │ │ ├── templates/ # 牌面模板图 │ │ └── tessdata/ # OCR语言包 ├── test/ └── README.md模块划分很清楚capture只管拿帧vision只管把帧变成牌ai只管给决策control只管执行。谁出了问题就查谁不互相甩锅。2. 图像识别模块让程序“看清”每一张牌2.1 视频源接入到底要不要自己写视频解码“视频图像识别是否要做视频解码”这个问题被问过很多次。答案是绝大多数场景不用自己解。OpenCV的VideoCapture封装了FFmpegUSB摄像头、屏幕录制、RTSP视频流、本地mp4都能直接读取它会自动完成解码你拿到的是Mat帧。真正要关心的是两件事解码帧率和分辨率。我测试时用的输入是1080p录屏文件直接按原始分辨率读帧率控制在8到10 FPS。图像识别不需要高帧率麻将一个回合出牌间隔至少好几秒8 FPS绰绰有余。反而不建议用30 FPS跑每帧全流程走一遍CPU占用很高后面控制层反而反应不过来。2.2 牌面定位与单张牌切割识别最核心的一步是定位。我用的方案是经典轮廓检测流程如下Mat gray new Mat(); Imgproc.cvtColor(frame, gray, Imgproc.COLOR_BGR2GRAY); Imgproc.GaussianBlur(gray, gray, new Size(5, 5), 0); Mat binary new Mat(); Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);流程是转灰度 - 高斯模糊降噪 - Otsu自适应二值化 - findContours找轮廓 - 按面积和长宽比过滤 - 按坐标排序。滤波条件我调了很多轮最后稳定在轮廓面积500到5000像素、宽高比0.6到0.9这个区间。在这个条件之外的基本都是噪点、牌桌花纹或者手指影子。这里有个非常实用的技巧麻将牌在牌桌上会有一定倾斜直接切出来的矩形可能带边角干扰。我在切图之前加了一步最小外接矩形矫正用Imgproc.minAreaRect拿到旋转角度再做仿射变换把牌转正。这一步之后不管是模板匹配还是OCR准确率都上了一个台阶。2.3 模板匹配和Tess4J OCR如何分工最初我只用模板匹配两张牌颜色相近或者打印字体变形就乱认。后来改成模板匹配优先、OCR兜底的混合方案。方案优点缺点模板匹配速度快、实现简单、对规则字体识别极准换环境要重新截图遇倾斜和光影变化易失效Tess4J OCR对文字类牌面通用性强能容忍角度、光照变化对花牌图案几乎无能为力识别速度稍慢我处理的策略是先对每一张切割好的牌做模板匹配用归一化相关系数打分分数高于0.85就认为是可靠结果直接采用。低于0.85再交给Tess4J识别字牌文字识别结果还要做一次白名单过滤。白名单是条数不多的字符集合比如“一条 二条 三万 红中 发财”这些。OCR结果不在白名单里就标记为“未知牌”等待下一帧重新识别。这招非常管用。用了混合识别之后单帧牌面识别准确率从89%左右提升到97%以上而且没有增加太多计算耗时。2.4 识别结果的结构化输出识别层输出的不是图片而是牌对象列表。麻将的张数、花色、序号都要精确定义否则后面决策层全乱。我在代码里定义了一个Tile类public class Tile { private String suit; // wan / tiao / bing / zi private int rank; // 1-9字牌用0-6代替 private String rawName; // 原始识别文本用于调试 }转成字符串之后大概是“手牌: 一万 一万 三万 五条 六条 七条 二筒 三筒 四筒 红中”。这种结构化的状态文本是给AI模型做决策的基础。3. AI决策层与SDK调用链路3.1 牌局状态怎么编码给AI大模型不认识图像它只认识文本所以必须把牌局状态组织成清晰的自然语言描述。我设计的prompt模板大致是这样你现在是一个严谨的麻将出牌助手。当前是我方手牌... 牌河里的牌... 别家刚刚打出的牌... 场上已经碰/杠的牌... 请从手牌中选择一张打出去只输出牌名不要解释。很多AI Agent项目轻视prompt的作用实际上prompt写得好不好直接影响决策质量。我第一版只给了“手牌”三个字加牌列表模型经常给出明显不合理的出牌。后来把牌河、别家动作、碰杠记录全部写进去决策才变得合理。3.2 大模型SDK调用封装SDK调用这块务必做两层封装。第一层是基础鉴权把API Key放到环境变量里不要硬编码进代码。第二层是超时重试。大模型接口不是本地函数动不动可能卡几秒而且有概率返回空结果。我封装了一个AiClient核心逻辑如下public String ask(String prompt) { // 组装请求体设置超时时间 RequestBody body buildBody(prompt, 5_000); // 5秒超时 for (int i 0; i 3; i) { try { Response resp httpClient.newCall(request).execute(); if (resp.isSuccessful()) { return parseResponse(resp.body().string()); } } catch (IOException e) { log.warn(第{}次调用失败: {}, i 1, e.getMessage()); } } return ; // 返回空串上层走兜底策略 }这里有个很多人没意识到的点大模型调用失败不代表程序要崩。返回空结果的时候决策层应该有一个兜底方案比如直接打出最右边那张牌或者沿用规则引擎写死的简单策略。对自动化系统来说稳定可用比每次最优更重要。3.3 决策延迟与降级方案实测下来单次大模型调用的响应时间在1到3秒之间偶尔到5秒。牌局中发呆几秒虽然不算致命但体验很差。我做了两个优化一是当牌型和上一帧完全一样时直接忽略这次AI请求沿用上次决策二是把最近20个回合的请求结果做本地缓存相同牌型直接命中。实际跑下来加了缓存之后平均决策耗时从2秒左右降到了0.8秒。这个优化在后续联调中起了大作用自动化打牌的节奏从“一顿一顿”变成了“流畅连贯”。4. 控制执行层与整机联调4.1 屏幕坐标映射AI输出的是“三条”这个牌名控制层必须知道穿三条按钮在屏幕哪个位置。坐标映射公式很简单图像识别到的牌区域中心坐标乘以缩放系数加上偏移量就是屏幕点击坐标。我遇到的最大坑是Windows的DPI缩放。屏幕显示缩放如果是125%或者150%Java Robot拿到的坐标和实际屏幕像素对不上。解决办法是读取系统DPI缩放比把映射系数乘上这个值。double scaleX screenWidth / frameWidth; double scaleY screenHeight / frameHeight; int targetX (int)(tileCenterX * scaleX); int targetY (int)(tileCenterY * scaleY); robot.mouseMove(targetX, targetY); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);4.2 主循环设计整个系统的主循环其实很简单就这个结构while (running) { Mat frame capture.grabFrame(); // 采集一帧 ListTile hand recognizer.recognize(frame); // 图像识别 String action aiClient.ask(buildPrompt(hand)); // AI调用SDK robot.click(calcPosition(action)); // 自动化操作 Thread.sleep(500 ThreadLocalRandom.current().nextInt(200)); }采集、识别、决策、执行周而复始。睡前一段随机睡眠是为了让操作节奏不至于像机器一样精准在真机演示时更自然。这一行随机延时一定要加否则机器人痕迹太明显而且对硬件负担也大。每次点击之后至少等500毫秒给画面刷新留出时间。4.3 安全护栏看门狗与急停自动化操作一旦跑起来最怕的就是识别错了还一路往下点。我加了三道保险手动急停监听键盘按下Esc键立即跳出循环释放鼠标。看门狗连续5帧识别结果变化异常比如某区域大面积花屏主动暂停流程等画面恢复。操作间隔下限每次点击之间强制执行500毫秒以上的间隔防止失控状态下高速连点。这三道护栏在调试中真的救过我好几回。有一次识别模块写了个边界bug导致方块坐标变成负数鼠标直接飞到屏幕角落。要不是看门狗强制暂停可能就把系统设置界面点开了。5. 常见问题与避坑指南5.1 识别错牌漏牌的最常见原因识别不准的原因我按踩坑频率排了个序光照突变环境光变化导致二值化结果不稳定。解决方案是不要固定二值化阈值用Otsu自适应阈值已经能解决大部分情况。牌面反光牌桌贴膜或者灯光直射时牌面会出现高光区域。预处理阶段先做高斯模糊能压掉一部分高光噪声。相邻牌粘连两张牌挨太近轮廓检测会合并成一个轮廓。我的做法是如果检测出宽高比明显大于正常的轮廓就按中线切分再二次识别。5.2 决策超时导致系统“发呆”这个问题出现得很隐蔽。AI SDK偶尔会挂起超过10秒如果主线程一直被阻塞整个流程就像死机一样。排查方法很简单在日志里记录每次调用的开始时间和结束时间统计P95延迟。后来我把HTTP客户端连接超时和读取超时都设成5秒配合重试机制最坏情况也不会超过15秒就恢复执行。5.3 点击操作无效或被系统拦截自动化点击有时点了没反应排查思路如下现象可能原因解决办法鼠标动了但按钮没触发点击坐标偏了或DPI缩放未处理校准坐标映射重新读取缩放比例有时点得中有时点不中画面延迟导致目标位置已变化点击前重新识别一次目标位置完全无反应程序没有系统辅助权限以管理员或辅助功能授权方式运行游戏窗口失焦点击被发送到后台窗口先调用robot.windowActivate把窗口置前还有一个细节模拟点击之前一定要确认窗口是激活状态。否则点击坐标在屏幕上是那个位置但事件被系统发给别的窗口点了等于白点。5.4 测试复现建议如果你想复现这个项目我强烈建议先用录屏文件调试而不是一上来就连摄像头或者真机。把一段牌局录成mp4所有模块都对着视频跑。视频的好处是可暂停、可倒放、可反复验证识别效果调参效率比真机环境高十倍。等识别和决策在离线视频上稳定了再切到真机联调。这个项目的代码后来被我重构了两遍。第一版卡在识别环节第二版卡在决策延迟第三版才把链路做到稳定。我个人的体会是这类“感知-决策-执行”的闭环项目真正的难点从来不在单点技术而在把几个模块拼在一起还能保持稳定。花在联调上的时间通常比写每个模块的时间加起来还多。如果你也对这类自动化工程感兴趣建议从最简版本起步一个识别模块加一个定时点击模块先把“看清牌”和“点得准”练扎实再加AI决策层。最后再多说一句这套方案只适合在自建环境里做技术验证不要想着拿去做线上牌局或任何涉财场景把它当工程题来做你会收获非常大。本文还有配套的精品资源点击获取