[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-70936":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":32,"lastSyncTime":33,"discoverSource":34},70936,"ddddocr","sml2h3\u002Fddddocr","sml2h3","带带弟弟 通用验证码识别OCR pypi版","https:\u002F\u002Fddddocr.com",null,"Python",14225,2284,98,114,0,18,70,184,54,45,"MIT License",false,"master",true,[27,5,28],"captcha","ocr","2026-06-12 02:02:45","# DdddOcr - 通用验证码识别SDK\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"logo.png\" alt=\"DdddOcr Logo\" width=\"300\">\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Cstrong>一个简单易用的通用验证码识别Python库\u003C\u002Fstrong>\n\u003C\u002Fp>\n\n## 目录\n\n- [赞助合作商](#赞助合作商)\n- [项目介绍](#项目介绍)\n- [环境支持](#环境支持)\n- [安装方法](#安装方法)\n- [功能概览](#功能概览)\n- [初始化参数详解](#初始化参数详解)\n  - [参数详细说明](#参数详细说明)\n  - [功能组合与冲突](#功能组合与冲突)\n  - [模型选择指南](#模型选择指南)\n  - [性能优化参数](#性能优化参数)\n- [详细使用说明](#详细使用说明)\n  - [文字识别功能](#文字识别功能)\n    - [基础OCR识别](#基础ocr识别)\n    - [OCR概率输出](#ocr概率输出)\n    - [自定义字符范围](#自定义字符范围)\n    - [颜色过滤功能](#颜色过滤功能)\n  - [目标检测功能](#目标检测功能)\n  - [滑块验证码处理](#滑块验证码处理)\n    - [算法1：边缘匹配](#算法1边缘匹配)\n    - [算法2：图像差异比较](#算法2图像差异比较)\n  - [自定义模型导入](#自定义模型导入)\n- [高级用法](#高级用法)\n  - [批量处理](#批量处理)\n  - [多线程优化](#多线程优化)\n  - [验证码预处理](#验证码预处理)\n- [常见问题](#常见问题)\n  - [初始化速度慢](#初始化速度慢)\n  - [识别准确率不高](#识别准确率不高)\n  - [GPU加速](#gpu加速)\n  - [处理复杂验证码](#如何处理复杂验证码)\n  - [内存占用过高](#内存占用过高)\n  - [参数冲突问题](#参数冲突问题)\n  - [支持的图片格式](#支持的图片格式)\n  - [多线程并发问题](#多线程并发问题)\n- [项目技术支持](#项目技术支持)\n- [使用示例](#使用示例)\n- [许可证](#许可证)\n\n## 赞助合作商\n\n|                                                            | 赞助合作商 | 推荐理由                                                                                             |\n|------------------------------------------------------------|------------|--------------------------------------------------------------------------------------------------|\n| ![YesCaptcha](https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fyescaptcha.png) | [YesCaptcha](https:\u002F\u002Fyescaptcha.com\u002Fi\u002FNSwk7i) | 谷歌reCaptcha验证码 \u002F hCaptcha验证码 \u002F funCaptcha验证码商业级识别接口 [点我](https:\u002F\u002Fyescaptcha.com\u002Fi\u002FNSwk7i) 直达VIP4 |\n| ![超级鹰](https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Flogo.gif) | [超级鹰](https:\u002F\u002Fwww.chaojiying.com\u002F) | 全球领先的智能图片分类及识别商家，安全、准确、高效、稳定、开放，强大的技术及校验团队，支持大并发。7*24h作业进度管理 |\n| ![Malenia](https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fmalenia.png!\u002Fscale\u002F50)    | [Malenia](https:\u002F\u002Fmalenia.iinti.cn\u002Fmalenia-doc\u002F) | Malenia企业级代理IP网关平台\u002F代理IP分销软件 |\n| 雨云VPS    | [注册首月5折](https:\u002F\u002Fwww.rainyun.com\u002Fddddocr_) | 浙江节点低价大带宽，100M每月30元 |\n\n## 项目介绍\n\nDdddOcr 是一个通用验证码离线本地识别SDK，由 [sml2h3](https:\u002F\u002Fgithub.com\u002Fsml2h3) 与 [kerlomz](https:\u002F\u002Fgithub.com\u002Fkerlomz) 共同开发完成。该项目通过大批量生成随机数据进行深度网络训练，可以识别各种类型的验证码，包括：\n\n- 常见的数字字母组合验证码\n- 中文验证码\n- 滑块验证码\n- 各种特殊字符验证码\n\n项目设计理念是\"最简依赖\"，尽量减少用户的配置和使用成本，提供简单易用的API接口。\n\n## 环境支持\n\n| 系统 | CPU | GPU | 最大支持Python版本 | 备注 |\n|-----|-----|-----|--------------|-----|\n| Windows 64位 | ✓ | ✓ | 3.12 | 部分版本Windows需要安装[vc运行库](https:\u002F\u002Fwww.ghxi.com\u002Fyxkhj.html) |\n| Linux 64 \u002F ARM64 | ✓ | ✓ | 3.12 | |\n| macOS X64 | ✓ | ✓ | 3.12 | M1\u002FM2\u002FM3芯片用户请参考[相关说明](https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fddddocr\u002Fissues\u002F67) |\n\n不支持的环境：\n- Windows 32位\n- Linux 32位\n\n## 安装方法\n\n### 从PyPI安装（推荐）\n\n```bash\npip install ddddocr\n```\n\n### 从源码安装\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fddddocr.git\ncd ddddocr\npip install .\n```\n\n### 安装 API 依赖（可选）\n\n```bash\npip install \".[api]\"\n```\n\n> **注意**：请勿直接在ddddocr项目的根目录内直接import ddddocr，请确保你的开发项目目录名称不为ddddocr。\n\n## 功能概览\n\nDdddOcr提供以下核心功能：\n\n| 功能 | 描述 | 初始化参数 |\n|-----|-----|----------|\n| 文字识别 | 识别图片中的文字内容 | `ocr=True`（默认） |\n| 目标检测 | 检测图片中的目标位置 | `det=True` |\n| 滑块验证码识别 | 识别滑块验证码的缺口位置 | `ocr=False` |\n| 自定义模型导入 | 导入自定义训练的模型 | `import_onnx_path=\"模型路径\"` |\n\n## 初始化参数详解\n\n`DdddOcr` 类初始化时支持多种参数配置，以适应不同的使用场景：\n\n```python\nddddocr.DdddOcr(\n    ocr=True,           # 是否启用OCR功能\n    det=False,          # 是否启用目标检测功能\n    old=False,          # 是否使用旧版OCR模型\n    beta=False,         # 是否使用Beta版OCR模型（新模型）\n    use_gpu=False,      # 是否使用GPU加速\n    device_id=0,        # 使用的GPU设备ID\n    show_ad=True,       # 是否显示广告信息\n    import_onnx_path=\"\", # 自定义模型路径\n    charsets_path=\"\",    # 自定义字符集路径\n    max_image_bytes=None, # 单图最大字节数（默认 8MB）\n    max_image_side=None   # 单图最长边限制（默认 4096px）\n)\n```\n\n### 参数详细说明\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----|-----|-----|-----|\n| `ocr` | bool | True | 是否启用OCR功能，用于识别图片中的文字。**互斥性**：当`det=True`时会强制关闭OCR |\n| `det` | bool | False | 是否启用目标检测功能，用于检测图片中的目标位置。**互斥性**：`det=True`会覆盖`ocr=True` |\n| `old` | bool | False | 兼容参数，当前不会改变模型选择（默认即使用旧版模型） |\n| `beta` | bool | False | 是否使用Beta版OCR模型（新模型），对某些验证码识别效果更好。**互斥性**：与`old=True`参数互斥（但`old`当前不生效） |\n| `use_gpu` | bool | False | 是否使用GPU加速。**依赖关系**：需要安装CUDA和相应的onnxruntime-gpu版本，否则会初始化失败 |\n| `device_id` | int | 0 | 使用的GPU设备ID。**依赖关系**：仅在`use_gpu=True`时生效，指定使用哪个GPU设备 |\n| `show_ad` | bool | True | 是否在初始化时显示广告信息 |\n| `import_onnx_path` | str | \"\" | 自定义模型的onnx文件路径。**依赖关系**：设置此参数时，`charsets_path`参数必须同时提供；此时`ocr\u002Fdet`设置会被忽略 |\n| `charsets_path` | str | \"\" | 自定义字符集的json文件路径。**依赖关系**：必须与`import_onnx_path`一起使用，否则无效 |\n| `max_image_bytes` | int\u002Fstr | 8MB | 单图最大字节数上限（入参可为 int 或数字字符串） |\n| `max_image_side` | int\u002Fstr | 4096 | 单图最长边像素上限（入参可为 int 或数字字符串） |\n\n### 功能组合与冲突\n\n根据参数组合，ddddocr具有不同的工作模式：\n\n1. **标准OCR模式**：\n   - 参数设置：`ocr=True, det=False`（默认）\n   - 功能：识别图片中的文字\n\n2. **目标检测模式**：\n   - 参数设置：`ocr=False, det=True`\n   - 功能：检测图片中的目标位置\n   - 注意：同时设置`ocr=True, det=True`时，会进入目标检测模式（`det`优先）\n\n3. **滑块识别模式**：\n   - 参数设置：`ocr=False, det=False`\n   - 功能：使用滑块匹配算法（需调用`slide_match`或`slide_comparison`方法）\n\n4. **自定义模型模式**：\n   - 参数设置：`import_onnx_path=\"模型路径\", charsets_path=\"字符集路径\"`\n   - 功能：使用自定义训练的模型进行识别\n   - 注意：设置此模式时，`ocr`和`det`参数会被忽略，且自定义字符集文件需包含 `charset\u002Fword\u002Fimage\u002Fchannel` 字段\n\n5. **OCR模型选择**：\n   - 默认模型：不设置特殊参数（当前使用 `common_old.onnx`）\n   - Beta模型：`beta=True`（使用 `common.onnx`）\n   - 旧版模型参数：`old=True`（当前不改变模型，仅为兼容保留）\n   - 注意：`beta`和`old`参数互斥，但`old`当前不生效\n\n### 模型选择指南\n\n- **默认模型**：当前默认使用 `common_old.onnx`，适用于多数简单验证码场景\n- **Beta模型**：`beta=True` 使用 `common.onnx`，对部分复杂验证码效果更好\n- **自定义模型**：当默认模型无法满足需求时，可以通过[dddd_trainer](https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fdddd_trainer)训练自己的模型\n\n### 性能优化参数\n\n- **GPU加速**：对于处理大量图片时，开启GPU加速可显著提升性能\n  ```python\n  ocr = ddddocr.DdddOcr(use_gpu=True, device_id=0)\n  ```\n  \n- **GPU设备选择**：在多GPU环境中，可通过`device_id`指定使用的GPU\n  ```python\n  # 使用第二张GPU卡\n  ocr = ddddocr.DdddOcr(use_gpu=True, device_id=1)\n  ```\n\n- **关闭广告显示**：在生产环境中可关闭广告提示\n  ```python\n  ocr = ddddocr.DdddOcr(show_ad=False)\n  ```\n\n## 详细使用说明\n\n### 文字识别功能\n\n#### 基础OCR识别\n\n主要用于识别单行文字，如常见的英数验证码等。支持中文、英文、数字以及部分特殊字符的识别。\n\n```python\nimport ddddocr\n\n# 初始化OCR对象\nocr = ddddocr.DdddOcr()\n\n# 读取图片\nwith open(\"验证码图片.jpg\", \"rb\") as f:\n    image = f.read()\n\n# 识别图片\nresult = ocr.classification(image)\nprint(result)  # 输出识别结果\n```\n\n**OCR识别示例图片**\n\n**参考例图**\n\n包括且不限于以下图片\n\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F20210715211733855.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F78b7f57d-371d-4b65-afb2-d19608ae1892.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211226142305.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211226142325.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F2AMLyA_fd83e1f1800e829033417ae6dd0e0ae0.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Faabd_181ae81dd5526b8b89f987d1179266ce.jpg\" alt=\"captcha\" width=\"150\">\n\u003Cbr \u002F>\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F2bghz_b504e9f9de1ed7070102d21c6481e0cf.png\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F0000_z4ecc2p65rxc610x.jpg\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F2acd_0586b6b36858a4e8a9939db8a7ec07b7.jpg\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F2a8r_79074e311d573d31e1630978fe04b990.jpg\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Faftf_C2vHZlk8540y3qAmCM.bmp\" alt=\"captcha\" width=\"150\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002F%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20211226144057.png\" alt=\"captcha\" width=\"150\">\n\n**OCR模型选择**\n\nDdddOcr内置两套OCR模型，可以通过`beta`参数切换：\n\n```python\n# 使用第二套OCR模型\nocr = ddddocr.DdddOcr(beta=True)\n```\n\n**透明PNG图片处理**\n\n对于透明黑色PNG图片，可以使用`png_fix`参数（对所有 OCR 模式生效）：\n\n```python\nresult = ocr.classification(image, png_fix=True)\n```\n\n> **注意**：`png_fix` 仅对带透明通道的图片生效；初始化DdddOcr对象只需要一次，不要在每次识别时都重新初始化，这会导致速度变慢。\n\n#### OCR概率输出\n\n可以获取OCR识别结果的概率分布，便于进行更灵活的结果处理：\n\n```python\nimport ddddocr\n\nocr = ddddocr.DdddOcr()\nimage = open(\"test.jpg\", \"rb\").read()\n\n# 获取识别结果的概率分布\nresult = ocr.classification(image, probability=True)\n\n# 处理概率结果\ns = \"\"\nfor i in result['probability']:\n    s += result['charsets'][i.index(max(i))]\n\nprint(s)\n```\n\n**概率输出示例**（仅对内置模型生效，自定义模型会忽略`probability=True`并直接返回字符串）：\n\n```python\n# 概率输出结果示例\n{\n    'charsets': ['', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', ...],\n    'probability': [\n        [0.01, 0.02, 0.01, 0.03, 0.02, 0.01, 0.02, 0.75, 0.03, 0.05, 0.01, ...],  # 第一个字符的概率分布\n        [0.01, 0.01, 0.02, 0.01, 0.03, 0.02, 0.01, 0.02, 0.01, 0.80, 0.01, ...],  # 第二个字符的概率分布\n        ...\n    ]\n}\n```\n\n#### 自定义字符范围\n\n可以通过`set_ranges`方法限定OCR识别的字符范围：\n\n```python\nimport ddddocr\n\nocr = ddddocr.DdddOcr()\nimage = open(\"test.jpg\", \"rb\").read()\n\n# 设置识别范围为数字\nocr.set_ranges(0)  # 等同于 ocr.set_ranges(\"0123456789\")\n\n# 或自定义字符范围\nocr.set_ranges(\"0123456789+-x\u002F=\")\n\nresult = ocr.classification(image)\nprint(result)\n```\n\n**内置字符范围参数**：\n\n| 参数值 | 含义 |\n|-----|-----|\n| 0 | 纯数字 0-9 |\n| 1 | 纯小写英文 a-z |\n| 2 | 纯大写英文 A-Z |\n| 3 | 小写英文 + 大写英文 |\n| 4 | 小写英文 + 数字 |\n| 5 | 大写英文 + 数字 |\n| 6 | 小写英文 + 大写英文 + 数字 |\n| 7 | 默认字符库 - 小写英文 - 大写英文 - 数字 |\n\n#### 颜色过滤功能\n\n对于一些特殊的验证码，可以通过颜色过滤来提高识别准确率：\n\n```python\nimport ddddocr\n\nocr = ddddocr.DdddOcr()\nimage = open(\"test.jpg\", \"rb\").read()\n\n# 只保留红色和蓝色部分\nresult = ocr.classification(image, colors=[\"red\", \"blue\"])\nprint(result)\n```\n\n**支持的颜色**：\n- red (红色)\n- green (绿色)\n- blue (蓝色)\n- yellow (黄色)\n- orange (橙色)\n- purple (紫色)\n- pink (粉色)\n- brown (棕色)\n\n也可以自定义颜色范围：\n\n```python\n# 自定义颜色范围\ncustom_ranges = {\n    'light_blue': [(90, 30, 30), (110, 255, 255)]  # HSV颜色空间\n}\n\nresult = ocr.classification(image, colors=[\"light_blue\"], custom_color_ranges=custom_ranges)\n```\n\n> **提示**：`custom_color_ranges` 只有在 `colors` 列表包含对应键名时才会生效。\n\n### 目标检测功能\n\n用于检测图像中可能的目标主体位置，返回目标的边界框坐标：\n\n```python\nimport ddddocr\nimport cv2\n\n# 初始化检测对象\ndet = ddddocr.DdddOcr(det=True, ocr=False)\n\n# 读取图片\nwith open(\"test.jpg\", 'rb') as f:\n    image = f.read()\n\n# 检测目标\nbboxes = det.detection(image)\nprint(bboxes)  # 输出格式：[[x1, y1, x2, y2], ...]\n\n# 可视化检测结果\nim = cv2.imread(\"test.jpg\")\nfor bbox in bboxes:\n    x1, y1, x2, y2 = bbox\n    im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)\ncv2.imwrite(\"result.jpg\", im)\n```\n\n**目标检测示例**：\n\n**参考例图**\n\n包括且不限于以下图片\n\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fpage1_1.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fpage1_2.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fpage1_3.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fpage1_4.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cbr \u002F>\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fresult.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fresult2.jpg\" alt=\"captcha\" width=\"200\">\n\u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fresult4.jpg\" alt=\"captcha\" width=\"200\">\n### 滑块验证码处理\n\nDdddOcr提供两种滑块验证码处理算法：\n\n#### 算法1：边缘匹配\n\n适用于有透明背景的滑块图片，通过边缘检测找到滑块在背景图中的位置：\n\n```python\nimport ddddocr\n\n# 初始化滑块检测对象\nslide = ddddocr.DdddOcr(det=False, ocr=False)\n\n# 读取滑块图和背景图\nwith open('target.png', 'rb') as f:\n    target_bytes = f.read()\n\nwith open('background.png', 'rb') as f:\n    background_bytes = f.read()\n\n# 匹配位置\nres = slide.slide_match(target_bytes, background_bytes)\nprint(f\"滑块位置: {res}\")\n\n# 可视化结果\nbackground = cv2.imdecode(np.frombuffer(background_bytes, np.uint8), cv2.IMREAD_COLOR)\nx1, y1, x2, y2 = res[\"target\"]\n\n# 在背景图上绘制匹配位置\ncv2.rectangle(background, (x1, y1), (x2, y2), (0, 255, 0), 2)\n\n# 显示结果\nplt.figure(figsize=(10, 6))\nplt.imshow(cv2.cvtColor(background, cv2.COLOR_BGR2RGB))\nplt.title(\"滑块匹配结果\")\nplt.axis('off')\nplt.savefig(\"slide_result.jpg\")\nplt.show()\n```\n\n**滑块匹配示例**：\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Ctd align=\"center\">\n      \u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fb.png\" width=\"50\"\u002F>\u003Cbr\u002F>\n      \u003Cstrong>滑块图\u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\">\n      \u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fa.png\" width=\"300\"\u002F>\u003Cbr\u002F>\n      \u003Cstrong>背景图\u003C\u002Fstrong>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n对于没有透明背景的滑块图，可以使用`simple_target`参数：\n\n```python\nres = slide.slide_match(target_bytes, background_bytes, simple_target=True)\n```\n\n#### 算法2：图像差异比较\n\n适用于比较两张图片的不同之处，找出滑块缺口位置：\n\n```python\nimport ddddocr\n\nslide = ddddocr.DdddOcr(det=False, ocr=False)\n\n# 读取带有缺口阴影的图片和完整图片\nwith open('bg.jpg', 'rb') as f:\n    target_bytes = f.read()\n\nwith open('fullpage.jpg', 'rb') as f:\n    background_bytes = f.read()\n\n# 比较差异\nres = slide.slide_comparison(target_bytes, background_bytes)\nprint(res)  # 输出格式：{\"target\": [x, y]}\n```\n\n**图像差异比较示例**：\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Ctd align=\"center\">\n      \u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Fbg.jpg\" width=\"300\"\u002F>\u003Cbr\u002F>\n      \u003Cstrong>带缺口阴影的图片\u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\">\n      \u003Cimg src=\"https:\u002F\u002Fcdn.wenanzhe.com\u002Fimg\u002Ffullpage.jpg\" width=\"300\"\u002F>\u003Cbr\u002F>\n      \u003Cstrong>完整图片\u003C\u002Fstrong>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n### 自定义模型导入\n\nDdddOcr支持导入通过[dddd_trainer](https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fdddd_trainer)训练的自定义模型：\n\n```python\nimport ddddocr\n\n# 导入自定义模型\nocr = ddddocr.DdddOcr(\n    det=False, \n    ocr=False, \n    import_onnx_path=\"mymodel.onnx\", \n    charsets_path=\"charsets.json\"\n)\n\nwith open('test.jpg', 'rb') as f:\n    image_bytes = f.read()\n\nres = ocr.classification(image_bytes)\nprint(res)\n```\n\n## 高级用法\n\n### 批量处理\n\n对大量验证码进行批量处理时，保持OCR实例的复用可以显著提高效率：\n\n```python\nimport ddddocr\nimport os\nimport time\n\n# 初始化OCR对象（只需一次）\nocr = ddddocr.DdddOcr()\n\n# 批量处理目录中的所有图片\ndef batch_process(directory):\n    results = {}\n    \n    start_time = time.time()\n    for filename in os.listdir(directory):\n        if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp')):\n            file_path = os.path.join(directory, filename)\n            \n            with open(file_path, 'rb') as f:\n                image = f.read()\n                \n            # 使用同一个OCR实例处理所有图片\n            result = ocr.classification(image)\n            results[filename] = result\n    \n    end_time = time.time()\n    print(f\"处理 {len(results)} 张图片耗时: {end_time - start_time:.2f} 秒\")\n    return results\n\n# 使用示例\nresults = batch_process(\".\u002Fcaptchas\u002F\")\nfor filename, text in results.items():\n    print(f\"{filename}: {text}\")\n```\n\n### 多线程优化\n\n在多线程环境下使用时，应当为每个线程创建独立的OCR实例：\n\n```python\nimport ddddocr\nimport concurrent.futures\nimport os\n\ndef process_image(file_path):\n    # 每个线程创建自己的OCR实例\n    ocr = ddddocr.DdddOcr()\n    \n    with open(file_path, 'rb') as f:\n        image = f.read()\n    \n    result = ocr.classification(image)\n    return os.path.basename(file_path), result\n\ndef parallel_process(directory, max_workers=4):\n    file_paths = [os.path.join(directory, f) for f in os.listdir(directory) \n                 if f.endswith(('.png', '.jpg', '.jpeg', '.bmp'))]\n    \n    results = {}\n    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:\n        future_to_file = {executor.submit(process_image, file_path): file_path for file_path in file_paths}\n        \n        for future in concurrent.futures.as_completed(future_to_file):\n            filename, result = future.result()\n            results[filename] = result\n    \n    return results\n\n# 使用示例\nresults = parallel_process(\".\u002Fcaptchas\u002F\", max_workers=8)\n```\n\n### 验证码预处理\n\n对于干扰较多的验证码，可以先进行预处理再识别：\n\n```python\nimport ddddocr\nimport cv2\nimport numpy as np\nfrom PIL import Image\nimport io\n\ndef preprocess_captcha(image_bytes):\n    # 转换为OpenCV格式\n    nparr = np.frombuffer(image_bytes, np.uint8)\n    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n    \n    # 灰度化\n    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n    \n    # 二值化\n    _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)\n    \n    # 去除小噪点\n    kernel = np.ones((2, 2), np.uint8)\n    opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)\n    \n    # 转回字节流\n    is_success, buffer = cv2.imencode(\".jpg\", opening)\n    processed_bytes = io.BytesIO(buffer).getvalue()\n    \n    return processed_bytes\n\n# 使用示例\nocr = ddddocr.DdddOcr()\n\nwith open(\"noisy_captcha.jpg\", \"rb\") as f:\n    image_bytes = f.read()\n\n# 预处理验证码\nprocessed_bytes = preprocess_captcha(image_bytes)\n\n# 识别处理后的图片\nresult = ocr.classification(processed_bytes)\nprint(f\"验证码识别结果: {result}\")\n```\n\n## 常见问题\n\n1. **初始化速度慢**  \n   首次初始化DdddOcr对象时会加载模型，可能会比较慢，但只需要初始化一次即可。避免在循环中反复初始化。\n   ```python\n   # 错误的用法\n   for img in images:\n       ocr = ddddocr.DdddOcr()  # 每次都初始化，严重影响性能\n       result = ocr.classification(img)\n   \n   # 正确的用法\n   ocr = ddddocr.DdddOcr()  # 只初始化一次\n   for img in images:\n       result = ocr.classification(img)\n   ```\n\n2. **识别准确率不高**  \n   - 尝试使用另一个OCR模型（设置`beta=True`）\n   - 对于特殊验证码，尝试使用颜色过滤功能\n   - 限定识别字符范围（使用`set_ranges`方法）\n   - 对于透明PNG图片，使用`png_fix=True`参数\n\n3. **GPU加速**  \n   可以通过设置`use_gpu=True`和`device_id`参数来启用GPU加速：\n   ```python\n   ocr = ddddocr.DdddOcr(use_gpu=True, device_id=0)\n   ```\n   使用GPU需确保已安装对应的CUDA版本和onnxruntime-gpu库。\n\n4. **如何处理复杂验证码**  \n   对于复杂的验证码，可以尝试以下步骤：\n   - 先使用目标检测功能定位验证码位置\n   - 对检测到的区域进行裁剪\n   - 应用颜色过滤去除干扰\n   - 使用OCR识别处理后的图片\n\n5. **内存占用过高**  \n   如果在同一程序中需要使用多个功能，建议不要同时初始化多个不同功能的实例，而是根据需要初始化：\n   ```python\n   # 根据需要初始化不同的对象\n   if need_ocr:\n       processor = ddddocr.DdddOcr(ocr=True, det=False)\n   elif need_detection:\n       processor = ddddocr.DdddOcr(ocr=False, det=True)\n   ```\n\n6. **参数冲突问题**  \n   当同时设置多个模式参数时，需注意优先级：\n   - `ocr=True`和`det=True`同时设置时，优先使用目标检测模式\n   - `beta=True`和`old=True`同时设置时，使用Beta模型（`old`当前不生效）\n   - 设置`import_onnx_path`时，`ocr`和`det`参数会被忽略\n\n7. **支持的图片格式**  \n   ddddocr支持多种图片格式：\n   - JPG\u002FJPEG\n   - PNG (带透明通道时可配合`png_fix=True`)\n   - BMP\n   - GIF (仅识别第一帧)\n   \n   对于不常见格式或Base64编码的图片，可以先转换为bytes：\n   ```python\n   # Base64编码图片处理\n   import base64\n   image_bytes = base64.b64decode(base64_str)\n   result = ocr.classification(image_bytes)\n   ```\n\n8. **多线程并发问题**  \n   在多线程环境下使用时，每个线程应当创建独立的OCR实例，否则可能导致识别结果错乱。\n\n## 项目技术支持\n\n本项目基于[dddd_trainer](https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fdddd_trainer)训练所得，训练底层框架为PyTorch，推理底层依赖于[onnxruntime](https:\u002F\u002Fpypi.org\u002Fproject\u002Fonnxruntime\u002F)。\n\n## 使用示例\n\n### 完整的验证码识别流程\n\n```python\nimport ddddocr\nimport cv2\nimport numpy as np\nfrom PIL import Image\nimport io\n\n# 初始化OCR对象\nocr = ddddocr.DdddOcr()\n\n# 读取验证码图片\nwith open(\"captcha.jpg\", \"rb\") as f:\n    image_bytes = f.read()\n\n# 转换为OpenCV格式进行预处理\n# img = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)\n\n# 预处理：灰度化、二值化等\n# gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n# _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)\n\n# 转回字节流\n# is_success, buffer = cv2.imencode(\".jpg\", binary)\n# processed_bytes = io.BytesIO(buffer).getvalue()\n\n# 识别处理后的图片\nresult = ocr.classification(image_bytes)\nprint(f\"验证码识别结果: {result}\")\n```\n\n### 滑块验证码完整示例\n\n```python\nimport ddddocr\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# 初始化滑块检测对象\nslide = ddddocr.DdddOcr(det=False, ocr=False)\n\n# 读取滑块图和背景图\nwith open('target.png', 'rb') as f:\n    target_bytes = f.read()\n\nwith open('background.png', 'rb') as f:\n    background_bytes = f.read()\n\n# 匹配位置\nres = slide.slide_match(target_bytes, background_bytes)\nprint(f\"滑块位置: {res}\")\n\n# 可视化结果\nbackground = cv2.imdecode(np.frombuffer(background_bytes, np.uint8), cv2.IMREAD_COLOR)\nx1, y1, x2, y2 = res[\"target\"]\n\n# 在背景图上绘制匹配位置\ncv2.rectangle(background, (x1, y1), (x2, y2), (0, 255, 0), 2)\n\n# 显示结果\nplt.figure(figsize=(10, 6))\nplt.imshow(cv2.cvtColor(background, cv2.COLOR_BGR2RGB))\nplt.title(\"滑块匹配结果\")\nplt.axis('off')\nplt.savefig(\"slide_result.jpg\")\nplt.show()\n```\n\n## API 服务\n\nDdddOcr 提供了一键启动 API 服务的功能，可以通过 RESTful API 的方式访问 DdddOcr 的所有功能。\n\n### 命令行启动 API 服务\n\n```bash\n# 使用默认配置启动 API 服务\npython -m ddddocr api\n\n# 指定 API 服务配置\npython -m ddddocr api --host 0.0.0.0 --port 8000 --workers 4\n\n# 配置 OCR 功能\npython -m ddddocr api --ocr true --beta true\n\n# 配置目标检测功能\npython -m ddddocr api --ocr false --det true\n```\n\n> **提示**：如果直接运行 `python -m ddddocr.api`，默认会绑定在 `127.0.0.1`，可通过环境变量 `DDDDOCR_HOST` 覆盖。\n\n### API 命令行参数说明\n\n| 参数名 | 类型 | 默认值 | 说明 |\n|-------|------|-------|------|\n| `--host` | 字符串 | 0.0.0.0 | API 服务主机地址（`python -m ddddocr api` 默认） |\n| `--port` | 整数 | 8000 | API 服务端口 |\n| `--workers` | 整数 | 1 | API 服务工作进程数 |\n| `--ocr` | 布尔值 | true | 是否启用 OCR 功能 |\n| `--det` | 布尔值 | false | 是否启用目标检测功能 |\n| `--old` | 布尔值 | false | 是否使用旧版 OCR 模型 |\n| `--beta` | 布尔值 | false | 是否使用 Beta 版 OCR 模型 |\n| `--use-gpu` | 布尔值 | false | 是否使用 GPU 加速 |\n| `--device-id` | 整数 | 0 | GPU 设备 ID |\n| `--show-ad` | 布尔值 | true | 是否显示广告 |\n| `--import-onnx-path` | 字符串 | \"\" | 自定义模型路径 |\n| `--charsets-path` | 字符串 | \"\" | 自定义字符集路径 |\n\n### 使用 Docker 运行 API 服务\n\n#### 构建并运行 Docker 镜像\n\n```bash\n# 构建 Docker 镜像\ndocker build -t ddddocr-api .\n\n# 运行 Docker 容器\ndocker run -d --name ddddocr-api -p 8000:8000 ddddocr-api\n\n# 使用自定义配置运行\ndocker run -d --name ddddocr-api \\\n  -p 8000:8000 \\\n  -e DDDDOCR_OCR=true \\\n  -e DDDDOCR_BETA=true \\\n  -e DDDDOCR_WORKERS=4 \\\n  ddddocr-api\n```\n\n#### 使用 Docker Compose 运行 API 服务\n\n```bash\n# 使用默认配置启动\ndocker-compose up -d\n\n# 使用自定义配置启动\nDDDDOCR_OCR=true DDDDOCR_BETA=true DDDDOCR_WORKERS=4 docker-compose up -d\n```\n\n### API 接口说明\n\nAPI 服务提供了以下接口：\n\n#### 1. 文字识别接口 (OCR)\n\n```\nPOST \u002Focr\n```\n\n请求体：\n\n```json\n{\n  \"image\": \"图片的Base64编码字符串\",\n  \"probability\": false,\n  \"colors\": [],\n  \"custom_color_ranges\": null\n}\n```\n\n响应：\n\n```json\n{\n  \"result\": \"识别到的文字\",\n  \"processing_time\": 0.123\n}\n```\n\n> **注意**：当 `probability=true` 时，API 会返回 `result` 为一个字典，包含 `charsets` 与 `probability` 字段，结构与本地 `classification(probability=True)` 一致。\n\n#### 2. 目标检测接口\n\n```\nPOST \u002Fdet\n```\n\n请求体：\n\n```json\n{\n  \"image\": \"图片的Base64编码字符串\"\n}\n```\n\n响应：\n\n```json\n{\n  \"result\": [\n    [x1, y1, x2, y2],\n    ...\n  ],\n  \"processing_time\": 0.123\n}\n```\n\n#### 3. 滑块匹配接口\n\n```\nPOST \u002Fslide_match\n```\n\n请求体：\n\n```json\n{\n  \"target_image\": \"目标图片的Base64编码字符串\",\n  \"background_image\": \"背景图片的Base64编码字符串\",\n  \"simple_target\": false,\n  \"flag\": false\n}\n```\n\n响应：\n\n```json\n{\n  \"result\": {\n    \"target_x\": 0,\n    \"target_y\": 0,\n    \"target\": [x1, y1, x2, y2]\n  },\n  \"processing_time\": 0.123\n}\n```\n\n#### 4. 滑块比较接口\n\n```\nPOST \u002Fslide_comparison\n```\n\n请求体：\n\n```json\n{\n  \"target_image\": \"目标图片的Base64编码字符串\",\n  \"background_image\": \"背景图片的Base64编码字符串\"\n}\n```\n\n响应：\n\n```json\n{\n  \"result\": {\n    \"target\": [x, y]\n  },\n  \"processing_time\": 0.123\n}\n```\n\n#### 5. 设置字符范围接口\n\n```\nPOST \u002Fset_charset_range\n```\n\n请求体：\n\n```json\n{\n  \"charset_range\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"]\n}\n```\n\n响应：\n\n```json\n{\n  \"result\": \"字符范围设置成功\",\n  \"charset_range\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"],\n  \"processing_time\": 0.123\n}\n```\n\n\n#### 6. 健康检查接口\n\n```\nGET \u002Fhealth\n```\n\n响应：\n\n```json\n{\n  \"status\": \"ok\",\n  \"timestamp\": 1628765432.1234\n}\n```\n\n#### 文件上传接口\n\n所有上述接口都支持通过表单上传文件的方式提交请求。例如：\n\n```\nPOST \u002Focr\u002Ffile\n```\n\n可以通过表单字段上传图片文件。\n\n### API 客户端示例\n\n#### Python 示例 (Base64编码方式)\n\n```python\nimport requests\nimport base64\n\n# 读取图片文件并Base64编码\nwith open(\"captcha.png\", \"rb\") as f:\n    img_base64 = base64.b64encode(f.read()).decode()\n\n# 发送OCR请求\nurl = \"http:\u002F\u002Flocalhost:8000\u002Focr\"\nresponse = requests.post(url, json={\"image\": img_base64})\n\n# 处理响应\nresult = response.json()\nprint(f\"识别结果: {result['result']}\")\n```\n\n#### Python 示例 (文件上传方式)\n\n```python\nimport requests\n\n# 准备文件\nfiles = {\"file\": open(\"captcha.png\", \"rb\")}\n\n# 发送OCR请求\nurl = \"http:\u002F\u002Flocalhost:8000\u002Focr\u002Ffile\"\nresponse = requests.post(url, files=files)\n\n# 处理响应\nresult = response.json()\nprint(f\"识别结果: {result['result']}\")\n```\n\n### Docker 环境变量配置参考\n\n| 环境变量名 | 默认值 | 说明 |\n|-----------|-------|------|\n| `DDDDOCR_HOST` | 0.0.0.0（CLI 默认）\u002F 127.0.0.1（直接运行 `python -m ddddocr.api` 默认） | API 服务主机地址 |\n| `DDDDOCR_PORT` | 8000 | API 服务端口 |\n| `DDDDOCR_WORKERS` | 1 | API 服务工作进程数 |\n| `DDDDOCR_OCR` | true | 是否启用 OCR 功能 |\n| `DDDDOCR_DET` | false | 是否启用目标检测功能 |\n| `DDDDOCR_OLD` | false | 是否使用旧版 OCR 模型 |\n| `DDDDOCR_BETA` | false | 是否使用 Beta 版 OCR 模型 |\n| `DDDDOCR_USE_GPU` | false | 是否使用 GPU 加速 |\n| `DDDDOCR_DEVICE_ID` | 0 | GPU 设备 ID |\n| `DDDDOCR_SHOW_AD` | true | 是否显示广告 |\n| `DDDDOCR_IMPORT_ONNX_PATH` | \"\" | 自定义模型路径 |\n| `DDDDOCR_CHARSETS_PATH` | \"\" | 自定义字符集路径 |\n\n## 许可证\n\n本项目采用MIT许可证，详情请参阅[LICENSE](https:\u002F\u002Fgithub.com\u002Fsml2h3\u002Fddddocr\u002Fblob\u002Fmaster\u002FLICENSE)文件。 \n## 输入与输出校验说明\n\n- **图片合法性**：所有 Base64 与文件上传都会做尺寸、格式与大小校验（默认上限 8192 KB、最长边 4096px，可在实例化 `DdddOcr(max_image_bytes=..., max_image_side=...)` 时自定义），异常时返回 400。\n- **允许格式**：PNG \u002F JPEG \u002F JPG \u002F WEBP \u002F BMP \u002F GIF \u002F TIFF。\n- **输入类型**：本地调用支持 `bytes\u002Fbytearray`、Base64 字符串、文件路径或 `PIL.Image`。\n- **类型约束**：`DdddOcr` 的公开方法会校验布尔\u002F整数参数，`FastAPI` 层也通过 Pydantic 验证请求体，错误会带具体字段。\n- **统一异常**：核心库新增 `DdddOcrInputError` \u002F `InvalidImageError`，API 会把这些异常映射为 400，方便调用方处理。\n- **响应结构**：HTTP 接口现有明确的 `response_model`，文档 (`\u002Fdocs`) 中可直接查看字段含义。\n- **模式提示**：在 `det=True` 模式下调用 `classification` 会抛出 “当前识别类型为目标检测”。\n\n## 示例库\n\n仓库新增 `examples\u002F` 目录，覆盖本地调用、目标检测和 HTTP 客户端等典型场景：\n\n- `basic_ocr.py`：最小 OCR 示例，可演示概率输出与颜色过滤。\n- `detector.py`：演示如何用 `det=True` 模式返回所有检测框。\n- `api_client.py`：演示如何向 `python -m ddddocr api` 服务发送 JSON 请求。\n- `generate_basic_ocr_cases.py`：生成基础 OCR 测试用例图片。\n\n详细说明见 `examples\u002FREADME.md`，可结合 README 其他章节快速起步。\n","DdddOcr 是一个简单易用的通用验证码识别Python库，支持多种类型的验证码识别。其核心功能包括文字识别、目标检测以及滑块验证码处理，并且允许用户导入自定义训练模型以适应特定需求。该库设计时注重“最简依赖”，旨在减少用户的配置和使用成本，同时提供高性能的API接口。DdddOcr适用于需要自动处理各种形式验证码的应用场景，比如网站自动化测试、数据抓取等任务中遇到的图像验证问题。此外，它还支持多线程优化和批量处理，进一步提升了处理效率。",2,"2026-06-11 03:35:01","high_star"]