# paper-recognizer — 微信小程序尿检试纸识别 纯 JavaScript 实现,零依赖,约 40KB。复制即用。 ## 文件说明 ``` miniapp/ ├── paper-recognizer.js # 核心识别引擎(唯一必需文件) └── README.md ``` ## 快速集成 ### 1. 复制文件 将 `paper-recognizer.js` 放入小程序项目的 `utils/` 目录。 ### 2. 页面引入 ```javascript // pages/recognize/recognize.js const { PaperRecognizer } = require('../../utils/paper-recognizer.js'); const recognizer = new PaperRecognizer(); ``` ### 3. 拍照识别 ```javascript Page({ data: { result: null }, // 拍照 onTakePhoto() { wx.chooseImage({ count: 1, sourceType: ['camera'], success: (res) => this.doRecognize(res.tempFilePaths[0]) }); }, // 识别 doRecognize(filePath) { wx.getImageInfo({ src: filePath, success: (info) => { // 建议长边超过 1500px 时先缩放,保证性能 const maxLen = 1500; let w = info.width, h = info.height; if (Math.max(w, h) > maxLen) { const scale = maxLen / Math.max(w, h); w = Math.round(w * scale); h = Math.round(h * scale); } // 离屏 Canvas 获取像素 const ctx = wx.createCanvasContext('offscreenCanvas', this); ctx.drawImage(filePath, 0, 0, w, h); ctx.draw(false, () => { wx.canvasGetImageData({ canvasId: 'offscreenCanvas', x: 0, y: 0, width: w, height: h, success: (res) => { const rgba = new Uint8Array(res.data); const result = this.recognizer.recognize(rgba, w, h); if (result.success) { console.log('试纸类型:', result.paperType); console.log('色块数量:', result.itemCount); console.log('定位块颜色:', result.locatorColor); console.log('颜色数据:', result.colors); } else { console.error('识别失败:', result.errorCode, result.errorMessage); } } }); }); } }); } }); ``` ### 3. 相册选图识别 ```javascript wx.chooseImage({ count: 1, sourceType: ['album'], success: (res) => this.doRecognize(res.tempFilePaths[0]) }); ``` ## 识别结果字段 | 字段 | 类型 | 说明 | |------|------|------| | `success` | boolean | 是否成功 | | `errorCode` | number | 错误码(成功为 0) | | `errorMessage` | string | 错误描述 | | `paperType` | string | 试纸类型,如 "14_S", "11_L" | | `itemCount` | number | 色块数量 | | `locatorColor` | string | 定位块颜色 "Red"/"Green"/"Blue" | | `smallLocatorOnLeft` | boolean | 小定位块是否在左侧 | | `blurLevel` | string | 清晰度 "None"/"Slight"/"Severe" | | `blurScore` | number | 清晰度分数(越高越清晰,>300 为 None) | | `colors` | array | 色块颜色数组 `[{id, r, g, b}, ...]` | ## 错误码 | 码 | 含义 | |----|------| | 0 | 成功 | | -1 | 未找到定位块 | | -2 | 定位块配对失败 | | -3 | 定位块颜色不一致 | | -4 | 未找到匹配的试纸配置 | | -5 | 未知试纸类型 | ## 性能参考 | 图片分辨率 | 预估耗时 | 建议 | |-----------|---------|------| | < 800×100 | < 20ms | 直接处理 | | ~1100×400 | ~150ms | 直接处理 | | ~2500×1100 | ~600ms | 建议缩放到 1500px | | > 3000px | > 1s | 必须缩放 | ## 注意事项 1. **Canvas 必须存在于 WXML 中** — 即使隐藏也要声明: ```html ``` 2. **拍照时保持试纸平整** — 严重透视变形或大角度旋转可能导致识别失败。 3. **光照均匀** — 算法使用 HSV 颜色分割,极端光照(强反光、暗光)下定位块可能漏检。 4. **仅支持 14/11/8 项试纸** — 支持短型(S)和长型(L)两种规格。 ## 试纸类型清单 | paperType | itemCount | 说明 | |-----------|-----------|------| | 14_S | 14 | 14 项短型 | | 14_L | 14 | 14 项长型 | | 11_S | 11 | 11 项短型 | | 11_L | 11 | 11 项长型 | | 8_S | 8 | 8 项短型 | | 8_L | 8 | 8 项长型 |