From 00e8ab530889072cc3e89c7dc2a7ff4f6846a4cc Mon Sep 17 00:00:00 2001 From: CNWei Date: Mon, 10 Aug 2026 19:56:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20ddddocr-rs=20=E5=AE=8C=E6=88=90=20core/?= =?UTF-8?q?ort/tract2=20=E8=A7=84=E8=8C=83=E6=95=B4=E6=94=B9=E4=B8=8E?= =?UTF-8?q?=E5=8F=91=E5=B8=83=20=20=20=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - core:内置官方字符集(OLD/BETA)与 ModelMetadata::from_builtin_* 构造器 - ort:导出 Session、实现 Info、修正 cuda feature 接线、共享推理工具 - tract2:包名更名(原 ddddocr-tract 已被占用)并完成规范整改 - 集成测试按领域拆分(ocr / det / slide / common / api_surface) - 发布准备:Cargo.toml 元数据、workspace 版本 0.2.4、LICENSE/ NOTICE、README 模型下载说明 --- Cargo.toml | 4 +- NOTICE | 4 +- README.md | 144 ++- code3.png | Bin 5715 -> 0 bytes ddddocr-core/src/error.rs | 2 +- ddddocr-core/src/lib.rs | 2 +- ddddocr-core/src/ocr.rs | 1 + ddddocr-core/src/ocr/builtin.rs | 1038 +++++++++++++++++ ddddocr-core/src/ocr/metadata.rs | 31 + ddddocr-core/src/traits.rs | 2 +- ddddocr-ort/Cargo.toml | 28 +- ddddocr-ort/src/det.rs | 2 +- ddddocr-ort/src/det/session.rs | 45 +- ddddocr-ort/src/lib.rs | 17 +- ddddocr-ort/src/loader.rs | 4 +- ddddocr-ort/src/loader/error.rs | 57 +- ddddocr-ort/src/loader/metadata.rs | 112 +- ddddocr-ort/src/loader/model.rs | 57 +- ddddocr-ort/src/ocr/session.rs | 238 ++-- ddddocr-ort/src/runtime.rs | 41 + ddddocr-ort/src/types.rs | 3 + ddddocr-ort/tests/api_surface.rs | 76 ++ ddddocr-ort/tests/char_slice.rs | 600 ---------- ddddocr-ort/tests/common/mod.rs | 25 + ddddocr-ort/tests/det.rs | 33 + ddddocr-ort/tests/ocr.rs | 56 + ddddocr-ort/tests/ocr_test.rs | 253 ---- ddddocr-ort/tests/slide.rs | 52 + ddddocr-tract/Cargo.toml | 26 - ddddocr-tract/src/det.rs | 1 - ddddocr-tract/src/det/session.rs | 52 - ddddocr-tract/src/error.rs | 8 - ddddocr-tract/src/lib.rs | 11 - ddddocr-tract/src/ocr/session.rs | 153 --- ddddocr-tract/src/types.rs | 4 - ddddocr-tract/tests/char_slice.rs | 600 ---------- ddddocr-tract/tests/ocr_test.rs | 251 ---- ddddocr-tract2/Cargo.toml | 22 + .../src/ocr.rs => ddddocr-tract2/src/det.rs | 0 ddddocr-tract2/src/det/session.rs | 44 + ddddocr-tract2/src/lib.rs | 22 + .../src/loader.rs | 2 +- .../src/loader/error.rs | 38 +- .../src/loader/metadata.rs | 108 +- .../src/loader/model.rs | 64 +- ddddocr-tract2/src/ocr.rs | 1 + ddddocr-tract2/src/ocr/session.rs | 174 +++ ddddocr-tract2/src/runtime.rs | 25 + ddddocr-tract2/src/types.rs | 7 + ddddocr-tract2/tests/api_surface.rs | 74 ++ ddddocr-tract2/tests/common/mod.rs | 25 + ddddocr-tract2/tests/det.rs | 33 + ddddocr-tract2/tests/ocr.rs | 55 + ddddocr-tract2/tests/slide.rs | 52 + samples/{huatu.png => background1.png} | Bin samples/{kenyuan.jpg => background2.jpg} | Bin samples/{hua.png => target1.png} | Bin samples/{ken.jpg => target2.jpg} | Bin 58 files changed, 2542 insertions(+), 2237 deletions(-) delete mode 100644 code3.png create mode 100644 ddddocr-core/src/ocr/builtin.rs create mode 100644 ddddocr-ort/src/runtime.rs create mode 100644 ddddocr-ort/tests/api_surface.rs delete mode 100644 ddddocr-ort/tests/char_slice.rs create mode 100644 ddddocr-ort/tests/common/mod.rs create mode 100644 ddddocr-ort/tests/det.rs create mode 100644 ddddocr-ort/tests/ocr.rs delete mode 100644 ddddocr-ort/tests/ocr_test.rs create mode 100644 ddddocr-ort/tests/slide.rs delete mode 100644 ddddocr-tract/Cargo.toml delete mode 100644 ddddocr-tract/src/det.rs delete mode 100644 ddddocr-tract/src/det/session.rs delete mode 100644 ddddocr-tract/src/error.rs delete mode 100644 ddddocr-tract/src/lib.rs delete mode 100644 ddddocr-tract/src/ocr/session.rs delete mode 100644 ddddocr-tract/src/types.rs delete mode 100644 ddddocr-tract/tests/char_slice.rs delete mode 100644 ddddocr-tract/tests/ocr_test.rs create mode 100644 ddddocr-tract2/Cargo.toml rename ddddocr-tract/src/ocr.rs => ddddocr-tract2/src/det.rs (100%) create mode 100644 ddddocr-tract2/src/det/session.rs create mode 100644 ddddocr-tract2/src/lib.rs rename {ddddocr-tract => ddddocr-tract2}/src/loader.rs (63%) rename {ddddocr-tract => ddddocr-tract2}/src/loader/error.rs (64%) rename {ddddocr-tract => ddddocr-tract2}/src/loader/metadata.rs (50%) rename {ddddocr-tract => ddddocr-tract2}/src/loader/model.rs (52%) create mode 100644 ddddocr-tract2/src/ocr.rs create mode 100644 ddddocr-tract2/src/ocr/session.rs create mode 100644 ddddocr-tract2/src/runtime.rs create mode 100644 ddddocr-tract2/src/types.rs create mode 100644 ddddocr-tract2/tests/api_surface.rs create mode 100644 ddddocr-tract2/tests/common/mod.rs create mode 100644 ddddocr-tract2/tests/det.rs create mode 100644 ddddocr-tract2/tests/ocr.rs create mode 100644 ddddocr-tract2/tests/slide.rs rename samples/{huatu.png => background1.png} (100%) rename samples/{kenyuan.jpg => background2.jpg} (100%) rename samples/{hua.png => target1.png} (100%) rename samples/{ken.jpg => target2.jpg} (100%) diff --git a/Cargo.toml b/Cargo.toml index ece210e..8a427a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,11 @@ resolver = "2" members = [ "ddddocr-core", "ddddocr-ort", - "ddddocr-tract", + "ddddocr-tract2", ] [workspace.package] -version = "0.2.1" +version = "0.2.4" edition = "2024" license = "MIT OR Apache-2.0" diff --git a/NOTICE b/NOTICE index 4266eac..f5be3e1 100644 --- a/NOTICE +++ b/NOTICE @@ -3,4 +3,6 @@ Copyright 2026 CNWei This product includes software developed by: - sml2h3 (ddddocr) - Model weights and original logic. -- Sonos (tract) - ONNX inference engine. \ No newline at end of file +- Sonos (tract) - ONNX inference engine. +- pyke.io (ort) - Rust bindings for ONNX Runtime. +- Microsoft (ONNX Runtime contributors) - ONNX inference engine. diff --git a/README.md b/README.md index 9ba3654..757d70f 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,135 @@ # ddddocr-rs -带带弟弟 OCR (ddddocr) 的 Rust 移植版。高性能、低占用,支持多种验证码识别与检测。 +[带带弟弟 OCR(ddddocr)](https://github.com/sml2h3/ddddocr) 的 Rust 移植版:提供验证码 OCR 识别、目标检测与滑块匹配能力。核心库与推理引擎解耦,同一套 API 可切换 [Tract](https://github.com/sonos/tract) 或 [ONNX Runtime](https://onnxruntime.ai/) 后端。 -🧩 滑块识别算法核心知识点总结 -本项目实现了两种核心匹配模式,其底层逻辑与 OpenCV 的对齐情况如下: +## 架构 -1. 匹配模式对比 (Match Modes) - |**模式**|**算法原理**|**适用场景**|**备注**| - |---|---|---|---| - |**边缘模式** (Edge-based)|基于 **Canny 边缘检测** 提取轮廓后再进行匹配。|**推荐方案** - 。适用于绝大多数拼图滑块。|天然免疫拼图周边的透明/黑色留白干扰,坐标最精准。| - |**简单模式** (Simple/Gray)|直接基于 **灰度像素值** 进行归一化互相关计算。|适用于无明显边缘、靠颜色差异识别的场景。|对背景和透明边框敏感,可能存在重心偏移。| +项目为 Cargo workspace,包含三个 crate: -2. 数学公式差异 (NCC vs. CCOEFF) - 在简单模式下,本项目采用的是 归一化互相关 (NCC),对应 OpenCV 中的 TM_CCORR_NORMED。 +| crate | 说明 | +|---|---| +| `ddddocr-core` | 引擎无关的核心库:OCR / 目标检测 / 滑块匹配、模型元数据与图像预处理 | +| `ddddocr-ort` | ONNX Runtime 推理后端(可选 `cuda` feature 启用 GPU 加速) | +| `ddddocr-tract2` | Tract(纯 Rust)推理后端 | -逻辑对齐:Rust 的 match_template 结果与 Python cv2.TM_CCORR_NORMED 完全一致。 +`ddddocr-core` 通过 `traits::InferenceEngine` / `OcrEngine` / `DetEngine` 抽象推理能力,由 `ddddocr-ort` / `ddddocr-tract2` 实现,业务代码只依赖核心库接口即可。 -关于偏移:若拼图原始图片(Target)四周包含大量的透明留白: +## 快速开始 -CCORR (本项目):会将留白视为图像的一部分,计算出的是整张图片框的中心。 +在 Cargo.toml 中添加: -CCOEFF (OpenCV 默认):会自动进行“均值中心化”,在一定程度上能削弱留白的影响。 +```toml +[dependencies] +ddddocr-core = "0.2" +ddddocr-ort = "0.2" # 或 ddddocr-tract2 = "0.2" +``` -最佳实践:若发现坐标有固定位移,建议优先切换至 边缘模式,或对滑块图进行 Bounding Box 裁剪 后再匹配。 +核心库自带一个不依赖真实模型的演示示例(用假引擎演示完整调用链): -3. 图像预处理一致性 +```bash +cargo run -p ddddocr-core --example quick_start +``` - 为确保识别精度,本项目在 Rust 中完美复刻了 Python OpenCV 的预处理链路: +真实推理需要自行准备 ONNX 模型文件(crate 包内不包含模型)。以 ORT 后端为例: -- **灰度化权重**:采用 OpenCV 标准感光公式 $0.299R + 0.587G + 0.114B$。 +```rust +use ddddocr_core::traits::{Info, Loader}; +use ddddocr_core::{ModelMetadata, Normalization, Ocr, Resize}; -- **Alpha 处理**:在将 PNG 转为 RGB 时,自动将透明区域填充为黑色,确保与 PIL (Python Imaging Library) 行为一致。 +// 1. 构建会话(等价写法:ddddocr_tract2::loader::ModelLoader) +let session = ddddocr_ort::loader::ModelLoader::default() + .build_for_path("models/common.onnx")?; -- **坐标定义**:所有返回坐标均为匹配区域的 **几何中心点** $(x + w/2, y + h/2)$。 +// 2. 组装 OCR 运行时 +let metadata = ModelMetadata::from_static_slice( + &["a", "b"], // 字符集 + false, // 非单字模型 + Resize::DynamicWidth(64), // 高度固定 64、宽度等比缩放 + 1, // 灰度单通道 + Normalization::MinusOneToOne, +); +let ocr = ddddocr_ort::OcrRuntime::new(session, metadata); -💡 开发者建议: +// 3. 识别图片 +let result = Ocr::builder().build_with(&ocr).predict(&image)?; +println!("识别结果: {}", result); +``` -如果识别结果在 $X$ 轴上有大约 $10px$ 左右的固定误差,通常是因为滑块原图自带了透明边距(留白)。此时请确保 -simple_target=false。该模式会通过 Canny 边缘检测 提取轮廓特征,能自动锁定拼图实体并忽略背景留白的像素干扰。 -鸣谢 (Credits) +目标检测与滑块匹配类似:`Detector::new(&engine).predict(&image)` 返回检测框列表;`Slider::new().slide_match(target, background, simple_target)` 返回匹配坐标与置信度。 -- 本项目是 [ddddocr](https://github.com/sml2h3/ddddocr) 的 Rust 移植版本,原作者为 sml2h3。衷心感谢原作者对 OCR 社区做出的杰出贡献。 -- 推理引擎基于 [tract (Sonos)](https://github.com/sonos/tract)。感谢其为 Rust 生态提供的轻量级推理方案。 \ No newline at end of file +## 模型下载 + +OCR / 目标检测需要 ONNX 模型文件。官方模型位于 [ddddocr 仓库 `ddddocr/` 目录](https://github.com/sml2h3/ddddocr/blob/master/ddddocr/),下载后放入仓库根目录的 `models/` 文件夹: + +| 文件 | 大小 | 用途 | 直链 | +|---|---|---|---| +| `common.onnx` | 约 51.6 MB | 新版 OCR 模型(默认) | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common.onnx) | +| `common_det.onnx` | 约 19.2 MB | 目标检测模型 | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common_det.onnx) | +| `common_old.onnx` | 约 13 MB | 旧版 OCR 模型 | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common_old.onnx) | + +> 注意:`ddddocr-tract2` 不支持旧版模型 `common_old.onnx`,请使用 `common.onnx`。 +> +> 字符集配对:`common.onnx` 对应内置 Beta 字符集(`Charset` / `ModelMetadata::from_builtin_beta`,归一化 `MinusOneToOne`);`common_old.onnx` 对应旧版字符集(`from_builtin_old`,归一化 `ZeroToOne`)。 +> +> 仓库测试使用的 `common_sml2h3_f32.onnx`、`common_huashi666_i64.onnx` 为社区转换的 f32 / i64 变体模型(与 `common.onnx` 同源),不在上述官方目录中,需自行获取。 + +## 字符集与内置默认值 + +OCR 模型的字符集(token 列表)是模型的一部分:字符 `i` 对应模型输出 logits 的第 `i` 列,必须与模型训练时一致,否则识别结果会错位。 + +字符集有两种提供方式: + +- 通过模型元数据 JSON 的 `charset` 字段(`Metadata::from_json_str` / `from_json_bytes` 自动解析); +- 代码内显式指定:`ModelMetadata::from_static_slice(&["", "a", "b"], ...)` 或 `Charset::new(...)`。 + +`ddddocr-core` 内置官方模型的默认字符集(旧版 `CHARSET_OLD` 与 Beta `CHARSET_BETA`),作为免配置的快速通道。字符集数据独立存放在 `ddddocr-core/src/ocr/builtin.rs` 私有模块中(与业务逻辑分离),通过 `ModelMetadata` 的公开构造方法使用: + +```rust +use ddddocr_core::{ModelMetadata, Normalization, Resize}; + +// 官方旧版模型配套 +let meta = ModelMetadata::from_builtin_old( + false, + Resize::DynamicWidth(64), + 1, + Normalization::ZeroToOne, +); + +// 官方 Beta 模型配套 +let meta = ModelMetadata::from_builtin_beta( + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, +); +``` + +数据内置于代码,不依赖外部文件。若使用自有模型,请仍以元数据 JSON 或 `from_static_slice` 指定匹配的字符集。 + +## 滑块匹配核心知识点 + +项目实现两种匹配模式,底层逻辑与 OpenCV 对齐: + +| 模式 | 算法原理 | 适用场景 | 备注 | +|---|---|---|---| +| 边缘模式(Edge-based) | 基于 Canny 边缘检测提取轮廓后匹配 | **推荐方案**,适用于绝大多数拼图滑块 | 天然免疫拼图周边透明/黑色留白干扰,坐标最精准 | +| 简单模式(Simple/Gray) | 基于灰度像素值做归一化互相关(NCC) | 无明显边缘、靠颜色差异识别的场景 | 对背景和透明边框敏感,可能存在重心偏移 | + +关键点: + +- 简单模式采用归一化互相关(NCC),与 OpenCV 的 `TM_CCORR_NORMED` 完全一致。 +- 若拼图原图四周带透明留白,本项目会将留白计入整张图片框中心;OpenCV 默认的 CCOEFF 会做均值中心化削弱留白影响。 +- 图像预处理与 Python 链路保持一致:灰度权重采用 OpenCV 标准感光公式 `0.299R + 0.587G + 0.114B`;PNG 转 RGB 时透明区域填充为黑色;返回坐标为匹配区域的几何中心 `(x + w/2, y + h/2)`。 + +> 若识别结果在 X 轴上有约 10px 固定误差,通常是滑块原图自带透明边距所致。此时请确保 `simple_target = false`,边缘模式会自动锁定拼图实体并忽略留白干扰。 + +## 致谢 + +- [sml2h3 (ddddocr)](https://github.com/sml2h3/ddddocr) - 模型权重与原始逻辑。 +- [Sonos (tract)](https://github.com/sonos/tract) - 纯 Rust ONNX 推理引擎。 +- [pyke.io (ort)](https://github.com/pykeio/ort) - ONNX Runtime 的 Rust 绑定。 +- [Microsoft (ONNX Runtime)](https://onnxruntime.ai/) - ONNX 推理引擎。 + +## License + +`MIT OR Apache-2.0`,许可证文本见仓库根目录的 `LICENSE-MIT` 与 `LICENSE-APACHE`。 diff --git a/code3.png b/code3.png deleted file mode 100644 index ac30b0bca790308bb6bb7110b8c6e4ff21023ec3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5715 zcmWldcRbbKAICrT%81AenGxC9<03P3tx)z(x#qq0CLw$!Bv+E8n~>~1ulcjd-h1!O z@9?;nKd#69oO9mq_v`h1ooGEBHF8o$QV4>`HPlt$;I9{W3lI~6-wC6f+z>>^sG*`{ zfcm`o!cWf(J9JG#qCuR{JRsZA)PR5SRsc3H$%1g>&Ubpjlc4cx4#oV`iF)J>qk18^ z(<|bqgp@XS9ci!`sf-RU9GP;18^|T~IdXNheoQL55tqXs-U%nbF{zG7_&d$IHtFo; zb2b_{eVkq)I^oeXDK}P(Jg%n0fkLmb*L)}(h&{Z*-Q8W!*cjV;;49bP-;b*1OD3g@ ziO4cEG-T)DiNaR>tF^YV@$qM1U~qJGb#P>iBXlnLgvA)}`TR8-((&<;>geqB@zhP* z9;W9@)_l7);gQZ?Vq$dvxTT zs?ELPDc#)CGWqu*k_l;;ml<%xa4+!0>eq`3_h%Qmx|vV>{A6mjx3<0qm6eptZj2T~ zP8e!c(8tn7WiubwRNmn&+9iOT)uP-*R#$cTOg5sXz(o>77(PnF^E{Iz(|#l%2A( zvwNLOWX-et-iC(as&i6nuCJ{%rdR~F&wFim_ViH7%gaMh4!nH_<>Mp#cWlgbVQFb@ z7t2Zny{Pe}B_}6`UT8U}sS(+VFu;_R+38}eN=y^e)5+4bBde=r@$vDyWQc`@h2O@- zsp{*~NVrbLz8){_b5K=P<$d@Nf5y~AT3VWp%frZsZftDq%{sk1Vq|1+@Pk$!T2wQ4 zz^eO`IBKVX=)r3Qg6j3_*RoS*XTIOQeXAcCN$LNr!^25U5?@wb&Ftjlw6eb5RN=8~ zDUohf^qh@48oa1zXu{sUC2m`Euij}S+u7U0h0eTmbaduc`m%o%6h!Id;<4jXM1@iO zTUp^9FjiEAE-o)u-yw>hSGaRgut!^5L-S3Kw~4`^idmoHhA2i6Zc1q9--77Hca<(8-)Po!ohNxU6uU z239k-x%m_y7iV{G?>;Om;pFV>zxsN``^lPV#~$E2yu8GHc3bXh=;={~bdsCxP!r>G z3JE3rFyQljaEJ82goOHD13ud5_wUihOA)O+5)vP=DT#?nW8>qlo%H|XiihWMnm-n^ zbH#P7yOgLs%y+f&^t>Y~D#{jKzv|gIi?Fn|#OiW>Yj^7BA z%E}&tM+!R1WAru)7bla$ak9pb_Zw~|0UyoasjTZ%+dppPB&9vhcZVh~Ynw~1`iEW9wn+4Bf zqrUW;6-(2mXJuVJZDov$EYmDsUvG>cgWlBZRk|;dp3YJRsRK#7`}!}!SVaZ@bfdV3 zm_7VMN=nk+o;#WydaR7??2N%G6Hf~{xwvp1Px(D6s4FZK`f7w(rDb7x`Yt9$!_bh{ z#`E;-j5-IdakMe242tC@$=tl^`QOx(`FFXZ=h|R=bWBZ6Q?K^-_D~{I0?JP9em~o7 zVRm+0I-ez#98O^~wY80nFy3TMPHt|&HMwY&Ml&5Ll=S)2r%%hlI-80;mUUz=cA8L2 zX%4&sqM|fJ6wHc&f%4|4S%S#Ak`h|!42rs|!-5C-g@sf=#MHI5n|U(*anrjAfr^&1 zLWM!sfy{Egcbb}-*uoVb(kTN0$6&}X#s#fFf8{X&2$@3L9B(hL*{(FvSQv71EaKz@ z^)tA%RDwS4iLJf8$hPm98(G8nI1_a=eo0A5bxkRFltel?(5aJw%qtZRStTWMto^rrkA za%LE-4LGM_V$!N>qv6r{Qd5)hZ0DTk3&`~uJ5fMv~ zw4ICnp82&QOl%7y14Hz}g00JBrI!w#lOX75PA)EXAZJ@ChlhvHOPpzKN-XLES?aDY zxBI52DI;JwN$ufUDS}q^_K}G!ko?t&O=T#8zkamX!4(51fZi^*z7}JgU0%j^+5Qhk zMoJpmVEM&~4Z7KOs$IW}gpIQ^X<}mHhvCuDXz)G4mlsQq>u@01%Yy-6EkCRF;BYt< zEo}r5tAB!ncHWTlXIUR=@2ZUc`MEi&d-vY+pi#K2{yR9hxVQ-^DN$d(u&Jo2;UNU- zyu7>$pFgaAM2iSW+tMU>F}$QqDHjfE=zlUBwR3b7Ik2h%v=%gISXLH$M>-n)KJ)4z zS13&zbvR_a8y|ELHlk)}$(Bq6`TF`6TDQC-z)~Udx%XEw#l-`MIlh4p2nYz&H8dJN z3YhgyOvGl$Ao~kKJd`K;Mn~JTNg`mfXDivfyu6CfpVM1gTc@&B`qixu=Z7`T)`Nnq zh~~hf1_ouA!GOG|^d#y0C;+Ufrly9MkMAo6=It#JH!VoVokW6% zhiBkpWo1Rr#H0*^;c_U01>W;nxb46B$|7uFwOMAn8n3>@u0pr=;J}kv$~}B4_xty+ zMMa5ewm{=oHa1i=G)OpN;CY{oEr2cm=B$8aSqet0;96K%@ZKSny}sBlmR=xhm_^Jq zN7JlqZAHSeQinp8XFR17!Rdl=rwrzoM1S}YzOmuLczxL1)JfM=)AxkQXlDrcH0DXPFZQ8x>|hP zhDJYUAev8}JV{;j76xCrv%eqq{2@9eo+=bzl7W#?zfw$myqc5K0~idpB=#F1VPjJh z*gHE2W&;{r|~GB4(i0*4Ez1$vB{f+*0J_NAkK@AJE)>M;i@z zl(LGe=pka$d^#Wy85tR|;$WDg!H*Q?E;LgRbjcqY8rnNJ7#>DMDR`mfpk!*w_~*|b z)HAN2pld0fB9;3}K|u?e+Q5N|v<5R;aXN!wv1N@^E#Si~g~ z%p`@JOBjK6Atae^SgN_X`D>uRmKGU!C@4L)wT{LjQIceS*qAE2UoCe zxL81t@@y&Hb?*ZyWLEa31hxgI zQ~IUmqR2V3NC7^;+Eto_FW`XtOHMn}&wQC$b~X`UXzd^UDwyCvF!r zL<*K@@UL09xlyCK%T4|tuQ%&idU8K?+h3eu6 zrf`z@1~sww{B8k0NzlwG9N$#e(Rt$GA^KlZ((aVsc2;&a9!LnVEQAr+D2>)3^BX#( zK^|B{TSrIelWZ${AJE)rpCtxRh1+e5d+A0$`y5sL{biF?IjI3RaDd4=Jv~iLP5r{J zjX(&2{-84$gCCukMR4Wzyg3*vcjJiv`00}-K=CDQf#j4FeRILM#rAo0AUw|?=A(l| zSBkf%B=f?~Y}3J|+C86ez_q^HX-4yKS766Tm)L7B0f9_YL&KI=w!#&PAT2Ct*oiPC zb}rt4YjbOBKN;k)omMR8ck~cP5d=NqH0{_fa9Fl3F0rexes}8I_e@VsPwRq@`qmE@ z0FT%X#_K5LArRGP= zNXhsPjqA>azCJ}FB{OtBD+Jxk47!q<3c3zpTXSA|*+UvabPojq zYXXrt_48-^nV-}PdrA8G`Zo$+8z95S&wrOIv#R(}vZmWgFMD`I1iOR;or#Hwy1F_9 zF-syK->+C2#p+ilyrx>SIm*Pc&q&&55Sf}o52%YM>XMqOF$C1fi%LfkX2(g zsxFgmH%#G75t-nqU-pk*zku;$|4UIp`p+{>2T#7i_GPO%g*$9d)rgHaf>fHC`Zgpa zM76BKu9HqoLITE@3xpdD)H_6ckAiefbwOuUmz2X;LLSFnMICcRMweFWLkGlK=64TMqVOe6z zo~WMi;R8M->AgX39(ZcU$;rtkBf}JQK0Zz7!Y?iT>4DY*fK1Px-3Cb_&#(a8^CYv7 zM&Oc=kZ8jd^9=eg&%9@UXL25g!?M0a^i54oRd>nHjHSrN}epUuH`LIM>x)?WsJeg6`%vbh;yz}ND} zuJes1BJN4p({zcfoE!p3&&Vk9&mR$hz)IPDU8V+vU4bj~CrG1a8r%@eVWAl?@;A}z z)4RXpn{L#QoIz9ipj z3+5?ku&m#jta6YO**RU#+{cGwhJaQ@nC5@a`Hqf^23qvDz<-gyTH=ZZ++;K@gc1=F z7T(03^NnI+N=j_Ws}XR`<92r71iAspBZ#6?e}p}ws%pVZ1K+ckiK^(}9C8+qfBfJ< zv@r>`+qWl2n~mxV*qWT2oFr<84Okwu!+!^h#X9MQ$l!TwO-Qv4r3#qzWK~vvN)fEO zJvcbnJ3W7M8}`D9$KwxpFfrn`0%wieLr?g91#-$ntf5Ha4J2 zd7xyHfftf|e0<;;$Ks6S`bt#v^l!m^lsQ+VdBO6fD>29plT}C?5bjg7kHXKZCW0Ji z9jm-IzlPu)2b!6gCEh^!<%Yw`>Z(#efZPo{g2`B>hB zVT_eIskpBU*B4-5DxoKh}2a5ldYRAPc!`Y>SDB&D4kBAw6$Ro&$&Q$jCAIZ?Fsp z%(vJAVY#*^a{nH}kWxJdz7#dS>HW_|;`?9f`d`-yt41YFhLpbdh-Pg|M_t5L5oJ3H Y#1nkB6_=kB!DTU|p{k?u8)g~$f2FnhEdT%j diff --git a/ddddocr-core/src/error.rs b/ddddocr-core/src/error.rs index 06360f8..b2a84d1 100644 --- a/ddddocr-core/src/error.rs +++ b/ddddocr-core/src/error.rs @@ -165,7 +165,7 @@ mod tests { #[test] fn new_wraps_third_party_error() { - let io_err = std::io::Error::new(std::io::ErrorKind::Other, "boom"); + let io_err = std::io::Error::other("boom"); let err = DdddError::new(io_err); assert!(matches!(err, DdddError::Other(_))); } diff --git a/ddddocr-core/src/lib.rs b/ddddocr-core/src/lib.rs index 947d4a3..d0c344b 100644 --- a/ddddocr-core/src/lib.rs +++ b/ddddocr-core/src/lib.rs @@ -2,7 +2,7 @@ //! //! `ddddocr-rs` 的核心库:提供与具体推理引擎解耦的 OCR 识别、目标检测(det)与滑块匹配(slide)能力。 //! 推理能力由 [`traits::InferenceEngine`]、[`traits::OcrEngine`]、[`traits::DetEngine`] 抽象, -//! 由 `ddddocr-tract`、`ddddocr-ort` 等引擎 crate 实现。 +//! 由 `ddddocr-tract2`、`ddddocr-ort` 等引擎 crate 实现。 //! //! 完整可运行示例见 `ddddocr-core/examples/quick_start.rs`。 diff --git a/ddddocr-core/src/ocr.rs b/ddddocr-core/src/ocr.rs index 54cf476..4613c28 100644 --- a/ddddocr-core/src/ocr.rs +++ b/ddddocr-core/src/ocr.rs @@ -1,6 +1,7 @@ //! OCR 模块:识别器构建器、执行入口及元数据、字符集等类型。 mod builder; +mod builtin; mod charset; mod color_filter; mod executor; diff --git a/ddddocr-core/src/ocr/builtin.rs b/ddddocr-core/src/ocr/builtin.rs new file mode 100644 index 0000000..3554a4a --- /dev/null +++ b/ddddocr-core/src/ocr/builtin.rs @@ -0,0 +1,1038 @@ +//! 内置字符集数据:与官方 ddddocr 模型配套的旧版(OLD)与 Beta 字符集。 +//! +//! 本模块为私有数据模块,对外通过 [`super::metadata::ModelMetadata::from_builtin_old`] / +//! [`super::metadata::ModelMetadata::from_builtin_beta`] 暴露。 + +pub const CHARSET_OLD: &[&str] = &[ + "", "掀", "袜", "顧", "徕", "榱", "荪", "浡", "其", "炎", "玉", "恩", "劣", "徽", "廉", "桂", + "拂", "鳊", "撤", "赏", "哮", "侄", "蓮", "И", "进", "饭", "饱", "优", "楸", "礻", "蜉", "營", + "伙", "杌", "修", "榜", "准", "铒", "戏", "赭", "襟", "彘", "彩", "雁", "闽", "坎", "聂", "氡", + "辜", "苁", "潆", "摁", "月", "稇", "而", "醴", "簉", "卑", "妖", "埽", "嘡", "醛", "見", "煎", + "汪", "秽", "迄", "噭", "焉", "钌", "瑕", "玻", "仙", "蹑", "钀", "翦", "丰", "矗", "2", "胚", + "镊", "镡", "鍊", "帖", "僰", "淀", "吒", "冲", "挡", "粼", "螈", "缵", "孺", "侦", "曷", "渐", + "敷", "投", "宸", "祉", "柳", "尖", "梃", "淘", "臁", "躇", "撖", "惭", "狄", "聢", "官", "狴", + "诬", "骄", "跻", "場", "姻", "钎", "藥", "綉", "驾", "舻", "黢", "鲦", "蜣", "渖", "绹", "佰", + "怜", "三", "痪", "眍", "养", "角", "薜", "濑", "劳", "戟", "傎", "纫", "徉", "收", "稍", "虫", + "螋", "鬲", "捌", "陡", "蓟", "邳", "蹢", "涉", "煋", "端", "懷", "椤", "埶", "廊", "免", "秫", + "猢", "睐", "臺", "擀", "布", "麃", "彗", "汊", "芄", "遣", "胙", "另", "癯", "徭", "疢", "茆", + "忡", "'", "烃", "笕", "薤", "肆", "熛", "過", "盖", "跷", "呷", "痿", "沖", "魍", "讣", "庤", + "弑", "诩", "庵", "履", "暮", "始", "滟", "矅", "蛹", "鸿", "啃", "铋", "沿", "鐾", "酆", "團", + "恙", "閥", "聒", "讵", "颠", "沾", "堅", "踣", "陴", "覃", "滙", "浐", "钇", "脆", "炙", "亮", + "觌", "産", "汩", "鸭", "斄", "堆", "掭", "揞", "鹂", "郫", "瘅", "蚂", "揩", "学", "组", "浸", + "腙", "耀", "嗛", "局", "蠓", "肠", "昏", "I", "岑", "镯", "憧", "油", "泸", "鸟", "潇", "蕻", + "褒", "瞧", "旸", "昭", "庐", "鞒", "内", "痈", "己", "曙", "怠", "锟", "晞", "耢", "鲢", "醦", + "糕", "療", "寇", "梵", "黾", "呻", "苒", "ü", "校", "嘏", "昃", "Ⅰ", "蕰", "凖", "嵛", "裨", + "筏", "匜", "咋", "乏", "婵", "镂", "珰", "感", "蔗", "蚵", "庞", "弢", "槟", "口", "漉", "﹒", + "咂", "俩", "增", "硐", "襙", "绉", "卿", "距", "璱", "猖", "铚", "郚", "嬖", "缒", "阃", "扞", + "V", "望", "最", "浔", "骜", "赃", "闻", "砍", "奸", "灶", "以", "获", "鳎", "浦", "罐", "孓", + "纭", "瘀", "普", "氰", "塮", "症", "顷", "们", "螓", "蛸", "鵰", "册", "美", "萨", "沘", "犰", + "嫌", "名", ")", "懦", "滇", "F", "垡", "声", "毅", "隅", "鲎", "煨", "萦", "宜", "唇", "鯨", + "邛", "杲", "赜", "长", "魂", "桠", "锇", "搓", "俘", "仰", "膘", "宦", "歹", "遁", "猃", "噉", + "幂", "糜", "嗤", "周", "剂", "曦", "暧", "焖", "髻", "釐", "泰", "窟", "檎", "旧", "犀", "镄", + "百", "取", "岍", "逗", "叽", "呃", "鲪", "萬", "陈", "7", "習", "区", "逄", "宏", "罡", "漭", + "盗", "郿", "般", "谢", "倪", "纵", "婶", "砧", "揖", "扪", "濒", "愤", "茓", "浞", "子", "揄", + "旌", "趄", "樊", "醑", "遄", "婚", "汶", "矩", "裈", "弊", "呱", "铳", "勿", "蚴", "忿", "褓", + "缚", "酱", "璞", "庆", "除", "礌", "珩", "榨", "鼢", "逞", "容", "圯", "猛", "陌", "-", "嚯", + "镘", "鱾", "睚", "猬", "杜", "鳓", "燈", "計", "咣", "炜", "睁", "箱", "邮", "略", "馇", "逐", + "雀", "僬", "髯", "奖", "俱", "-", "绗", "犏", "辱", "忑", "挽", "康", "蝼", "栏", "模", "辒", + "•", "儋", "罱", "墈", "会", "秀", "栈", "缔", "醜", "蚣", "阮", "鼗", "眼", "湧", "沁", "夥", + "毕", "媚", "瘳", "痣", "搴", "闿", "遍", "焰", "岣", "舱", "埌", "麿", "嘿", "靽", "体", "想", + "霓", "钛", "摽", "苑", "芳", "技", "綮", "钅", "燠", "栾", "年", "悱", "腹", "员", "呕", "闇", + "嗫", "檩", "荒", "溱", "舨", "峙", "卒", "洑", "预", "弯", "蔷", "叵", "锯", "慈", "牧", "患", + "贇", "偷", "鲜", "锓", "躔", "嚬", "烈", "娌", "嘲", "详", "麺", "舒", "厨", "徵", "葹", "只", + "篦", "鹀", "剕", "驳", "聍", "黧", "砾", "暅", "褫", "呈", "森", "结", "龛", "钲", "轧", "扔", + "蕹", "赵", "涒", "冯", "渲", "缭", "坚", "趼", "鲑", "倫", "门", "班", "垚", "鞍", "菘", "畐", + "僇", "侉", "禢", "轳", "饦", "兽", "呯", "捂", "樨", "卧", "栝", "豭", "冶", "鉰", "申", "蜈", + "印", "缨", "镫", "蕾", "圜", "扑", "娉", "烦", "缳", "广", "峄", "獒", "铔", "奁", "醚", "倥", + "蹇", "阚", "镆", "煺", "德", "颉", "嗅", "绷", "蒯", "祺", "崧", "往", "枨", "涡", "鲲", "瓅", + "岌", "肘", "飔", "缘", "千", "棱", "溶", "窣", "篼", "代", "捡", "送", "咡", "术", "滑", "茜", + "晾", "挤", "曳", "糈", "G", "翊", "殴", "妹", "溥", "璆", "烩", "拙", "襄", "几", "嘴", "D", + "驮", "淙", "蹐", "合", "環", "剑", "怪", "褂", "畑", "燏", "订", "珪", "≥", "瘟", "耷", "槑", + "衷", "猕", "迁", "霎", "槜", "﹖", "鋈", "苹", "嫣", "祜", "李", "鄒", "噢", "萄", "仝", "纨", + "直", "悛", "拣", "远", "诏", "圧", "躬", "蝟", "總", "眆", "筻", "硇", "鳁", "眠", "钆", "泞", + "猱", "宾", "酞", "募", "螳", "腴", "念", "宠", "唯", "怊", "勃", "M", "兿", "蟑", "妁", "掸", + "拌", "铸", "讼", "诟", "锺", "Ω", "竟", "羚", "剽", "C", "苦", "煳", "罢", "跨", "~", "豸", + "±", "俬", "捺", "彦", "钣", "鋆", "用", "缤", "搁", "徼", "谦", "筘", "嗨", "扮", "旇", "折", + "咯", "昆", "叟", "垂", "箐", "捻", "燕", "島", "瞀", "鮮", "屡", "點", "瘭", "恚", "旚", "丟", + "捽", "菁", "瀑", "炕", "蹩", "芒", "r", "是", "媾", "鹝", "囵", "萤", "拷", "频", "埴", "课", + "癍", "袱", "螯", "谘", "榛", "Y", "缣", "裔", "憩", "相", "觀", "晗", "坳", "炔", "勉", "汆", + "钡", "舐", "衫", "疫", "鲙", "蘩", "穈", "殁", "九", "泻", "咤", "構", "谆", "陕", "装", "蔡", + "画", "介", "苋", "務", "敝", "俟", "帇", "鸺", "贸", "茗", "肃", "滪", "输", "瘗", "菽", "饹", + "诉", "遐", "浑", "扎", "卟", "铀", "邗", "觋", "嘎", "塑", "潏", "金", "姘", "潋", "逵", "鲻", + "逯", "炮", "甄", "髡", "剩", "嗬", "芴", "屋", "改", "骣", "芪", "邠", "痋", "珑", "帆", "狙", + "八", "奔", "族", "轵", "氖", "雕", "痧", "眊", "胛", "酉", "鲼", "砣", "猸", "餮", "郇", "沫", + "跖", "蝉", "屑", "辘", "閣", "涑", "邡", "篃", "交", "笼", "颇", "贻", "魄", "黡", "劂", "糠", + "炅", "帨", "苍", "瓴", "粤", "莎", "朿", "埔", "绸", "齁", "鱿", "惨", "腢", "郡", "棠", "猫", + "脑", "風", "蚱", "捐", "嵌", "胱", "馗", "竽", "泥", "辍", "怖", "雾", "絮", "淼", "筝", "碲", + "悼", "龀", "の", "珥", "忐", "溲", "昕", "荔", "掂", "瘦", "僭", "蔌", "抺", "椅", "誉", "扯", + "僜", "停", "衉", "汇", "赔", "眄", "呙", "咙", "剿", "次", "蛟", "嗓", "』", "汕", "詈", "帘", + "踧", "姁", "血", "堪", "喜", "滩", "璎", "胄", "俨", "眚", "凌", "拽", "滔", "⑿", "嬃", "―", + "汐", "潭", "阡", "呓", "婷", "执", "妊", "恂", "妥", "鳘", "蔫", "设", "睒", "笪", "謇", "鞋", + "谍", "黯", "虍", "馬", "蚧", "骑", "峤", "舾", "儀", "駡", "β", "蓑", "柏", "痒", "蒇", "痕", + "妍", "熠", "僻", "爬", "迭", "畫", "绰", "湯", "凭", "菼", "懈", "顒", "午", "箪", "糙", "址", + "钼", "堵", "佘", "侍", "卤", "(", "榚", "泽", "溘", "蟹", "b", "燁", "颂", "菠", "榉", "鲡", + "埸", "荛", "歘", "断", "邸", "贡", "礞", "蔼", "脸", "爪", "帜", "翡", "仟", "皎", "辆", "滫", + "昔", "™", "柬", "弓", "遇", "杪", "侨", "娓", "镪", "觑", "一", "踌", "牟", "褡", "厩", "晌", + "每", "娘", "渤", "c", "咫", "成", "颏", "孩", "鼓", "瞌", "槁", "捒", "阉", "伉", "癣", "胞", + "鲟", "瓤", "杅", "紡", "喂", "掠", "镜", "镧", "侞", "赦", "貝", "丕", "臧", "L", "池", "彷", + "棓", "锽", "渊", "食", "饨", "堡", "玥", "氣", "讽", "敬", "闺", "帡", "携", "哫", "珈", "魆", + "哄", "旁", "喻", "泄", "畎", "郁", "唅", "葜", "繪", "飐", "谶", "聆", "斝", "谥", "辉", "髅", + "進", "吧", "蹀", "铛", "笛", "睥", "楼", "凝", "況", "鸷", "苠", "饺", "沙", "缴", "块", "梢", + "慝", "珐", "鄏", "霰", "迸", "氆", "趵", "棣", "鳔", "祆", "☆", "苯", "恁", "螨", "庭", "缠", + "槠", "津", "髋", "诔", "葶", "蜾", "坻", "蒹", "摔", "向", "垩", "蹭", "淇", "筛", "滬", "玡", + "铺", "逼", "劵", "绲", "团", "鳀", "常", "玖", "擢", "株", "铵", "樽", "弭", "醇", "糨", "璈", + "曩", "潔", "祘", "磨", "希", "鲅", "擂", "谗", "唳", "欷", "欧", "绋", "庙", "琬", "稳", "糊", + "拥", "霪", "浼", "翎", "俜", "摸", "筚", "巯", "墼", "苫", "缩", "镚", "婪", "圹", "咚", "儿", + "蒽", "婆", "鲐", "雹", "霞", "嶪", "濠", "琉", "澌", "媢", "禤", "摺", "掏", "矢", "艄", "围", + "呸", "寺", "拤", "氐", "柝", "跎", "僖", "挢", "茨", "涮", "缫", "撸", "荨", "嶷", "廋", "魋", + "付", "喋", "蜗", "邙", "棹", "璪", "倡", "鞭", "游", "錦", "眬", "抒", "眈", "培", "夏", "黔", + "獐", "皋", "戛", "鲀", "垒", "耽", "纤", "漩", "铈", "握", "窝", "芋", "濞", "截", "零", "敖", + "眸", "怦", "噎", "簋", "掳", "妣", "湃", "璠", "殄", "觞", "桅", "笋", "鲞", "踯", "傀", "犨", + "抵", "疰", "暌", "耖", "供", "枳", "怂", "娶", "鸩", "捣", "庸", "逡", "懋", "颃", "長", "鼫", + "姮", "蹈", "耵", "乂", "骐", "殇", "膏", "仳", "冥", "梭", "洵", "碣", "昝", "仉", "軒", "隍", + "更", "な", "嵕", "拜", "粑", "鲴", "吇", "秃", "尕", "魃", "狨", "臛", "蟥", "胨", "注", "谁", + "张", "才", "尸", "派", "矮", "洳", "舟", "溺", "锴", "寓", "籴", "夕", "叭", "荠", "澼", "劃", + "久", "私", "炉", "娟", "麤", "稂", "河", "纴", "夺", "亏", "焙", "。", "塗", "蜩", "栌", "渡", + "薰", "崋", "揿", "漤", "啾", "郏", "舣", "卉", "爱", "牚", "撵", "钺", "再", "企", "笺", "疾", + "承", "俾", "瞈", "邰", "汾", "瘛", "檫", "蒎", "觅", "绀", "掎", "U", "赓", "匳", "聘", "蛤", + "跤", "嗜", "洼", "歔", "弟", "飕", "莼", "嫉", "那", "滈", "践", "僦", "偎", "扢", "绚", "乕", + "旳", "招", "饯", "®", "攸", "鞁", "囫", "铨", "陒", "鷄", "畀", "韨", "經", "纾", "萸", "肴", + "→", "宗", "迳", "鳞", "亚", "搂", "喀", "狮", "坦", "瞥", "采", "姝", "钳", "□", "剌", "維", + "葸", "鼩", "公", "刀", "沩", "喔", "泺", "哉", "徨", "篝", "掊", "沕", "运", "偆", "浒", "语", + "乇", "仪", "萝", "疍", "踽", "碡", "熰", "荞", "嚓", "天", "饰", "泵", "械", "孑", "蛰", "荟", + "源", "峡", "矜", "睬", "噬", "腆", "婉", "‘", "等", "誓", "辀", "岖", "琖", "碜", "霍", "怼", + "唛", "弈", "淑", "疆", "晴", "镴", "鸡", "埚", "焕", "芦", "唻", "踅", "吴", "殡", "唏", "吨", + "寡", "鹉", "絲", "坉", "會", "埭", "Ⅲ", "捏", "墅", "卓", "叙", "徇", "柜", "各", "荭", "J", + "恝", "囐", "蓉", "犋", "叡", "莺", "颌", "蒸", "饸", "疋", "玊", "兢", "鱽", "藍", "杳", "辂", + "獘", "拔", "侪", "湍", "膂", "渔", "瘊", "雉", "稁", "職", "僤", "鄳", "祁", "稱", "I", "裴", + "锉", "曹", "鲶", "挨", "哑", "鷪", "鏠", "煞", "师", "蛲", "牁", "琅", "告", "媒", "祭", "确", + "荚", "亰", "蝗", "阗", "歩", "疲", "f", "唣", "愛", "郾", "棍", "山", "狲", "纽", "蚡", "栂", + "馓", "诊", "猴", "喤", "来", "继", "桎", "嬛", "骞", "邴", "暄", "贼", "昴", "廿", "克", "耔", + "彤", "鹭", "葓", "骢", "龁", "鏡", "瀚", "赅", "韩", "譄", "榷", "殚", "膛", "须", "、", "砖", + "唶", "番", "蛘", "畴", "铠", "亢", "氓", "铰", "炻", "筫", "迢", "兰", "玺", "砻", "积", "莜", + "吸", "监", "膦", "迪", "迷", "冷", "哀", "贳", "瞄", "器", "鹡", "惺", "徐", "酢", "寒", "Ⓡ", + "倾", "飞", "楽", "涢", "队", "舆", "赤", "璩", "戳", "殳", "掮", "舴", "蜷", "宄", "拴", "癌", + "舛", "婀", "抟", "靡", "骍", "揸", "思", "慧", "平", "橘", "臭", "硖", "卬", "畈", "兠", "茸", + "脂", "魚", "晩", "御", "龋", "涣", "罨", "爍", "糌", "汧", "缐", "贽", "要", "祀", "鲊", "爼", + "獯", "瀣", "棋", "肈", "佣", "娣", "柩", "枸", "偃", "v", "唷", "劍", "榴", "槐", "漫", "洽", + "蒡", "籼", "魔", "峋", "第", "歙", "萧", "谮", "埯", "撮", "马", "绡", "裘", "鹋", "蓬", "显", + "噶", "倒", "镳", "艽", "窬", "拳", "樯", "跋", "詹", "钥", "心", "嶽", "嚋", "戎", "吕", "涂", + "悃", "麦", "骋", "推", "箩", "硚", "匆", "村", "五", "杨", "凑", "鞫", "镰", "伥", "诒", "纣", + "崃", "鸻", "翰", "辌", "廛", "證", "舢", "盼", "腿", "圳", "贱", "皿", "隆", "屈", "龏", "瓒", + "顏", "↓", "赈", "煙", "窍", "韧", "壁", "莰", "箬", "蹋", "褰", "峥", "悚", "坜", "环", "回", + "疼", "渍", "蝄", "东", "臂", "坩", "走", "痍", "或", "蜀", "熳", "蜻", "佐", "懿", "嚅", "紗", + "螭", "忖", "顶", "狡", "吲", "洣", "帛", "呶", "柞", "柫", "酿", "粥", "琢", "呵", "踝", "榀", + "呲", "價", "鼋", "欺", "此", "背", "猎", "昱", "濡", "稚", "欠", "暇", "茬", "牙", "迹", "尼", + "氛", "膠", "缯", "娼", "骚", "姒", "鬟", "霁", "鲔", "者", "驰", "倩", "馉", "工", "芬", "烙", + "卦", "C", "裂", "垲", "摆", "珮", "缏", "杞", "绘", "司", "如", "姞", "荆", "挖", "跗", "伍", + "氚", "钘", "郢", "轱", "篆", "吭", "夡", "鹫", "讷", "轺", "!", "匈", "待", "聱", "黏", "海", + "蹶", "趋", "鎮", "觊", "江", "咸", "富", "艴", "稗", "钜", "搏", "壶", "鲮", "薪", "猞", "轰", + "踪", "赣", "循", "序", "噻", "若", "裾", "许", "癞", "吓", "判", "踔", "查", "蚀", "[", "樓", + "坌", "岳", "榄", "役", "倜", "⒂", "旭", "溆", "惯", "咀", "跫", "选", "囱", "污", "镶", "⒁", + "淠", "氮", "酯", "寅", "芼", "炊", "夯", "郪", "农", "褲", "嘬", "蹻", "烔", "罄", "开", "靴", + "镇", "杯", "羰", "硪", "籍", "摘", "馀", "餐", "眯", "⑴", "呗", "巫", "幤", "蒤", "蒗", "镥", + "檵", "盛", "純", "娃", "●", "耿", "巡", "婴", "槔", "i", "颊", "Ⅳ", "栅", "绅", "邘", "冉", + "碧", "使", "熨", "羞", "扼", "漳", "觯", "楊", "励", "逑", "咄", "之", "斤", "嘣", "鹰", "媸", + "鲂", "褚", "磚", "琨", "聪", "牖", "太", "蓍", "涫", "≤", "虽", "鸽", "燧", "褊", "聿", "壬", + "然", "疚", "莲", "悴", "簃", "颓", "坠", "瞬", "汳", "l", "登", "瘼", "窳", "桤", "縯", "匣", + "坡", "↑", "愦", "攘", "渭", "嬢", "鲰", "性", "楚", "澈", "赪", "達", "鄯", "罅", "帽", "茠", + "底", "嫜", "奏", "浅", "荽", "楹", "鼍", "枵", "嗔", "滍", "椴", "嵩", "氤", "搠", "两", "榔", + "树", "吝", "基", "峂", "栎", "侮", "舸", "遂", "颡", "锷", "杼", "酔", "幄", "哽", "睢", "陔", + "※", "嚆", "宬", "宽", "髦", "笾", "保", "蹊", "榕", "咏", "椋", "丧", "裤", "骛", "逧", "弇", + "崆", "樘", "疤", "鸤", "伞", "抚", "诎", "诵", "豢", "佳", "差", "埝", "极", "黍", "煜", "曰", + "阱", "悞", "叹", "垤", "藁", "嗵", "崔", "卫", "珂", "憯", "蔬", "菜", "碑", "扈", "铆", "夹", + "衡", "弱", "挈", "徜", "疠", "丶", "遠", "提", "斧", "炟", "肺", "B", "她", "晟", "谎", "邱", + "粳", "酽", "爨", "鬼", "伧", "兹", "嶓", "谤", "饕", "揶", "谱", "歡", "髪", "餍", "泳", "郞", + "谣", "汉", "褐", "非", "刽", "缅", "饴", "齐", "兴", "涯", "芫", "凡", "褶", "晡", "努", "蚶", + "彥", "皤", "砌", "黼", "吹", "指", "㙟", "蓁", "鹜", "話", "拊", "辨", "盎", "肌", "旘", "软", + "颍", "甏", "滚", "旦", "滨", "间", "尴", "对", "鄘", "称", "镗", "咅", "璐", "怔", "垛", "洎", + "瓮", "绨", "脚", "遒", "吊", "纸", "蹅", "经", "泉", "武", "汀", "歪", "败", "拾", "铪", "吼", + "邹", "磊", "论", "岛", "厍", "锛", "芎", "芭", "音", "澧", "镕", "锒", "宙", "牵", "忱", "嫔", + "麯", "澉", "擐", "砥", "撞", "痴", "盹", "畿", "厾", "酸", "俑", "脽", "鸈", "枷", "咨", "蔹", + "诂", "胰", "董", "脶", "黩", "髓", "鉵", "澎", "鲽", "梧", "樱", "诜", "鲯", "跂", "盂", "浴", + "苻", "锅", "實", "碁", "嘛", "氕", "艮", "涟", "绢", "姿", "茝", "砘", "簿", "穷", "镃", "∈", + "抽", "事", "誜", "窅", "瀘", "鲹", "兖", "嵎", "陧", "榍", "轶", "柿", "藤", "薏", "娆", "骷", + "梅", "摒", "睪", "剪", "羸", "忧", "邝", "跺", "旆", "堕", "伫", "绍", "疵", "樟", "–", "绾", + "蜴", "靸", "侃", "瘘", "珧", "遨", "縠", "信", "充", "桔", "黇", "劬", "脒", "良", "俵", "颙", + "轹", "犿", "屐", "牾", "4", "兮", "澝", "汗", "沼", "铲", "濋", "鹬", "丝", "妫", "重", "蒺", + "磲", "曚", "尔", "国", "桐", "俣", "剐", "哼", "恹", "哧", "藔", "谓", "轨", "眩", "痞", "添", + "鬯", "库", "梱", "婕", "蜢", "贿", "敕", "泯", "羟", "龇", "垸", "左", "肖", "辎", "鞣", "谄", + "可", "腺", "末", "狞", "贷", "嗌", "仕", "楞", "膻", "臻", "欻", "洲", "所", "檀", "抔", "罹", + "牒", "仫", "芨", "柄", "嫩", "酒", "祙", "渠", "的", "笨", "鳐", "楡", "过", "苡", "核", "拖", + "阢", "莒", "凤", "锋", "`", "硎", "弁", "鬶", "朐", "忏", "於", "昊", "剟", "咳", "湘", "日", + "满", "哨", "螵", "餪", "放", "佶", "葵", "硷", "c", "抱", "锥", "芮", "啻", "惊", "峁", "琊", + "嶲", "撺", "煅", "屏", "袗", "鄞", "梓", "鹌", "宅", "赂", "鱼", "洱", "騳", "E", "物", "觏", + "雙", "瑀", "上", "淩", "愀", "❋", "鄙", "憝", "沛", "硫", "产", "垯", "亁", "枭", "堰", "赑", + "趾", "庹", "腭", "迨", "拚", "晒", "蜇", "扣", "纰", "闵", "窭", "椽", "菏", "嘁", "伛", "郸", + "素", "殷", "表", "躞", "笸", "耻", "荧", "辛", "篑", "馈", "壮", "耩", "宛", "慰", "盡", "塆", + "铯", "苏", "王", "桕", "⑧", "°", "浚", "栉", "朘", "虚", "骆", "坂", "秤", "鲋", "蕊", "渝", + "呦", "潼", "驱", "诼", "峇", "盤", "趴", "肄", "笑", "讹", "貋", "穂", "啼", "趟", "暽", "傣", + "蜎", "挎", "陳", "勖", "戴", "旃", "瞎", "舌", "幻", "喾", "赁", "E", "播", "诀", "蟛", "鹛", + "骶", "輸", "連", "醳", "逅", "奉", "崖", "娩", "幔", "佃", "扅", "阔", "生", "贬", "疯", "珀", + "苶", "屯", "裣", "蹯", "蝮", "解", "陂", "疝", "茈", "帑", "议", "仲", "埙", "竺", "峰", "遮", + "涎", "穸", "阂", "潵", "镱", "例", "荑", "u", "脎", "衍", "轲", "⑵", "虾", "颚", "钞", "²", + "伴", "根", "沣", "腌", "户", "~", "辙", "愧", "噤", "觥", "波", "铗", "纂", "鲺", "僚", "毐", + "〇", "桼", "祗", "慢", "啵", "坏", "吗", "嗞", "甬", "曈", "徹", "灏", "混", "渌", "括", "脖", + "汝", "現", "訇", "紅", "飘", "虢", "腱", "旄", "嬴", "昨", "孀", "蚁", "呛", "讳", "病", ",", + "喈", "蒋", "镭", "葩", "耲", "鳈", "锄", "喘", "返", "傕", "咆", "享", "枥", "瓠", "茳", "铱", + "脘", "暹", "廒", "爝", "橹", "瞑", "铎", "岢", "叁", "翏", "捭", "賀", "悉", "帝", "芥", "牀", + "闌", "毯", "亍", "弧", "锆", "币", "祊", "纔", "齑", "肟", "绤", "獨", "翚", "颢", "係", "鍪", + "粉", "统", "诗", "娜", "褥", "鈺", "湔", "呤", "犸", "湨", "泣", "蟾", "犾", "烛", "斐", "朦", + "室", "诨", "榭", "煦", "醺", "敞", "燮", "糅", "衽", "孔", "猄", "疭", "辰", "钽", "胁", "釆", + "钉", "胤", "涧", "弼", "濯", "汨", "颖", "茫", "皑", "遏", "捃", "坭", "燴", "肩", "滞", "玢", + "巽", "砺", "蜿", "毁", "億", "骥", "本", "忽", "肚", "搽", "靰", "郴", "跆", "客", "酣", "α", + "屎", "辩", "殂", "垝", "紫", "秦", "喇", "凶", "傧", "铐", "蘊", "補", "贤", "竿", "途", "慗", + "榖", "券", "莠", "逆", "鳇", "误", "崟", "妇", "磷", "捧", "莸", "⇋", "绺", "稻", "填", "逋", + "侈", "隶", "侵", "翥", "惘", "惧", "鸥", "赠", "壳", "芯", "巩", "獗", "硅", "搎", "鲛", "9", + "夸", "穆", "缜", "诓", "观", "薛", "咎", "杧", "页", "饫", "瑟", "率", "礤", "悭", "畔", "匯", + "匮", "鼠", "犒", "芡", "傍", "嫂", "啸", "鄉", "哭", "鄱", "捷", "靺", "嚒", "嘀", "哒", "#", + "拼", "钚", "魁", "霣", "眶", "郊", "死", "愁", "箭", "鼙", "签", "害", "斛", "睑", "蟜", "余", + "墨", "様", "读", "養", "貉", "较", "浆", "翩", "徂", "冕", "铧", "列", "诈", "穝", "缑", "纲", + "志", "舀", "甾", "举", "馁", "ä", "畹", "榼", "垢", "襁", "麟", "灭", "佴", "镩", "酝", "柒", + "梯", "傈", "萭", "悫", "莨", "搞", "+", "兄", "偲", "攀", "曝", "嵝", "喳", "从", "遶", "撴", + ".", "鄄", "欲", "挺", "娡", "发", "速", "胲", "褀", "态", "行", "蚓", "坼", "适", "厦", "寐", + "带", "緃", "醤", "珽", "‧", "溍", "斋", "鐀", "朝", "欢", "传", "築", "咪", "据", "蹜", "医", + "妄", "肇", "囝", "怡", "镎", "桩", "轩", "岔", "腐", "矽", "媵", "搒", "菔", "拘", "D", "欃", + "唧", "瞒", "郈", "绦", "吟", "撝", "醉", "镣", "匝", "拎", "砒", "顸", "袁", "驼", "愔", "实", + "國", "奧", "胩", "府", "逾", "愕", "廷", "碌", "锖", "狩", "褴", "镢", "芷", "娥", "唤", "┌", + "云", "О", "檔", "驴", "躯", "驺", "洃", "檑", "窴", "(", "腕", "立", "楯", "齮", "〔", "漆", + "k", "芍", "蹽", "鬓", "概", "楣", "唐", "闲", "糗", "旱", "幸", "腽", "嗄", "迂", "镠", "顿", + "扥", "圃", "烜", "馍", "佝", "岷", "童", "悦", "┐", "铌", "袈", "靓", "骸", "和", "乔", "灸", + "泓", "临", "睿", "掖", "偿", "鐘", "犁", "祓", "鈴", "搌", "授", "鹳", "赢", "怅", "絪", "硬", + "芙", "螅", "”", "傢", "避", "裕", "歁", "全", "衰", "仃", "媛", "鬻", "跽", "沌", "急", "猷", + "激", "巉", "哝", "渣", "笫", "跳", "螫", "熜", "Z", "筷", "佩", "啶", "萃", "頫", "荙", "出", + "孽", "钟", "戡", "釉", "咬", "滦", "鹇", "贯", "鹮", "具", "翁", "机", "濱", "谳", "釣", "懑", + "葛", "袯", "谭", "质", "胴", "誊", "侗", "⑩", "静", "蚜", "溋", "嫪", "嗲", "瑭", "座", "舫", + "靶", "棘", "泊", "嵖", "摧", "勋", "僡", "藉", "疖", "巂", "随", "罾", "崚", "猹", "憨", "苘", + "斓", "鼷", "利", "谲", "剔", "艺", "箓", "蛀", "鲚", "搐", "裟", "捶", "绌", "揪", "帮", "缥", + "匍", "冀", "杻", "逛", "邑", "禾", "郰", "黜", "丘", "樂", "滌", "緣", "胃", "苄", "巾", "瑜", + "元", "蝶", "层", "烧", "级", "岭", "蘭", "繇", "蝓", "洞", "奢", "则", "政", "矾", "啭", "瘠", + "碴", "忤", "身", "匠", "警", "饩", "犬", "皲", "箔", "豕", "虑", "草", "喟", "芤", "逭", "艳", + "幡", "姚", "賓", "饪", "卯", "敌", "烽", "嫚", "黝", "豺", "㭗", "教", "偕", "板", "茹", "孤", + "人", "狻", "寰", "厕", "玲", "璨", "锵", "搛", "勍", "匾", "聃", "奘", "垃", "焓", "喽", "嫫", + "貌", "瘐", "嚰", "孟", "衔", "郎", "账", "础", "电", "黑", "骁", "拨", "濆", "圉", "刮", "闭", + "竣", "铅", "羔", "硌", "筑", "难", "管", "苕", "眺", "嫄", "竖", "榟", "崴", "摭", "狐", "娑", + "②", "罽", "谊", "←", "狳", "铫", "凯", "狉", "9", "肪", "崤", "莊", "妨", "缶", "滃", "瀦", + "揉", "肫", "恧", "糯", "嵬", "5", "裆", "嚷", "稣", "隐", "仂", "て", "驹", "籽", "肢", "尘", + "苈", "撷", "镲", "趹", "晤", "唱", "鉏", "篌", "驩", "雍", "闳", "拄", "藜", "朴", "伺", "诳", + "房", "吱", "Й", "鳄", "罿", "祧", "酩", "郅", "耎", "尜", "绝", "禅", "揠", "鎏", "慕", "麥", + "呜", "鸫", "党", "尝", "砑", "牌", "踉", "刨", "襻", "㾄", "螽", "谌", "止", "抑", "爻", "磬", + "铄", "蓠", "委", "汲", "鹑", "╱", "嚣", "彝", "穄", "穹", "態", "醋", "⒀", "叼", "婳", "簌", + "渥", "很", "甸", "帅", "锏", "与", "樾", "泷", "棼", "湲", "越", "祥", "短", "顼", "阘", "宋", + "馘", "鈉", "未", "囍", "浏", "叻", "箜", "鑽", "法", "曲", "淤", "僮", "做", "强", "析", "磕", + "谠", "染", "促", "朊", "隼", "铉", "莆", "蝣", "孛", "薮", "s", "惴", "秘", "妩", "訄", "蔓", + "喷", "诡", "犷", "酐", "酇", "刹", "壅", "甫", "史", "孃", "髌", "螬", "擤", "漏", "寞", "奡", + "悢", "颔", "岁", "耄", ";", "又", "锭", "鲤", "癔", "杰", "孥", "酲", "蓐", "耋", "捆", "庖", + "面", "鹈", "殊", "剡", "峪", "识", "锨", "归", "茴", "—", "菤", "汁", "攝", "液", "鼐", "示", + "讠", "男", "凍", "ò", "明", "莓", "砜", "崎", "蜂", "斡", "榫", "娅", "钪", "昙", "胜", "欣", + "怨", "◆", "粗", "秷", "节", "市", "贩", "祟", "弍", "蒟", "烁", "糧", "蠃", "編", "黙", "壕", + "戚", "犊", "桥", "仺", "孳", "怯", "皓", "倆", "垮", "扩", "诮", "钝", "脯", "晏", "帔", "葫", + "瑾", "運", "孬", "跄", "掣", "癜", "掌", "墀", "禇", "耸", "蜓", "鹆", "鄢", "攰", "瘢", "暝", + "鸣", "峧", "遵", "笃", "畚", "帧", "晨", "镔", "搜", "靠", "咐", "韓", "绮", "觉", "拦", "斲", + "疽", "掐", "尽", "許", "矶", "镉", "豹", "粞", "袋", "酵", "蛙", "戕", "劉", "髀", "彭", "玎", + "囿", "郐", "善", "睃", "結", "拧", "邯", "讧", "召", "椭", "瑪", "痼", "庼", "反", "疱", "屠", + "荣", "君", "胍", "乙", "臬", "头", "诰", "讪", "席", "晁", ":", "理", "槿", "璘", "禧", "呢", + "蹙", "擒", "鸲", "丐", "苓", "壑", "滥", "⑾", "炗", "礴", "耕", "卅", "唿", "苛", "寵", "窖", + "麻", "蕨", "沤", "氢", "虔", "癃", "及", "崛", "爽", "蛔", "颤", "膲", "桢", "坐", "蟞", "儇", + "葚", "骤", "誤", "寝", "嘭", "灰", "汹", "韂", "铮", "慒", "寶", "肽", "摅", "紧", "亞", "潸", + "悯", "橛", "檗", "闹", "愿", "担", "袄", "棚", "垟", "塄", "婞", "麈", "麸", "暗", "咦", "跞", + "谡", "盈", "磐", "慎", "瘰", "掼", "憔", "研", "被", "贮", "莛", "至", "呀", "庑", "矫", "摛", + "怃", "缙", "磺", "即", "驻", "瘤", "偏", "℃", "嫘", "癫", "汈", "鹟", "搅", "辅", "璀", "阊", + "绻", "瑙", "蓂", "棺", "孢", "铊", "鼒", "果", "砮", "飾", "凰", "Я", "遗", "祛", "纮", "劲", + "霹", "骃", "绔", "薅", "瀵", "垅", "?", "轻", "惇", "怕", "啥", "哙", "燎", "缆", "匡", "怫", + "卞", "朋", "酏", "阑", "爾", "伏", "敏", "埼", "罩", "菹", "艋", "肭", "鯭", "杋", "裀", "撬", + "蕺", "惠", "大", "爇", "笈", "絷", "琳", "谫", "诛", "糇", "袢", "倓", "髃", "觽", "埏", "寖", + "個", "筴", "外", "漯", "樭", "喁", "杀", "臑", "缇", "裸", "巅", "毹", "茅", "忆", "琼", "唑", + "烷", "项", "隋", "约", "排", "吮", "谂", "宝", "牲", "瘫", "娄", "沂", "醫", "拭", "纺", "蹰", + "哞", "风", "霆", "值", "酺", "侠", "螾", "埂", "育", "夷", "鮼", "怍", "鸠", "Θ", "瞳", "阇", + "耥", "羝", "伽", "洴", "記", "楔", "颼", "沪", "邢", "冰", "昀", "阙", "洌", "嫦", "杂", "仔", + "芑", "潴", "痄", "桨", "连", "碓", "塈", "F", "昇", "何", "桦", "晥", "驵", "旋", "药", "银", + "奋", "灣", "俐", "絡", "嫁", "浮", "为", "鞅", "科", "颦", "潽", "镍", "鸨", "粵", "骂", "拱", + "韫", "盆", "赎", "尿", "钿", "坍", "唁", "秧", "昌", "曆", "颋", "遭", "秭", "褔", "腋", "〉", + "吉", "漓", "臆", "焘", "已", "制", "钹", "鴨", "咖", "莘", "P", "碥", "互", "治", "标", "膝", + "伪", "浿", "纛", "郗", "看", "佧", "糖", "篓", "亡", "´", "骙", "澡", "影", "窂", "紬", "镅", + "慌", "框", "晋", "説", "丢", "凹", "卖", "巧", "蹉", "乾", "莫", "Z", "谔", "矧", "铑", "暴", + "庄", "湿", "活", "穿", "腩", "筣", "水", "6", "琦", "迈", "伯", "洄", "抡", "▪", "酋", "荤", + "雒", "粕", "簠", "菰", "髁", "枇", "陲", "多", "仗", "央", "滁", "胸", "梏", "痉", "姑", "襞", + "﹑", "齿", "弩", "花", "吆", "赫", "岵", "佪", "谑", "锤", "轴", "盐", "馄", "臜", "戢", "涠", + "鸸", "糟", "孪", "禁", "蒲", "化", "疏", "痰", "脾", "刈", "應", "珍", "膺", "扌", "廙", "汜", + "牍", "虐", "婿", "啕", "彻", "赝", "陶", "蠲", ">", "位", "屁", "醍", "粢", "挪", "臌", "滹", + "遴", "馨", "n", "稼", "徊", "酌", "轸", "债", "朰", "程", "辞", "痊", "插", "鹩", "郄", "铝", + "狱", "叱", "同", "寄", "搪", "蚯", "魭", "舍", "旷", "闰", "涝", "民", "嗡", "苌", "馕", "姥", + "屉", "啧", "枢", "❤", "窕", "钊", "矬", "菂", "佑", "≠", "獬", "桁", "墟", "皖", "鼻", "它", + "歇", "独", "好", "晕", "蚝", "锞", "颈", "豚", "聖", "裉", "扫", "岿", "悒", "佥", "苗", "妞", + "晚", "圭", "茼", "脲", "摊", "窠", "狸", "抻", "场", "呼", "囟", "噗", "狺", "困", "瀹", "削", + "衬", "谰", "蛆", "訓", "鉄", "痃", "炱", "蝻", "我", "暨", "骓", "馋", "埤", "脞", "晃", "螟", + "洮", "泛", "掾", "穑", "米", "蕲", "玦", "讙", "逢", "劐", "袭", "凫", "僳", "畛", "晷", "鳕", + "Ë", "愬", "坫", "鳡", "鞯", "叔", "胂", "囚", "筋", "青", "度", "涕", "琰", "﹔", "径", "陇", + "睛", "链", "状", "逶", "蘅", "“", "庇", "邽", "纥", "踶", "爺", "狭", "钫", "桃", "弛", "淳", + "办", "茕", "砸", "喱", "仅", "潞", "杈", "得", "咕", "俞", "检", "借", "恋", "驿", "倌", "钢", + "琐", "哆", "撙", "箫", "川", "猥", "牢", "蹁", "城", "馏", "锡", "楝", "蛱", "奈", "瑶", "桺", + "耆", "翟", "阒", "稲", "橐", "萱", "惹", "蘼", "主", "擦", "蟒", "台", "佬", "荫", "廖", "笏", + "铕", "衣", "洇", "炒", "瀍", "崭", "圻", "洚", "契", "嫱", "倏", "晶", "了", "堠", "勰", "椎", + "询", "梗", "飒", "锰", "览", "溇", "寻", "蓅", "【", "碇", "井", "露", "顔", "堌", "庳", "踩", + "i", "饷", "俊", "楫", "條", "搭", "奍", "羽", "憋", "岘", "毡", "曜", "乃", "′", "针", "羲", + "菓", "吩", "咩", "鞘", "尊", "宫", "舜", "啖", "惗", "北", "懊", "骇", "阄", "躅", "权", "缲", + "肥", "铜", "《", "录", "也", "棬", "煮", "舄", "厮", "'", "順", "受", "霜", "新", "售", "牞", + "圣", "妗", "犴", "宥", "哦", "陀", "卺", "冚", "蹒", "亸", "禮", "骰", "瑢", "弒", "抛", "谷", + "嫰", "動", "嘌", "惩", "枣", "忌", "茡", "爵", "嘚", "郧", "丨", "敲", "帚", "沭", "槊", "⑶", + "專", "毶", "圄", "磅", "蛭", "由", "蠹", "剜", "诫", "秆", "愠", "藓", "母", "请", "衩", "忸", + "蜕", "饽", "晦", "倔", "腠", "痛", "品", "簧", "父", "锐", "描", "蓰", "蛴", "箍", "兕", "苜", + "饼", "奚", "泗", "裥", "皂", "嵚", ",", "澶", "蠖", "沅", "馎", "籀", "菝", "眵", "糥", "铽", + "痤", "颟", "淄", "作", "抉", "俄", "么", "郑", "耒", "佛", "1", "纡", "鸢", "④", "鎚", "壖", + "遢", "鬈", "拢", "托", "哈", "節", "橦", "冼", "六", "耗", "樵", "涔", "舳", "龌", "衿", "婧", + "栓", "椹", "嘘", "膊", "茁", "丹", "螃", "剖", "洧", "珞", "潺", "孱", "呐", "萩", "刷", "引", + "说", "熟", "/", "靖", "酷", "耠", "饬", "菌", "洙", "荃", "饲", "酾", "阁", "陬", "铿", "倻", + "牮", "鞡", "撕", "倘", "盒", "曺", "襦", "辄", "算", "塬", "潢", "羖", "湾", "续", "△", "疙", + "谖", "嘅", "遑", "篚", "筮", "氍", "递", "尧", "G", "{", "分", "埒", "@", "蜍", "荼", "襆", + "槭", "檠", "縢", "濉", "梆", "隔", "镛", "倞", "润", "瓯", "瓢", "蟊", "沐", "啷", "砚", "皱", + "剅", "儙", "错", "幌", "滓", "砗", "郤", "喧", "峣", "簸", "毖", "踏", "锕", "…", "悖", "谧", + "醵", "加", "镐", "泐", "傫", "胪", "缄", "卩", "蓼", "丸", "垌", "汞", "宴", "膙", "圊", "矻", + "嚏", "漾", "幕", "駕", "葒", "绪", "袪", "镋", "杭", "澴", "鬃", "粟", "偻", "饳", "抨", "亟", + "温", "韶", "轿", "罟", "际", "诖", "复", "坯", "骗", "*", "副", "裢", "憬", "邾", "崇", "蕈", + "疮", "粽", "炝", "珲", "莅", "衾", "爲", "枯", "汛", "仁", "熏", "馥", "㎡", "檐", "锦", "竭", + "颁", "遽", "瘙", "样", "遛", "殍", "湄", "消", "鳌", "痫", "鳏", "瓶", "窈", "谚", "麒", "鸹", + "蟋", "横", "唠", "瘪", "媪", "侔", "鐵", "系", "杖", "m", "叉", "沟", "衢", "寘", "■", "弗", + "建", "疣", "珣", "綦", "劈", "道", "嘈", "先", "芝", "降", "滕", "邵", "邺", "給", ")", "廨", + "郛", "势", "氇", "坤", "昂", "焼", "奕", "闱", "朓", "毽", "还", "坨", "銭", "龂", "銎", "壽", + "矸", "窒", "①", "玷", "蝽", "泃", "烀", "魈", "★", "慶", "K", "嘶", "酶", "呖", "殿", "乡", + "䄂", "阳", "轪", "碱", "譬", "摩", "鳖", "刳", "地", "包", "貊", "悝", "圩", "今", "嚭", "凳", + "谕", "馃", "捎", "佯", "侬", "愆", "微", "涤", "舔", "蛇", "筲", "助", "锾", "剧", "缧", "簪", + "惚", "柢", "庾", "虹", "雪", "猡", "脔", "亶", "烨", "T", "锗", "芈", "女", "动", "偬", "琥", + "县", "诣", "精", "嬗", "栀", "艨", "智", "冗", "闼", "嗝", "z", "夢", "拿", "鹲", "尤", "啮", + "﹐", "ɔ", "钓", "施", "萼", "邻", "竞", "碶", "艰", "》", "翻", "馆", "橪", "逝", "臀", "淫", + "枉", "羿", "拇", "溷", "徒", "涓", "關", "聋", "嵊", "殖", "叛", "敫", "舵", "亊", "诽", "菱", + "苎", "破", "腚", "A", "嵋", "扊", "挂", "篷", "棂", "碟", "復", "劾", "韪", "疔", "粒", "鲵", + "毙", "店", "锻", "衮", "寳", "◎", "斯", "倦", "醢", "曾", "茚", "荐", "隗", "芊", "豪", "亻", + "哂", "堃", "宇", "桑", "匋", "植", "亥", "撂", "棒", "蟠", "W", "迟", "蚋", "溊", "缌", "鞚", + "蚤", "適", "赌", "卣", "厚", "鲾", "匙", "槃", "郎", "鬏", "玳", "龄", "丈", "圮", "冑", "院", + "葬", "嵐", "瓦", "孵", "漶", "星", "吐", "獍", "藠", "萍", "振", "潜", "龉", "匦", "粹", "諾", + "畵", "峦", "&", "埕", "朵", "戒", "炳", "酪", "绂", "篁", "测", "殆", "涌", "业", "盏", "醊", + "笆", "孰", "骊", "湛", "踰", "汎", "哲", "澙", "鲷", "√", "鄣", "亿", "螺", "吠", "伟", "凛", + "骡", "恻", "巨", "扶", "泡", "峯", "韵", "腎", "睦", "栖", "}", "笙", "疌", "绶", "忒", "哥", + "价", "纻", "薨", "漂", "濮", "缮", "勐", "妮", "傩", "陛", "陷", "柆", "瞭", "鲳", "烬", "喉", + "固", "桡", "聊", "逦", "猊", "梻", "涵", "栒", "逍", "饥", "凼", "早", "姣", "蕤", "塌", "桀", + "亳", "虻", "鹨", "典", "情", "怄", "商", "钍", "赚", "塥", "煽", "垱", "蝴", "乓", "籁", "帷", + "锢", "圪", "快", "赘", "杵", "漠", "滴", "斩", "拈", "蚕", "陽", "篡", "郦", "瞻", "郯", "鳍", + "幽", "旅", "乖", "鹖", "斫", "痂", "肸", "右", "锂", "永", "泾", "茎", "觱", "彼", "擎", "䨱", + "翱", "徝", "醅", "求", "湫", "転", "溴", "師", "瓣", "蝠", "铭", "社", "苞", "仇", "噌", "你", + "嗾", "雳", "榧", "駹", "雯", "叨", "遫", "氏", "航", "辗", "溢", "历", "楷", "诱", "雏", "梳", + "藕", "屺", "槎", "钐", "燘", "棽", "驸", "褪", "清", "十", "廰", "移", "筌", "揾", "瞠", "姽", + "馑", "恢", "逸", "p", "瑚", "茄", "鹧", "俗", "璟", "栊", "买", "瀛", "镒", "球", "氲", "缛", + "講", "胀", "焒", "悲", "翕", "拗", "T", "桌", "脓", "闪", "稀", "狎", "火", "柁", "琴", "澍", + "嗟", "龚", "楮", "噼", "隽", "栩", "焻", "哩", "藻", "瘸", "含", "偶", "界", "嘃", "昶", "澄", + "頤", "绒", "鲁", "麝", "决", "撒", "岙", "季", "刿", "肝", "蒉", "蓇", "财", "完", "蠔", "脉", + "肱", "谙", "蜮", "郭", "慨", "晔", "髂", "蛏", "眨", "钗", "葺", "惆", "娈", "瞵", "踞", "棁", + "蝢", "嚎", "猝", "必", "剞", "关", "咛", "劫", "闸", "肯", "№", "莩", "哇", "蛑", "镬", "羡", + "驊", "茂", "塍", "沓", "筱", "杉", "战", "茧", "耙", "击", "需", "腊", "酎", "畦", "葙", "鹘", + "韭", "嚚", "争", "域", "伢", "鞲", "哳", "栲", "某", "翌", "哗", "焚", "螗", "懲", "躲", "約", + "镖", "凿", "饶", "够", "剁", "铥", "应", "署", "杮", "蒂", " ", "坷", "礅", "款", "梁", "鄜", + "髹", "選", "伤", "路", "З", "亲", "野", "啦", "捯", "憷", "鲩", "札", "怏", "塘", "绊", "愍", + "簦", "牦", "黥", "鳜", "唉", "W", "沱", "蚺", "甪", "摉", "协", "耨", "娱", "桄", "仆", "类", + "搡", "滤", "岗", "休", "坶", "谒", "忭", "飨", "闷", "菟", "鲣", "驷", "湜", "疡", "蚩", "萊", + "䝉", "硒", "贺", "弃", "徘", "陨", "否", "遥", "妒", "X", "間", "觜", "跬", "夬", "羮", "喙", + "赇", "鹗", "『", "砀", "残", "绿", "小", "勘", "瀌", "扉", "耧", "衅", "挟", "乐", "鹏", "墁", + "澜", "噍", "坊", "術", "嗖", "知", "盉", "圆", "嗈", "蘖", "资", "爭", "=", "刑", "裒", "〈", + "淸", "定", "袒", "戗", "钤", "吵", "旯", "蓝", "裎", "溅", "贰", "荏", "甥", "悌", "勤", "炽", + "换", "躜", "!", "薄", "痱", "双", "匕", "肷", "挥", "茑", "船", "砝", "煤", "荜", "弘", "▏", + "陆", "稔", "朽", "冤", "頉", "遊", "砰", "迎", "碎", "唪", "醪", "稆", "练", "锸", "阵", "皇", + "香", "镀", "嫡", "持", "桶", "垄", "阍", "戥", "臣", "琛", "涘", "惶", "赙", "葆", "住", "舊", + "枝", "媲", "蓣", "龅", "搦", "_", "图", "力", "纪", "悍", "麗", "戽", "腧", "绣", "跟", "哕", + "打", "蝰", "Φ", "吞", "功", "夀", "劓", "沇", "熔", "占", "隰", "命", "佻", "豁", "苣", "楦", + "掇", "蛛", "唢", "郜", "霉", "鲏", "予", "沸", "殻", "俯", "探", "篪", "荇", "邈", "烯", "忮", + "伸", "岬", "×", "锧", "窸", "毪", "纩", "蛋", "讯", "骼", "叶", "楂", "犟", "站", "盘", "隈", + "喝", "儣", "兵", "尚", "孙", "爿", "芜", "羁", "旖", "溽", "迩", "京", "7", "龃", "狝", "缦", + "缁", "鲃", "怒", "故", "據", "枫", "髙", "亭", "耳", "飚", "O", "编", "箸", "幼", "氘", "鞮", + "匐", "祯", "臃", "辫", "磋", "溝", "墙", "诚", "阻", "档", "歆", "璃", "悻", "婤", "映", "瑞", + "牂", "话", "忠", "潘", "惋", "冬", "氦", "腔", "胬", "盔", "\"", "饮", "贶", "嚄", "儆", "溜", + "砷", "樇", "跏", "泩", "馌", "埃", "莙", "革", "珙", "乌", "鍋", "穴", "石", "珺", "熹", "诞", + "<", "腉", "姊", "钧", "罪", "拆", "赊", "殒", "堇", "仑", "掺", "塃", "獴", "迥", "盦", "檬", + "益", "居", "鼑", "异", "嘻", "悔", "旮", "况", "時", "阋", "洛", "線", "#", "型", "迕", "睇", + "橱", "笊", "蛞", "愚", "茉", "镈", "镞", "垭", "扁", "泫", "搬", "古", "书", "疸", "痨", "黟", + "墉", "料", "并", "ㆍ", "裳", "鞑", "湮", "柠", "颐", "形", "━", "逹", "硁", "置", "韦", "瓞", + "象", "殽", "均", "浓", "瞓", "椐", "洨", "乱", "襜", "终", "優", "睹", "敦", "鼬", "唆", "佼", + "財", "瘃", "H", "痳", "勺", "依", "虎", "蕖", "玄", "缓", "滢", "^", "骅", "诘", "弋", ":", + "∩", "廪", "缈", "造", "蕉", "孖", "嫒", "寨", "意", "岽", "庶", "罗", "瞢", "酹", "蔟", "赴", + "烂", "栋", "格", "矛", "驯", "词", "嗦", "剀", "蓓", "期", "鏢", "羑", "奴", "椱", "A", "狗", + "烟", "蹬", "案", "记", "讴", "鳑", "侯", "霏", "焜", "沬", "份", "酦", "芗", "庚", "瑗", "鹎", + "穗", "鲠", "肛", "厄", "蜔", "學", "伊", "⑥", "琪", "邒", "少", "霖", "蓖", "猜", "塾", "肾", + "罃", "伐", "钩", "骈", "溟", "饵", "莉", "é", "刖", "洯", "堉", "锝", "趔", "七", "萁", "竹", + "憾", "蚨", "离", "柔", "替", "侑", "飙", "气", "震", "厥", "备", "刻", "顽", "瞽", "腄", "雄", + "燃", "旬", "简", "翠", "熥", "◇", "吃", "囡", "玙", "铷", "暖", "配", "傻", "窄", "皈", "夼", + "舂", "乜", "苩", "攉", "雠", "茇", "锈", "酰", "粮", "祝", "考", "堍", "鳅", "彬", "▲", "孝", + "蠊", "顇", "娲", "腥", "$", "珠", "厂", "诠", "蹓", "轼", "嵫", "捩", "硗", "胺", "证", "膀", + "」", "胯", "钷", "毂", "柙", "深", "沄", "匹", "8", "爷", "礳", "秏", "窜", "魑", "d", "转", + "烆", "屿", "眙", "極", "袤", "護", "V", "狂", "柑", "玠", "氩", "’", "馊", "玛", "坢", "%", + "燔", "颗", "舅", "暂", "艾", "芹", "溏", "晰", "件", "琚", "仿", "祾", "酤", "騠", "揳", "鲫", + "蜥", "仨", "牺", "步", "讓", "港", "煲", "铴", "腦", "鳝", "危", "鋪", "冠", "正", "柽", "抍", + "掘", "控", "娴", "娀", "離", "手", "臾", "酗", "筼", "煸", "弹", "照", "哎", "毒", "颀", "诙", + "刚", "搢", "䧳", "峒", "滋", "\\", "匀", "黉", "毓", "娠", "床", "浪", "祐", "铟", "4", "?", + "凄", "飗", "蚍", "葑", "抗", "鹞", "糸", "红", "英", "违", "橡", "眷", "防", "缬", "龠", "察", + "仍", "辇", "减", "闫", "箴", "龍", "館", "屙", "翙", "媽", "涴", "到", "旻", "删", "瞾", "鏖", + "咭", "豨", "荘", "炭", "畼", "构", "锘", "鉫", "候", "扇", "繄", "猩", "瘵", "恺", "贵", "榦", + "息", "恽", "胎", "狰", "雜", "辋", "璜", "硈", "泠", "呔", "蹿", "踹", "摄", "炀", "坞", "蹄", + "裝", "赛", "蝥", "塔", "靳", "荬", "找", "仡", "淮", "比", "淆", "义", "淝", "卢", "辟", "寂", + "庒", "鳯", "暲", "景", "邪", "腻", "赍", "甍", "讲", "哌", "嶝", "鎌", "总", "缱", "问", "磛", + "谅", "拉", "靈", "奭", "沆", "茔", "羅", "鄠", "網", "吏", "懵", "鑫", "歌", "黹", "嵘", "涞", + "碳", "崂", "婥", "赞", "镑", "購", "幺", "鸰", "饟", "蝌", "忝", "懒", "禺", "梽", "齉", "恳", + "拯", "弥", "荡", "芾", "幪", "厌", "馒", "蜘", "欸", "吣", "1", "却", "榻", "碾", "袂", "錎", + "钬", "無", "嬉", "笞", "蹴", "视", "雇", "创", "椟", "6", "瘁", "斜", "傥", "喃", "炷", "秾", + "嘱", "茀", "犄", "窑", "庀", "潍", "伦", "䀲", "凉", "Р", "撻", "萜", "二", "倨", "蔑", "捕", + "勚", "士", "鈇", "踺", "啤", "彧", "缪", "述", "傅", "颅", "畸", "畜", "滗", "慭", "琎", "斌", + "参", "胳", "骖", "稠", "汰", "铻", "闯", "留", "蘘", "沏", "亦", "择", "華", "禽", "砟", "祼", + "狃", "噫", "狼", "寤", "跪", "浠", "·", "费", "瓘", "鼹", "锪", "箢", "垣", "慊", "虏", "秩", + "偉", "镏", "钯", "恐", "鹃", "菇", "炸", "潮", "蟀", "硂", "偌", "哏", "验", "桉", "阴", "初", + "掴", "鹺", "峨", "赋", "舉", "裹", "赶", "土", "淋", "瘌", "沔", "r", "赀", "淖", "茯", "怛", + "谜", "洗", "似", "舡", "纳", "晓", "R", "诐", "痹", "漪", "顺", "挛", "阎", "贝", "钰", "惬", + "疬", "菀", "埘", "怙", "部", "译", "鲭", "窋", "敢", "夜", "撰", "珅", "特", "襕", "癖", "胡", + "⒃", "附", "擘", "痢", "尬", "鉴", "瞋", "膨", "阽", "挲", "⒄", "骎", "帕", "缕", "计", "障", + "鳆", "隹", "朔", "碹", "当", "迦", "氙", "蘑", "妓", "炬", "苊", "萎", "浈", "沥", "绯", "壤", + "噱", "蹾", "驶", "葱", "孕", "羹", "钻", "農", "勝", "膈", "灿", "赆", "靿", "耱", "陪", "忙", + "缰", "奶", "儒", "个", "朱", "燹", "琮", "轷", "錾", "箅", "澳", "嗥", "攥", "没", "匿", "鲆", + "|", "矣", "他", "鸶", "芸", "B", "髑", "街", "巿", "廣", "盯", "監", "鲸", "胭", "凬", "寿", + "挝", "绽", "+", "劝", "究", "眢", "集", "衙", "卷", "j", "跶", "牡", "畯", "貅", "销", "發", + "咱", "蓊", "揣", "咝", "琶", "荦", "阌", "盅", "嘹", "苟", "醮", "洪", "鲧", "钒", "柱", "氨", + "旰", "冽", "茭", "嵇", "粲", "蛾", "訾", "辔", "N", "尹", "趿", "蹲", "疟", "祠", "段", "車", + "网", "⒉", "舷", "廐", "侣", "棵", "粜", "觐", "铼", "锁", "兒", "舁", "时", "垦", "版", "摈", + "扳", "见", "腮", "嫖", "痭", "呆", "簖", "伋", "鳙", "珊", "麂", "既", "谴", "热", "超", "蠕", + "铞", "e", "殓", "因", "锿", "文", "禊", "皙", "鑙", "爹", "鋼", "忻", "秣", "镁", "奠", "橉", + "畺", "笮", "疹", "湝", "龟", "殃", "毵", "溃", "勢", "索", "砉", "阼", "堞", "酥", "冁", "喊", + "¥", "幛", "娇", "锲", "蕃", "铘", "铍", "鴿", "响", "傲", "脏", "杓", "罕", "笥", "弦", "但", + "缃", "扬", "盲", "碚", "幢", "鎖", "缺", "钋", "麽", "禳", "浃", "啄", "昧", "蒴", "帙", "琏", + "咧", "舰", "亵", "浊", "豳", "衲", "俏", "镵", "浩", "勾", "槛", "榈", "徙", "鹤", "洹", "铂", + "揎", "棕", "挦", "挫", "阆", "衹", "甚", "近", "】", "簏", "汽", "踮", "淌", "檇", "痔", "谝", + "钙", "蕞", "蔯", "兆", "蔽", "后", "蚬", "谸", "芟", "枞", "叫", "栗", "餘", "营", "郝", "氯", + "㺃", "狍", "冏", "庛", "纱", "泼", "碍", "认", "邓", "茵", "饧", "闟", "惝", "裙", "噙", "忘", + "虬", "群", "S", "佗", "恼", "坟", "肮", "皮", "玃", "在", "赧", "孚", "偾", "镨", "恨", "葡", + "西", "缞", "挠", "逃", "吾", "膪", "焦", "翘", "桧", "变", "渗", "繁", "際", "痘", "撼", "筅", + "坑", "前", "玑", "数", "融", "鲌", "讦", "窃", "鄌", "伾", "众", "攻", "彪", "锎", "焐", "殛", + "锊", "嗉", "枓", "抢", "鞠", "掩", "贾", "搔", "皁", "拶", "朗", "渺", "跛", "㛃", "鏾", "慥", + "杆", "沈", "戍", "豫", "楠", "爆", "汤", "昉", "耘", "缡", ".", "允", "揜", "责", "艟", "裁", + "喬", "砹", "鹣", "裼", "啉", "蛳", "酮", "听", "维", "阪", "獾", "浣", "訂", "瘿", "蜡", "泖", + "蔚", "貔", "致", "禨", "尓", "糺", "绐", "遯", "笄", "邦", "圈", "洟", "缟", "槲", "桹", "镓", + "骒", "髫", "暾", "像", "縻", "戊", "飧", "驽", "干", "万", "绕", "披", "雅", "桊", "卡", "贲", + "吡", "沧", "鳟", "堂", "扺", "岱", "封", "鄭", "螣", "瞩", "幞", "邕", "睫", "涩", "自", "趱", + "愣", "威", "酊", "罂", "慑", "袴", "架", "烘", "现", "灞", "钔", "股", "興", "乍", "噜", "济", + "碛", "兀", "诅", "柴", "瓿", "[", "怿", "竦", "白", "黄", "阶", "务", "榮", "澹", "谏", "垓", + "跸", "繻", "窿", "紊", "陟", "劁", "嗑", "牯", "厉", "敛", "鮕", "嘉", "蔻", "鼎", "恒", "硝", + "溉", "骘", "窘", "任", "裱", "处", "旨", "舶", "缸", "囹", "笠", "讥", "泜", "脊", "煊", "淦", + "牝", "硕", "胧", "泚", "溪", "贪", "牛", "答", "瘴", "Q", "炯", "⑤", "篾", "銀", "乩", "杶", + "垆", "蛐", "苔", "啪", "y", "玮", "琫", "寮", "邂", "後", "僵", "贴", "硭", "枚", "姆", "乎", + "讶", "醭", "橥", "脱", "蒈", "擞", "忪", "顾", "柚", "褿", "忲", "辖", "铡", "螠", "殉", "喆", + "爡", "轮", "棰", "鲉", "跃", "韬", "睡", "嘧", "袅", "圗", "檄", "踊", "阀", "题", "桫", "林", + "沉", "禚", "散", "麇", "沦", "秋", "导", "斑", "宰", "嘞", "暑", "笱", "搋", "擅", "镤", "锶", + "L", "厣", "有", "猗", "袆", "绞", "甭", "歧", "跣", "潦", "専", "绑", "飱", "廓", "磔", "接", + "腓", "窎", "瑁", "飓", "蟪", "俎", "П", "缉", "䘵", "夙", "潟", "桷", "淡", "虺", "恶", "|", + "驭", "怀", "邋", "辢", "逻", "晖", "蜃", "蜊", "溻", "冢", "尻", "礼", "厝", "亘", "酴", "饔", + "悸", "戆", "什", "玚", "馔", "哔", "沃", "竑", "葭", "垞", "鏂", "抃", "弄", "去", "焊", "焌", + "x", "苇", "與", "炼", "蛄", "莴", "阏", "薷", "禀", "鸯", "栽", "冒", "姓", "0", "尃", "蜞", + "毗", "骟", "秸", "荸", "柈", "恬", "赡", "侏", "兑", "蝤", "荷", "徳", "押", "挣", "腰", "宣", + "鸵", "葳", "遘", "讨", "狒", "涿", "囤", "邃", "蒜", "疑", "脍", "嘟", "鹠", "吻", "鄹", "耦", + "华", "霸", "侥", "勒", "挞", "臊", "尺", "让", "榆", "阝", "鳚", "灾", "鲬", "艿", "Ⅱ", "锩", + "攮", "蚊", "蔁", "唝", "涅", "挹", "淏", "鏊", "氵", "鹕", "律", "對", "粱", "恫", "挻", "滏", + "叮", "‰", "鼯", "绫", "秉", "怩", "質", "岐", "菊", "佤", "帏", "骺", "爰", "珉", "耪", "乞", + "郕", "鲱", "雷", "蒿", "不", "啐", "侓", "郓", "歼", "拒", "胗", "寕", "旒", "勁", "婢", "诌", + "蹂", "姐", "媳", "歃", "拐", "辐", "拟", "醯", "雌", "点", "玟", "您", "鲨", "载", "藩", "罔", + "噀", "抹", "萏", "补", "蝎", "辈", "劢", "乚", "唔", "瓜", "恿", "蟭", "涸", "纬", "睽", "樣", + "帻", "蓥", "谯", "柯", "渴", "脁", "诲", "福", "③", "熊", "羌", "疴", "袖", "虿", "杏", "覌", + "易", "醾", "筒", "肤", "苷", "柃", "榇", "酬", "癸", "啰", "眛", "稷", "展", "鸾", "祢", "蝾", + "敵", "毛", "痦", "老", "赐", "单", "淹", "畋", "符", "奎", "绥", "轾", "鄺", "濩", "眦", "觎", + "忾", "璋", "刘", "翳", "菪", "簟", "胼", "孫", "機", "獻", "低", "o", "捅", "鳥", "⑨", "卸", + "废", "启", "呋", "窥", "巢", "揭", "咴", "趺", "鲥", "空", "膄", "崮", "锜", "络", "納", "恤", + "刭", "批", "霭", "氧", "钮", "甑", "祲", "粘", "辏", "∶", "臨", "│", "粪", "惰", "肼", "浉", + "橄", "5", "東", "8", "漁", "浜", "忍", "奂", "遹", "扃", "扦", "入", "欤", "豆", "悠", "蕴", + "萑", "媄", "龈", "÷", "磙", "鸬", "缎", "嗯", "浕", "木", "陋", "柰", "瘩", "箨", "松", "躁", + "鲇", "彰", "恕", "楗", "姨", "撅", "诹", "戮", "桓", "棉", "束", "嗍", "庋", "瞿", "郂", "哪", + "町", "a", "铁", "洫", "失", "栳", "篇", "鳗", "眇", "椿", "義", "就", "都", "镌", "阖", "夭", + "拃", "跚", "業", "圬", "演", "篥", "3", "昼", "從", "瞍", "蓦", "鼾", "坪", "觫", "鲍", "馿", + "妾", "密", "奥", "耰", "佟", "嘤", "貘", "薯", "稽", "届", "褛", "钠", "猿", "佈", "倍", "铩", + "铙", "踵", "o", "捱", "鹐", "當", "狷", "写", "遆", "钱", "姗", "寸", "综", "挑", "礶", "靼", + "溯", "湟", "漱", "碰", "职", "味", "Λ", "璁", "壴", "给", "碘", "恭", "苴", "酚", "套", "宕", + "辽", "窀", "催", "踢", "惟", "璧", "翔", "稿", "癀", "霈", "光", "膑", "妆", "庡", "圾", "躺", + "惮", "切", "目", "梦", "岫", "飑", "叠", "累", "鴻", "透", "量", "妻", "沨", "俪", "屣", "挚", + "w", "厅", "货", "箧", "漦", "隙", "瘥", "妃", "門", "鹦", "隳", "龆", "瞪", "跑", "帼", "刺", + "起", "鞴", "岸", "渫", "莽", "髭", "耜", "瑛", "葉", "宵", "绠", "眭", "畅", "茱", "卜", "濂", + "浍", "冈", "脬", "厘", "夔", "纟", "槚", "哐", "萋", "曼", "膳", "潲", "啜", "啊", "猾", "捉", + "箕", "㐂", "藝", "艘", "園", "妲", "灵", "蚌", "范", "&", "疥", "陑", "洒", "唾", "a", "婄", + "谋", "t", "唬", "宓", "瓷", "︰", "焗", "默", "噔", "菡", "恃", "亩", "边", "啟", "颞", "啬", + "盟", "墩", "汭", "缝", "魇", "酡", "疗", "梾", "尾", "鹿", "锔", "溦", "酃", "囊", "掉", "罥", + "报", "诤", "喹", "蕙", "割", "蠢", "兼", "俺", "升", "屦", "獠", "辣", "跹", "颧", "宪", "抬", + "咿", "沲", "旗", "荩", "傒", "鳳", "變", "偈", "薹", "钭", "垧", "谪", "躐", "谀", "R", "字", + "怆", "陵", "追", "迓", "舞", "卲", "捲", "麾", "税", "方", "竴", "壹", "射", "轫", "塞", "僧", + "椠", "突", "阕", "惫", "U", "佞", "秒", "友", "視", "莹", "攒", "荻", "俅", "筐", "能", "刓", + "拍", "浥", "揽", "谨", "军", "巷", "怵", "额", "恪", "荀", "糍", "湎", "褙", "觇", "效", "估", + "噩", "恍", "聚", "涛", "式", "兜", "汔", "祃", "銘", "烺", "瑄", "枘", "丁", "樗", "堙", "窗", + "號", "鬣", "阈", "乳", "簇", "绳", "淞", "]", "征", "聩", "凸", "礓", "柘", "懂", "㧎", "纷", + "里", "爸", "靥", "莞", "馅", "仞", "芏", "莳", "殪", "煌", "落", "佚", "帱", "诶", "家", "将", + "浯", "抿", "讫", "趸", "筢", "绩", "原", "专", "滂", "嗳", "踬", "泱", "體", "蜱", "绵", "伻", + "埗", "妤", "蔺", "赳", "嘢", "梨", "鹪", "烤", "镦", "赉", "崞", "蚰", "骝", "幅", "汴", "丽", + "访", "叩", "羼", "亓", "恸", "燥", "笤", "丑", "枰", "守", "蜚", "戈", "高", "q", "瓻", "隘", + "H", "南", "剎", "扭", "骠", "孜", "园", "锬", "审", "¥", "罚", "购", "裰", "泔", "醌", "醒", + "绎", "莪", "掬", "睾", "鹁", "蛊", "票", "剃", "释", "调", "黛", "撩", "篱", "茌", "敓", "蜜", + "魉", "鳤", "昽", "俳", "辁", "键", "犯", "嶙", "狈", "邬", "枋", "婊", "憎", "督", "救", "措", + "足", "码", "栟", "虼", "棻", "阅", "肊", "坛", "鸱", "侩", "烫", "湉", "脐", "戾", "旎", "膚", + "椒", "境", "绛", "濛", "蓄", "章", "压", "窦", "彖", "阜", "咻", "神", "存", "诺", "課", "覺", + "鲈", "渚", "「", "缢", "仓", "氅", "筇", "桴", "荥", "些", "纯", "肋", "退", "妪", "别", "書", + "租", "嚼", "芘", "笳", "涰", "馐", "熵", "犹", "朕", "猪", "蔸", "參", "觳", "舖", "蝙", "骏", + "织", "躏", "纹", "锹", "蛉", "撑", "氽", "茶", "俛", "誠", "胖", "崽", "炫", "乘", "把", "趑", + "谵", "骧", "犍", "鸮", "灌", "焯", "倭", "狁", "盱", "踱", "滠", "儡", "诸", "芽", "駆", "蹼", + "虱", "祇", "\\u3000", "蠡", "衄", "谬", "蒍", "婺", "蘧", "博", "捍", "磁", "慷", "釂", "蛩", + "钕", "祎", "呑", "贫", "斗", "菅", "操", "规", "硼", "惕", "丫", "俭", "肿", "骀", "砼", "句", + "茛", "闶", "钏", "饻", "圠", "萌", "魏", "铃", "摞", "┅", "伎", "獭", "田", "钴", "峭", "魅", + "捋", "唼", "鹅", "祚", "嬷", "圖", "抄", "嶂", "鸳", "溧", "钵", "嗽", "墠", "锌", "愈", "併", + "踟", "羯", "翅", "纠", "勻", "岚", "菖", "便", "祈", "毳", "屹", "掰", "倬", "扛", "巴", "拮", + "绁", "跌", "飯", "嵯", "翮", "堤", "诃", "腑", "皆", "鄂", "胾", "片", "这", "浙", "雨", "鼱", + "袼", "鹊", "厢", "蛣", "摇", "蛮", "揍", "⒅", "啱", "薇", "岈", "兔", "谇", "纶", "肉", "崩", + "甩", "涪", "馼", "铣", "锚", "丙", "雲", "烹", "钦", "撄", "铬", "令", "虮", "湊", "禹", "抖", + "喏", "旺", "畲", "戬", "嗷", "釜", "车", "缀", "玕", "谐", "啁", "怎", "下", "惑", "恅", "藿", + "筰", "帐", "祸", "镝", "喵", "刁", "习", "藏", "墓", "护", "聲", "箦", "严", "按", "谛", "睨", + "艚", "歉", "蟮", "胶", "盍", "鳃", "狯", "垫", "杠", "线", "3", "葖", "t", "熬", "虞", "嶶", + "篮", "黻", "墒", "氟", "嫠", "漕", "腾", "哟", "玫", "撇", "垍", "靛", "翼", "淅", "省", "斥", + "稞", "蠼", "谩", "埠", "蘸", "刊", "烝", "宁", "鹚", "龊", "苪", "袷", "诧", "细", "蒌", "焅", + "2", "筹", "扒", "卮", "捞", "净", "菲", "逮", "槍", "蛎", "莱", "黠", "逖", "辚", "剥", "啴", + "诿", "楱", "氪", "领", "嗒", "藐", "惜", "甘", "佾", "嵴", "胫", ";", "晳", "锣", "瞅", "缷", + "耶", "搤", "策", "咽", "邀", "霾", "悟", "属", "鸪", "牴", "贞", "趁", "丞", "瘆", "豌", "著", + "饿", "筠", "划", "璇", "损", "卵", "腒", "畏", "盥", "耐", "圏", "拓", "蒙", "鋫", "劙", "蹦", + "熘", "烊", "匏", "咔", "轘", "沽", "菩", "罴", "磉", "炖", "假", "枪", "龙", "俸", "焱", "四", + "─", "毫", "涨", "浇", "椰", "賣", "蘇", "真", "安", "坝", "枕", "鸼", "昵", "亨", "苤", "祷", + "枧", "赟", "菑", "鳂", "戌", "悄", "種", "鳢", "嗣", "電", "颥", "妯", "谟", "蜒", "训", "泍", + "洁", "勇", "哿", "扰", "蟆", "螂", "刃", "絜", "曪", "乒", "湖", "鞨", "懜", "夤", "哓", "胥", + "桞", "俇", "肣", "半", "于", "橼", "锑", "熙", "甜", "槌", "盾", "屃", "缗", "共", "碗", "凇", + "笔", "阿", "擗", "袍", "敉", "钾", "俶", "蚪", "琤", "凱", "辕", "à", "恣", "皴", "創", "寥", + "妳", "腈", "畤", "迤", "垠", "触", "趙", "铤", "逊", "羊", "碉", "锱", "骨", "仄", "斟", "俚", + "啡", "芩", "迫", "杷", "种", "鹄", "牗", "耑", "艇", "芰", "整", "慙", "飛", "甓", "岩", "鸦", + "黎", "僊", "糁", "谈", "洋", "椑", "健", "〕", "內", "言", "掷", "倚", "姬", "矿", "灯", "阐", + "凋", "銮", "豇", "瑰", "抓", "噪", "堋", "吁", "妈", "庥", "彳", "鄗", "闩", "夫", "0", "庠", + "悬", "妙", "琵", "着", "首", "熣", "瞰", "揆", "燚", "条", "姜", "滘", "麓", "鳉", "椀", "蓿", + "廠", "泌", "蝈", "倕", "丛", "耍", "且", "蝇", "凉", "豐", "泪", "臼", "服", "刍", "織", "渎", + "尥", "甙", "埋", "珏", "援", "祖", "彊", "臱", "惦", "葴", "礁", "达", "橋", "钨", "崦", "醐", + "巳", "中", "颜", "溠", "铹", "负", "抠", "愎", "罘", "雩", "胝", "冱", "筵", "篙", "材", "肓", + "○", "迅", "腼", "橙", "仵", "茏", "慵", "齌", "琯", "疃", "貢", "豉", "瞟", "忉", "禄", "通", + "咒", "愫", "秕", "筜", "觖", "州", "渑", "胆", "喑", "張", "衖", "洺", "眉", "榞", "色", "邶", + "攫", "堑", "淬", "嗪", "肐", "殣", "辊", "隧", "献", "潤", "蓺", "函", "鹱", "轭", "劭", "椁", + "膜", "亹", "侧", "貂", "哚", "磴", "蠋", "囔", "险", "伶", "世", "菥", "莶", "瘾", "燫", "延", + "∵", "毋", "羧", "无", "雎", "曛", "沚", "巍", "g", "熄", "恰", "伷", "開", "冻", "颛", "支", + "⑦", "鞥", "赖", "试", "泮", "联", "沮", "穰", "è", "峻", "滿", "豊", "刎", "鴈", "覆", "串", + "锃", "春", "储", "矍", "哺", "评", "猁", "愉", "疳", "閃", "奄", "甲", "墦", "頭", "锫", "俦", + "玩", "搀", "砭", "流", "橇", "泅", "琇", "趣", "∧", "辑", "灊", "貴", "迮", "摹", "霄", "濟", + "限", "彀", "匪", "缂", "觚", "奇", "诋", "灼", "萘", "狠", "澥", "岂", "悺", "闾", "麋", "号", + "槽", "姹", "陉", "瑯", "尉", "h", "绖", "宿", "戋", "粝", "砂", "该", "鞧", "翯", "釘", "铢", + "窨", "設", "⒆", +]; + +pub const CHARSET_BETA: &[&str] = &[ + "", "笤", "谴", "膀", "荔", "佰", "电", "臁", "矍", "同", "奇", "芄", "吠", "6", "曛", "荇", + "砥", "蹅", "晃", "厄", "殣", "c", "辱", "钋", "杻", "價", "眙", "鴿", "⒄", "裙", "训", "涛", + "酉", "挞", "忙", "怍", "︰", "镍", "檐", "眯", "茓", "辖", "淩", "啟", "蜀", "芟", "裟", "楝", + "彘", "嶪", "费", "亞", "滁", "榉", "朝", "f", "倻", "裎", "谧", "崂", "卑", "助", "触", "氐", + "锟", "铢", "膪", "脐", "渲", "荫", "佾", "琯", "钣", "珰", "翦", "膻", "娥", "浥", "淄", "猸", + "内", "消", "粞", "反", "苪", "冽", "酵", "玩", "父", "存", "屯", "殷", "俐", "篱", "俛", "塮", + "苕", "耲", "输", "壖", "溶", "琤", "氏", "真", "黩", "瑄", "阶", "茔", "眩", "浙", "痄", "噔", + "烤", "楯", "²", "铆", "裈", "偬", "盏", "祐", "伯", "庙", "獯", "榀", "裒", "综", "蒸", "架", + "蜱", "鹖", "涴", "肌", "廖", "祾", "蔗", "破", "!", "鑫", "瓷", "H", "宛", "倪", "贝", "酝", + "倞", "榼", "菊", "帕", "胍", "淌", "抨", "倕", "味", "独", "à", "庐", "蹲", "肸", "洹", "騳", + "绖", "觉", "蝙", "铜", "選", "郚", "奄", "手", "篦", "忮", "潺", "歁", "湖", "貔", "缚", "癫", + "捣", "翎", "勇", "徒", "杪", "捃", "纴", "郞", "蛱", "浓", "講", "薇", "汊", "彻", "琖", "觇", + "驩", "野", "闺", "彩", "膊", "簸", "瑭", "龏", "栓", "攸", "堕", "鹿", "檠", "锽", "晟", "煊", + "衖", "p", "L", "侞", "吹", "岵", "捡", "邃", "曩", "泼", "娌", "磙", "鞮", "號", "苤", "骁", + "感", "氙", "榜", "菟", "蠲", "∶", "焌", "漯", "胪", "以", "剜", "=", "衰", "剔", "疏", "韩", + "邋", "探", "搌", "握", "舵", "腰", "咐", "郎", "鈺", "赴", "斩", "铥", "棂", "褫", "秾", "城", + "葬", "缺", "甓", "沙", "鴨", "恧", "吩", "膈", "俗", "引", "濑", "坛", "蛘", "谍", "飘", "鎚", + "貋", "袅", "圃", "肽", "祖", "瑢", "鄣", "卡", "恸", "饷", "撖", "阖", "碌", "墉", "⇋", "抗", + "僇", "撩", "狷", "静", "荽", "憯", "虻", "滹", "簧", "Y", "汾", "嫁", "蚴", "岈", "榔", "邶", + "挛", "火", "w", "旌", "線", "3", "跏", "F", "楸", "瞬", "證", "現", "符", "鲀", "窸", "朗", + "m", "劉", "襄", "鸻", "敖", "憩", "濛", "胶", "雏", "禽", "缜", "鐀", "澄", "泉", "懈", "鹟", + "牙", "叟", "镖", "膨", "硷", "钏", "嵌", "冲", "橪", "厨", "溘", "妻", "贺", "耀", "潲", "瞳", + "惺", "涑", "鄄", "舡", "战", "钹", "盍", "窀", "凳", "锋", "(", "绤", "翻", "》", "嶷", "戛", + "照", "设", "两", "霹", "風", "格", "栖", "椹", "№", "蔌", "达", "悠", "旒", "函", "抔", "逆", + "疙", "玫", "箢", "恩", "樘", "远", "考", "荭", "殒", "靡", "蝾", "舅", "䀲", "偾", "灿", "埴", + "瀍", "特", "诸", "搦", "恒", "妊", "课", "劂", "殊", "艋", "柚", "硕", "捅", "钍", "芘", "脖", + "襁", "募", "卅", "疆", "嫖", "黹", "臀", "豇", "瘗", "憎", "嗯", "Θ", "跺", "喧", "捺", "爪", + "鲠", "縠", "屋", "撑", "者", "娶", "喝", "墼", "丶", "茚", "髅", "瓢", "农", "橼", "攰", "折", + "诋", "镒", "赂", "捲", "耑", "沐", "窜", "亰", "煌", "阕", "羯", "纤", "滇", "值", "琥", "渴", + "祗", "鳌", "蛞", "庄", "鹇", "訄", "犷", "弋", "琐", "佗", "氛", "揄", "旺", "聱", "榨", "湿", + "蟥", "湎", "敕", "轷", "耿", "三", "運", "瑶", "困", "勁", "蚱", "泸", "螫", "斜", "蟠", "轨", + "镞", "霆", "嶙", "烷", "瘩", "敦", "塾", "僚", "澙", "關", "酩", "殴", "—", "例", "筷", "乘", + "颗", "核", "孬", "舣", "糇", "劾", "黧", "镌", "罅", "X", "仅", "哐", "蟊", "呻", "呕", "粟", + "配", "伊", "槊", "昌", "宰", "盘", "肫", "鳥", "圾", "恬", "辘", "绿", "時", "丐", "扃", "敓", + "摄", "陕", "滿", "鹆", "嗬", "龅", "渣", "釣", "萦", "督", "孑", "∧", "疥", "噱", "蝎", "君", + "笮", "泌", "镔", "称", "柘", "鬣", "罨", "潍", "垣", "顔", "褶", "礓", "△", "骐", "湍", "獾", + "羖", "戾", "预", "祭", "鹨", "凤", "茕", "珏", "蛊", "毛", "枰", "鄭", "娲", "丕", "蜜", "纟", + "蛹", "粮", "嚰", "嚓", "螨", "裰", "G", "集", "删", "郜", "舻", "嵛", "鵰", "腊", "峄", "脸", + "鲺", "坢", "寞", "撰", "顸", "枋", "荠", "夡", "豆", "馆", "赭", "傎", "淼", "镪", "許", "礌", + "带", "訂", "饧", "锜", "及", "漾", "編", "究", "仍", "糜", "喳", "嗝", "醦", "堅", "企", "烔", + "图", "垲", "枥", "畿", "踱", "槟", "◆", "酽", "溢", "酥", "谚", "缨", "死", "镑", "干", "用", + "紊", "坑", "副", "枭", "琮", "鸨", "獻", "弈", "伺", "醍", "氓", "宁", "臻", "贾", "啐", "玉", + "咀", "孀", "烆", "嘱", "频", "蜥", "楡", "瞩", "委", "锺", "赀", "睬", "旅", "刿", "韪", "抹", + "鞘", "x", "钝", "倌", "奖", "蟭", "灌", "肼", "曰", "啊", "属", "唐", "彦", "煦", "鄘", "坦", + "鬻", "告", "单", "菽", "匏", "浚", "仺", "怜", "拦", "鸡", "拄", "乍", "燠", "暧", "竭", "⒂", + "济", "Ⓡ", "趑", "舴", "体", "拒", "罂", "说", "猎", "闫", "鄗", "妲", "鑙", "葶", "匍", "等", + "略", "盲", "唔", "钰", "渠", "镦", "葫", "蹒", "姘", "婵", "夯", "实", "何", "株", "锌", "礁", + "桺", "捉", "鮕", "莓", "轶", "辉", "溋", "视", "嗒", "猞", "猁", "杓", "怡", "咴", "巷", "仂", + "婉", "睛", "?", "淡", "/", "郛", "绨", "较", "毁", "沓", "瞎", "馏", "蕙", "戏", "i", "董", + "臣", "鹫", "栳", "锹", "裕", "蜷", "唣", "9", "缂", "螬", "笥", "惶", "蚰", "徨", "忭", "传", + "绛", "离", "锑", "候", "拓", "德", "损", "附", "紡", "徕", "錾", "蕻", "⑧", "構", "镊", "脘", + "靸", "涒", "镡", "光", "廒", "尴", "荥", "佳", "弼", "暮", "榆", "鼑", "辅", "钆", "湝", "佤", + "瘌", "炽", "筰", "嗈", "電", "飙", "坶", "椿", "俾", "灊", "泵", "像", "咅", "樓", "苒", "烨", + "溺", "棽", "戒", "箅", "愔", "缢", "楞", "庤", "塑", "湮", "沽", "蝌", "赌", "薨", "锾", "圜", + "骥", "秉", "瞌", "惇", "诊", "圣", "睢", "我", "廰", "苠", "襻", "鲚", "酮", "厮", "评", "沈", + "愀", "垞", "习", "敷", "比", "欢", "尚", "钪", "卣", "她", ",", "伴", "赃", "蚬", "喇", "醇", + "嚅", "T", "姝", "鍊", "悯", "N", "抚", "颡", "獐", "趟", "洑", "缝", "喁", "帷", "憷", "获", + "阉", "镫", "臨", "炮", "奴", "揩", "叩", "恺", "粱", "胁", "憬", "痿", "´", "沘", "彀", "饩", + "滋", "竑", "嗑", "鸟", "T", "璠", "快", "銀", "舶", "羞", "桞", "飛", "茹", "師", "偌", "節", + "冁", "叡", "臑", "踔", "酔", "養", "溦", "岐", "豉", "杌", "胩", "仳", "沾", "窑", "曳", "闷", + "垢", "垆", "磨", "髹", "態", "丽", "見", "洃", "遣", "场", "铭", "溉", "衬", "橦", "详", "馊", + "濂", "瑾", "鲫", "贞", "搴", "胺", " ", "景", "执", "袴", "炖", "箭", "楂", "婚", "镧", "厩", + "宣", "缣", "跃", "痘", "亓", "宦", "豪", "侣", "郧", "與", "痳", "挚", "殻", "嘢", "洽", "蹉", + "孽", "森", "俚", "八", "砹", "凹", "訇", "屹", "啰", "宴", "廨", "沇", "麇", "泅", "绡", "辛", + "鹲", "鋆", "旮", "婀", "幔", "赞", ":", "永", "活", "萸", "霉", "←", "媲", "阚", "鲮", "佝", + "獒", "圹", "隋", "征", "蚶", "龊", "搀", "嫫", "鬏", "幞", "學", "然", "沧", "萑", "襜", "撻", + "苯", "狳", "鞠", "咋", "壹", "栅", "款", "镘", "阳", "蚜", "荬", "糊", "疳", "糕", "镵", "寐", + "褴", "v", "醋", "诀", "汰", "啸", "备", "娘", "氚", "镓", "室", "簟", "硝", "嘌", "釐", "争", + "男", "疬", "鹄", "艳", "倒", "忸", "庶", "葒", "岖", "涨", "羝", "诼", "纨", "纰", "扉", "酎", + "藉", "疮", "枞", "黜", "戮", "芽", "鳑", "末", "蒿", "茈", "透", "渊", "秷", "〈", "试", "络", + "羼", "滪", "奋", "虏", "脁", "沫", "蓰", "襆", "披", "鲌", "艚", "逹", "炳", "泔", "叹", "轳", + "锵", "嫜", "佥", "严", "迅", "筠", "逵", "铿", "钇", "拇", "诏", "绯", "吊", "纠", "蟾", "c", + "涝", "汩", "盐", "跋", "拤", "邹", "镨", "羚", "龆", "脊", "攉", "傕", "短", "團", "蹬", "嘤", + "奎", "熨", "芪", "鸢", "濉", "''", "莴", "義", "赜", "踺", "皂", "努", "偏", "狡", "遭", "吞", + "嘿", "婊", "媸", "增", "殿", "刮", "燘", "劫", "娜", "瞄", "寡", "优", "捋", "佴", "菰", "蓠", + "笙", "镃", "樇", "瘫", "B", "橇", "逯", "堍", "О", "磐", "腼", "て", "送", "狭", "皓", "亡", + "嗉", "菠", "顺", "連", "嶶", "瑪", "辟", "婷", "牛", "笫", "窅", "萁", "戟", "覃", "馍", "建", + "謇", "旘", "镣", "燏", "葉", "轺", "倏", "堪", "见", "葛", "钕", "键", "押", "僊", "槐", "戎", + "窨", "洙", "鲢", "鞒", "慒", "雁", "圭", "D", "陌", "肱", "蜿", "洧", "惑", "祛", "樟", "矧", + "呵", "峻", "凝", "蕨", "拯", "珮", "塥", "展", "贻", "囐", "弱", "庳", "嫔", "緣", "呈", "策", + "漉", "瑗", "鲂", "鹂", "吾", "灶", "并", "挲", "重", "奭", "皙", "侪", "埗", "烬", "纾", "椒", + "技", "ɔ", "擀", "恍", "遨", "订", "雨", "卵", "锏", "猗", "癸", ")", "谡", "稷", "枨", "蹽", + "荑", "沅", "稽", "間", "冉", "颇", "酺", "份", "瞾", "毯", "藥", "蕞", "狲", "吡", "慷", "卯", + "摽", "肿", "嗛", "悒", "丨", "横", "鳡", "仫", "狎", "砗", "聿", "腥", "酡", "飱", "柳", "遽", + "汇", "湔", "麋", "垃", "粽", "坷", "鳗", "迫", "丢", "\"", "⒀", "嗲", "肐", "結", "署", "飨", + "蠡", "涩", "挈", "浿", "鐾", "姞", "隧", "铘", "呜", "蜕", "鷄", "逼", "哌", "病", "係", "偿", + "Ⅲ", "埋", "妤", "赘", "悉", "陷", "沸", "呲", "誓", "舆", "髀", "挫", "羑", "据", "顿", "淝", + "抟", "珧", "郑", "仗", "怛", "掠", "稳", "尥", "祙", "找", "郐", "锔", "轹", "钓", "黙", "饸", + "谌", "斐", "龙", "噫", "駆", "浼", "峒", "育", "纣", "溠", "铊", "亨", "杮", "呓", "钌", "业", + "繻", "溪", "戌", "蓿", "椱", "悱", "仉", "阮", "芈", "濋", "搔", "纽", "琛", "趄", "双", "镯", + "☆", "敉", "啬", "讦", "娱", "爾", "遶", "漱", "郗", "锪", "颃", "靰", "醊", "驊", "呢", "術", + "妙", "蚣", "溽", "酇", "巾", "舐", "却", "废", "邾", "砣", "乙", "鲜", "蒤", "囍", "璈", "稔", + "蘘", "匐", "業", "碟", "渺", "贤", "绋", "畑", "颞", "侥", "盟", "鼍", "阊", "蔽", "标", "吮", + "淬", "鏾", "圗", "夜", "乕", "娇", "瞿", "循", "讲", "懒", "熘", "禚", "观", "钷", "万", "n", + "未", "藝", "愿", "圈", "浩", "伦", "扛", "暄", "饶", "梧", "欣", "咿", "檔", "吼", "妮", "覆", + "辰", "誤", "允", "危", "硗", "惫", "瘪", "李", "焱", "沣", "坯", "穄", "归", "画", "营", ":", + "色", "哔", "矢", "巯", "祆", "傍", "享", "悻", "取", "凫", "铒", "唅", "眈", "疹", "败", "晴", + "顼", "绶", "剃", "斗", "禾", "4", "誜", "俨", "2", "患", "结", "可", "帇", "抍", "筝", "衢", + "鹛", "跸", "颢", "钾", "渡", "棒", "丛", "皱", "梓", "将", "压", "#", "岛", "?", "砺", "过", + "党", "挣", "瞋", "谶", "妯", "羡", "化", "淫", "歪", "鼗", "阄", "蔓", "烩", "餘", "猊", ".", + "畯", "祧", "狒", "碁", "咛", "鲈", "叨", "哞", "5", "娈", "半", "免", "拿", "畎", "媾", "棚", + "丈", "周", "匋", "酯", "奚", "爇", "摇", "搭", "蓇", "陽", "岢", "禤", "藠", "雅", "哲", "弹", + "按", "↑", "蹀", "察", "螾", "渎", "褂", "觳", "耍", "皲", "骗", "箫", "蕺", "亚", "保", "棵", + "放", "踪", "了", "熣", "亦", "痛", "币", "馐", "夢", "诱", "梱", "鲰", "郕", "璜", "祯", "颦", + "走", "踣", "嫚", "旯", "雲", "湟", "墨", "笃", "肇", "撝", "腦", "账", "舞", "⑨", "噻", "幂", + "僵", "崦", "’", "牢", "号", "嫡", "囱", "肥", "代", "锶", "掏", "随", "棓", "殉", "嘅", "掰", + "功", "垛", "踶", "娠", "霜", "碣", "鲼", "伉", "凄", "骋", "鹞", "洺", "乌", "赧", "瑛", "黎", + "曚", "鲴", "髫", "瘴", "藏", "雍", "畐", "蔻", "爼", "蹴", "巨", "贱", "汜", "胡", "虬", "椎", + "逸", "魇", "亶", "Φ", "忆", "赉", "塞", "潢", "垌", "简", "鼹", "發", "枢", "麝", "虹", "惭", + "唛", "春", "瑟", "郰", "桡", "捩", "堙", "嗨", "驳", "F", "荪", "忑", "贪", "躅", "步", "揜", + "闪", "垟", "晶", "分", "韭", "戴", "泪", "啧", "機", "峙", "和", "鸱", "绎", "屠", "阋", "黍", + "淸", "萩", "汉", "吐", "匙", "铗", "蠔", "簠", "鲵", "须", "蛣", "躏", "完", "咻", "釜", "馼", + "崤", "欻", "珐", "于", "郅", "焓", "轴", "递", "堰", "嗷", "儇", "壕", "嘟", "酸", "庾", "龂", + "妍", "锅", "雳", "桦", "抬", "谄", "气", "六", "诎", "绀", "张", "復", "客", "荞", "鳚", "衔", + "亁", "昂", "漤", "鞚", "筘", "绫", "彝", "枪", "苊", "榟", "饺", "苦", "顶", "衷", "聚", "寮", + "揆", "轪", "栋", "臂", "葖", "颋", "镐", "愕", "贸", "Q", "琼", "糥", "世", "莪", "龁", "禁", + "绲", "陶", "弑", "黢", "铵", "睐", "沄", "紬", "防", "癣", "曾", "钉", "纶", "膘", "句", "莸", + "踝", "躐", "酤", "腑", "雄", "堤", "喀", "姣", "孢", "阡", "褐", "胂", "髙", ";", "骖", "膺", + "糙", "辢", "⒃", "险", "砻", "缫", "骎", "低", "蚵", "箐", "苞", "劭", "峪", "工", "盈", "腹", + "袄", "祉", "癔", "笨", "R", "乚", "畏", "虍", "臾", "泛", "噙", "杷", "麗", "蹋", "逍", "迓", + "摅", "页", "戥", "胞", "艄", "壅", "啶", "趼", "牟", "翙", "蓝", "府", "轿", "砼", "荜", "杆", + "惊", "起", "瘅", "墈", "氖", "匀", "麃", "阘", "虮", "蘇", "蚤", "汗", "鳞", "籁", "缲", "畈", + "亟", "劬", "課", "蓄", "缅", "楮", "湜", "珩", "斋", "塬", "殁", "魃", "脞", "H", "澼", "钚", + "饕", "缕", "Ⅱ", "攮", "卿", "莅", "镆", "熹", "藩", "汁", "順", "趿", "拆", "蟹", "砒", "惴", + "㎡", "忖", "寝", "戕", "螭", "酿", "™", "柬", "枧", "凶", "蚁", "島", "殄", "鲊", "忠", "肉", + "辕", "叫", "徙", "漆", "缞", "夀", "楦", "佪", "兴", "粉", "裳", "蘧", "國", "旬", "看", "Ⅰ", + "剑", "痭", "襟", "恐", "遹", "◎", "窃", "穰", "澎", "敬", "旱", "燚", "坩", "彤", "尜", "猃", + "夏", "穈", "媒", "柑", "駡", "孛", "脉", "车", "零", "菩", "痊", "卉", "桔", "距", "吧", "漦", + "启", "仁", "滬", "馋", "帅", "鳈", "鄌", "超", "芡", "窘", "刽", "掌", "氤", "梽", "拎", "踏", + "勋", "甍", "玑", "稱", "鞍", "浍", "翅", "饟", "鼎", "罩", "加", "虚", "蕰", "簉", "堇", "巢", + "疲", "蟑", "狝", "瓮", "潋", "行", "饥", "散", "糌", "牵", "貢", "偉", "咄", "痕", "沃", "苓", + "锂", "狻", "褿", "畸", "姿", "煎", "胜", "觅", "烊", "質", "疵", "擢", "椤", "米", "累", "诳", + "斡", "K", "恻", "匦", "烫", "湾", "鹎", "吟", "摘", "涞", "恿", "嫉", "炎", "婧", "朽", "铑", + "ㆍ", "讧", "曜", "挑", "〇", "搅", "鹐", "丁", "彼", "棠", "饪", "箬", "祎", "魄", "囿", "犬", + "市", "髃", "勚", "桶", "辎", "瓞", "财", "缄", "園", "睒", "护", "尿", "融", "围", "水", "糍", + "虢", "呦", "越", "棺", "砮", "邓", "鹦", "稣", "呃", "柙", "鎌", "转", "袋", "湉", "亘", "俩", + "腆", "谣", "飔", "撂", "鄳", "爲", "盦", "谳", "卸", "W", "嚆", "婕", "卫", "拚", "呀", "汽", + "洣", "冻", "鳝", "录", "毋", "閥", "熬", "谜", "齐", "匳", "慧", "猴", "撬", "妳", "諾", "蠼", + "瘟", "伐", "颤", "奶", "陧", "麾", "岌", "浇", "邸", "「", "不", "哼", "热", "旳", "慙", "&", + "苔", "郿", "钗", "氡", "纹", "侬", "霓", "靈", "扁", "聢", "疼", "岣", "甥", "恭", "喷", "芫", + "骂", "肪", "熥", "揠", "鲷", "遁", "霎", "娆", "圩", "爬", "傲", "贽", "紫", "觑", "琇", "蟆", + "怙", "玙", "庼", "筮", "慗", "层", "娓", "蚨", "糟", "璩", "隼", "锧", "疱", "铎", "祠", "绁", + "速", "湛", "蝮", "立", "媵", "禇", "撸", "禳", ">", "恋", "⑥", "鹡", "蓑", "樱", "奸", "蝣", + "埭", "聪", "慭", "睑", "肢", "焗", "骃", "毵", "潼", "塘", "烧", "劓", "栾", "牯", "〉", "毓", + "釉", "庞", "宕", "磚", "夺", "畜", "俏", "筼", "虱", "釆", "计", "陀", "诧", "臱", "牌", "固", + "鹉", "凰", "擞", "■", "㛃", "词", "店", "當", "许", "妣", "耋", "硼", "根", "焅", "砸", "霈", + "锃", "巳", "誉", "咕", "锊", "P", "云", "乞", "为", "姆", "桕", "丞", "鳤", "楷", "醒", "趔", + "怔", "砉", "潏", "肝", "拷", "也", "璐", "厘", "致", "昇", "绥", "抃", "佩", "斥", "⑶", "断", + "纵", "翁", "耄", "沭", "洄", "别", "吻", "渍", "r", "愦", "替", "骓", "攻", "旦", "来", "案", + "坫", "辞", "班", "锝", "拜", "掎", "穸", "笛", "痂", "笈", "鲶", "僻", "依", "碎", "蕤", "炕", + "寥", "拔", "髑", "慨", "眺", "⑿", "珞", "歧", "湲", "錦", "拮", "哭", "爰", "验", "寸", "%", + "口", "阔", "积", "篝", "狴", "殂", "痧", "绽", "搪", "祸", "缘", "遯", "祜", "种", "缓", "冒", + "庵", "窥", "颂", "哕", "谘", "蜗", "掖", "驮", "郎", "跂", "蝓", "贲", "馔", "琰", "大", "芊", + "粝", "啻", "蒉", "谒", "羔", "蘑", "菑", "布", "徂", "l", "炬", "蘩", "弭", "嵎", "補", "岑", + "佯", "棍", "没", "志", "裣", "咸", "权", "豺", "韦", "優", "紧", "嚚", "牴", "酚", "沤", "睥", + "葆", "乓", "划", "犒", "惚", "埕", "锴", "就", "滓", "汕", "冏", "缵", "囟", "旸", "麂", "接", + "餮", "瓤", "偕", "灏", "溻", "揶", "钯", "荸", "宪", "泠", "槠", "抺", "威", "燴", "井", "骣", + "耜", "磔", "懜", "淇", "瘘", "蹼", "觏", "圬", "纔", "恤", "铝", "薏", "鞫", "衉", "E", "球", + "姽", "毹", "嵘", "睦", "蛉", "伽", "橥", "痤", "卞", "警", "则", "芬", "磉", "悢", "逾", "吆", + "朿", "锒", "卧", "E", "焉", "纥", "髦", "鞯", "牞", "蹿", "琪", "洌", "幛", "淳", "菲", "涔", + "噗", "勺", "势", "哓", "毪", "刖", "雜", "浪", "懵", "棁", "秋", "◇", "玡", "埯", "谥", "芑", + "拌", "Z", "埂", "寻", "虼", "豫", "蛄", "蜞", "椟", "〔", "哩", "絷", "咱", "郈", "湫", "抡", + "矮", "庖", "锰", "鎖", "葸", "棣", "砑", "题", "棋", "晕", "兠", "蓣", "貂", "裤", "昊", "扳", + "讴", "弩", "蚀", "尓", "暗", "莘", "黏", "寖", "蛔", "И", "痪", "饳", "妈", "Z", "秏", "矽", + "蘭", "艴", "菖", "寿", "撅", "秤", "颓", "廪", "醪", "耢", "螣", "椰", "麈", "听", "敞", "铠", + "润", "穑", "涟", "澹", "茨", "昨", "嚯", "钟", "護", "榇", "曦", "蜎", "呷", "邦", "瘵", "鲬", + "谖", "概", "九", "飞", "潇", "高", "锫", "钐", "徘", "诟", "缧", "剞", "【", "簋", "噍", "痋", + "关", "糁", "鹊", "潤", "邬", "赔", "序", "盤", "拙", "盾", "鸫", "迟", "氇", "塄", "庀", "噩", + "臃", "绔", "岔", "珠", "癀", "骡", "隶", "堋", "笆", "影", "昶", "飗", "α", "薄", "碜", "瞅", + "奠", "鲽", "牂", "裆", "刀", "遑", "隙", "沔", "訾", "旇", "s", "诮", "炱", "榚", "些", "縯", + "提", "甚", "埏", "峣", "意", "出", "郡", "摊", "哦", "轼", "嚒", "杈", "痢", "裥", "袖", "陔", + "溷", "裀", "迄", "枇", "筑", "貊", "鲃", "鸪", "V", "鞭", "粳", "菥", "盒", "毙", "风", "壽", + "胝", "章", "泄", "浜", "菇", "釘", "揖", "蝰", "榧", "掊", "瘿", "亍", "欤", "髻", "歃", "朱", + "撇", "铁", "兜", "喋", "趵", "瘼", "芤", "邳", "除", "滌", "么", "践", "矜", "曆", "炒", "咔", + "促", "姐", "酦", "货", "箔", "锡", "吝", "医", "汀", "精", "馘", "骶", "碉", "啷", "缉", "褪", + "阙", "滕", "蓐", "搏", "俅", "癌", "股", "圪", "孕", "鳕", "话", "鳳", "妩", "馬", "鞣", "璁", + "测", "螠", "圆", "颥", "卒", "钲", "䨱", "骢", "批", "陨", "婶", "熵", "鸣", "梁", "怅", "滑", + "驵", "帑", "鑽", "痈", "鲑", "犍", "茑", "糧", "谫", "咒", "绘", "塆", "耖", "铮", "殳", "角", + "齮", "挻", "捎", "2", "З", "廋", "泻", "犊", "儋", "椋", "聍", "鼬", "鳏", "收", "跞", "盥", + "信", "嘴", "眉", "黠", "纡", "Ω", "愆", "桹", "昽", "讠", "蚧", "龀", "鳓", "麓", "括", "蘊", + "鈇", "写", "焕", "哒", "忌", "咳", "蜮", "衄", "氰", "邘", "缇", "缮", "表", "续", "篇", "旄", + "闻", "門", "偃", "茳", "晗", "鋪", "讶", "衙", "闭", "管", "傒", "藔", "鳯", "萼", "泥", "汔", + "浆", "姚", "几", "含", "沆", "繇", "灾", "嗦", "饬", "系", "熠", "漶", "潭", "牲", "湘", "稁", + "宄", "亳", "杏", "豳", "監", "印", "旁", "辙", "播", "让", "乳", "镚", "腒", "衅", "铅", "殛", + "形", "颚", "茸", "绚", "铲", "贬", "溆", "寘", "傫", "解", "事", "旻", "差", "竣", "篃", "渥", + "嵩", "@", "鹀", "哈", "痍", "绪", "囔", "渗", "帐", "叙", "⑦", "跖", "貝", "盅", "碶", "哗", + "裼", "窝", "滙", "郸", "延", "炼", "芹", "簃", "谭", "莱", "佞", "猝", "褥", "陆", "王", "碴", + "粑", "怃", "倭", "貉", "硈", "裴", "溍", "坂", "勐", "踬", "敌", "改", "膠", "罘", "罚", "繁", + "幢", "煸", "扩", "黑", "氮", "孓", "饔", "姹", "蠖", "倬", "慝", "沩", "嚏", "雌", "琏", "莹", + "觊", "颟", "坤", "筅", "桉", "肈", "幻", "”", "烽", "蓅", "噌", "桎", "矻", "指", "瀚", "羊", + "邒", "筒", "匣", "旨", "葑", "团", "偻", "镛", "忉", "帱", "往", "刎", "害", "母", "串", "酢", + "舟", "栝", "娣", "⒉", "装", "笊", "篑", "垄", "镳", "牝", "煲", "氵", "遂", "骜", "钜", "屡", + "宇", "z", "惨", "潆", "鹃", "豌", "浞", "幄", "麺", "暽", "弁", "菤", "酲", "虑", "样", "访", + "睁", "黼", "悞", "禧", "涠", "舂", "駕", "屈", "噀", "邽", "炅", "欸", "隆", "描", "绦", "派", + "溲", "颙", "忐", "鹺", "只", "诈", "腭", "亵", "这", "炀", "趣", "喙", "跨", "場", "全", "搢", + "舨", "踢", "巿", "糸", "乐", "澈", "羰", "匯", "D", "濒", "莛", "癯", "娴", "姒", "祥", "渖", + "庭", "渑", "挹", "狉", "萍", "鹚", "焻", "自", "舸", "岫", "飑", "戍", "淙", "愠", "导", "賣", + "进", "赳", "鱿", "硂", "僤", "O", "拟", "钨", "笳", "汴", "挤", "稞", "柏", "阐", "弥", "艽", + "爻", "魭", "俶", "聂", "鲎", "齌", "菀", "僜", "煅", "满", "兀", "辔", "舊", "胥", "卢", "额", + "膝", "嵬", "昼", "唏", "璨", "苷", "舫", "倨", "耵", "碳", "鄺", "橘", "裔", "裸", "宋", "窋", + "悚", "昱", "错", "咣", "檄", "硁", "莆", "肃", "曼", "垍", "绵", "役", "內", "館", "规", "犋", + "毅", "锨", "瓘", "丘", "疝", "杀", "袗", "屏", "阎", "衹", "嚣", "冼", "铪", "熏", "t", "储", + "傧", "髁", "邙", "窴", "泾", "止", "晾", "涵", "庸", "庠", "靿", "睚", "减", "衲", "思", "簖", + "耘", "之", "斑", "扬", "袼", "缗", "菏", "滍", "研", "垚", "艘", "黇", "蜘", "汨", "侦", "疃", + "再", "沂", "榛", "励", "嚼", "拴", "钴", "珑", "撕", "鸯", "共", "醐", "揿", "醴", "凭", "菹", + "鹬", "捷", "掼", "芝", "缪", "咏", "挺", "蒗", "疖", "伸", "索", "黉", "髋", "習", "姜", "蔺", + "扶", "忽", "锉", "戚", "珲", "摸", "黛", "跌", "螈", "冚", "洱", "鼯", "庡", "痒", "哆", "品", + "歆", "登", "呔", "追", "鉫", "碾", "祚", "总", "帚", "薹", "趴", "容", "滘", "❋", "迷", "拾", + "炯", "析", "佼", "嗾", "-", "针", "滩", "禅", "讯", "織", "饱", "哟", "蹓", "侧", "蹯", "踽", + "趙", "漫", "卷", "朴", "卺", "狈", "绉", "浉", "玳", "榕", "畛", "蛾", "帔", "欠", "劙", "矾", + "進", "蚺", "骨", "捂", "疾", "璱", "圠", "坚", "弯", "秩", "逧", "烟", "佛", "嫱", "鳢", "裹", + "耥", "潮", "巽", "嶝", "廷", "鳆", "五", "西", "壤", "慌", "鴈", "爡", "‧", "儆", "萘", "愁", + "昔", "咩", "侃", "炫", "迳", "构", "缶", "皴", "捱", "菜", "秀", "粢", "畵", "辊", "伟", "榄", + "嗪", "已", "聖", "枕", "恢", "厍", "涅", "鄢", "饨", "鲨", "谪", "礤", "搁", "疔", "雎", "羿", + "犁", "硐", "盹", "若", "操", "昀", "亩", "凑", "睃", "贰", "穷", "荆", "葹", "嘃", "廓", "憔", + "制", "胧", "染", "麿", "镴", "砀", "组", "茎", "畫", "哑", "坨", "罱", "刳", "嘲", "瞰", "缏", + "侩", "谝", "谮", "还", "惋", "佈", "谏", "酗", "怩", "i", "秽", "抻", "蟪", "狠", "辑", "羟", + "娉", "肯", "毕", "枸", "啮", "鳙", "要", "娑", "蜈", "忍", "侗", "Р", "凛", "巉", "拽", "该", + "俎", "惠", "薅", "猬", "忲", "●", "哏", "柔", "沉", "磁", "脾", "龃", "鲩", "钞", "厂", "鱽", + "濞", "群", "唱", "攝", "刃", "蹻", "剕", "朊", "啜", "语", "蜻", "遠", "呖", "都", "嫄", "戢", + "丫", "酞", "修", "户", "膏", "侈", "浣", "捍", "馒", "谱", "點", "滏", "跟", "鹁", "书", "愉", + "扭", "票", "耒", "燁", "魚", "拨", "鞑", "匆", "最", "憨", "晨", "癍", "邻", "醅", "骘", "骇", + "蔫", "。", "珪", "安", "歉", "邑", "淦", "胱", "漏", "咂", "叮", "瘛", "钺", "聘", "玎", "荻", + "涰", "淏", "烈", "囚", "㙟", "矫", "嗵", "澶", "磛", "肖", "蹑", "支", "哪", "久", "嗅", "稍", + "抠", "具", "裨", "韨", "虿", "漪", "外", "埸", "ä", "葡", "鲇", "廛", "蝥", "广", "兒", "涧", + "阌", "谊", "嵴", "拂", "悸", "哳", "4", "佘", "篁", "基", "赪", "掬", "演", "谋", "酣", "植", + "波", "恅", "杼", "胀", "纯", "缩", "盆", "芷", "绺", "施", "礞", "莳", "稻", "狐", "馌", "椑", + "恃", "镩", "骼", "孱", "硭", "曈", "焼", "秕", "觥", "茛", "射", "肣", "蟞", "′", "彰", "罔", + "麻", "逋", "谓", "革", "藤", "堆", "忿", "茂", "屦", "炟", "碹", "啤", "垤", "文", "佐", "叼", + "蹭", "踉", "眍", "龟", "黾", "崋", "氘", "尼", "瞢", "悦", "罢", "瑀", "睇", "贴", "涿", "拍", + "庥", "粪", "陳", "闌", "蓍", "元", "磊", "忻", "葴", "买", "诺", "㐂", "沦", "苏", "岂", "浊", + "脍", "誠", "嚬", "蔬", "黄", "銘", "钩", "劃", "嫘", "嵖", "笄", "鸰", "熳", "堑", "河", "遮", + "尝", "灭", "愬", "娅", "鸽", "锢", "狂", "弓", "侨", "滚", "释", "晏", "徵", "苡", "佚", "切", + "惰", "降", "槎", "脑", "磺", "谟", "裉", "弘", "醺", "眇", "顒", "兰", "忧", "础", "-", "茫", + "袒", "喤", "慶", "話", "跽", "堵", "能", "武", "壳", "汤", "橐", "圧", "嗡", "簌", "斧", "林", + "楊", "净", "嫌", "猛", "炸", "冠", "弦", "洵", "°", "創", "葜", "苁", "顏", "薛", "平", "舜", + "崧", "撼", "哮", "窣", "殖", "象", "飒", "瞥", "玥", "斝", "胭", "葱", "擎", "踰", "盛", "稇", + "斫", "滴", "硫", "胬", "唁", "拐", "殍", "冱", "陪", "鋈", "烦", "辋", "妇", "轸", "潴", "荤", + "碡", "徭", "膜", "秧", "淀", "缤", "琶", "^", "肋", "违", "轭", "$", "箕", "墩", "罗", "摆", + "槛", "笠", "塃", "畚", "嘛", "秸", "≥", "剪", "羅", "帜", "庇", "骙", "酾", "康", "陬", "蝶", + "闇", "圏", "琴", "鬈", "苶", "黡", "瓠", "酋", "琎", "奏", "科", "搒", "億", "翡", "熊", "性", + "痞", "篾", "邴", "篥", "饵", "揸", "狙", "鳂", "否", "煺", "畦", "凖", "鹧", "宵", "庛", "鬯", + "袂", "昴", "徽", "奧", "鸥", "锸", "庚", "彪", "槿", "趱", "铡", "讹", "莎", "約", "璞", "┌", + "铫", "鸈", "瞀", "鼙", "廙", "估", "屺", "锘", "渝", "汶", "囵", "跻", "酏", "扎", "孜", "腔", + "吗", "块", "潽", "“", "焚", "倘", "靥", "默", "笺", "遍", "剅", "桠", "极", "夷", "眸", "泳", + "谢", "懦", ")", "泜", "物", "开", "淮", "邵", "卟", "徜", "轧", "苍", "酶", "捌", "耨", "膄", + "琦", "痦", "涪", "舰", "迥", "涘", "季", "悫", "初", "贩", "碍", "沼", "腮", "勻", "恣", "他", + "院", "7", "蜒", "叉", "昉", "瞽", "疢", "蓼", "相", "臜", "ü", "秘", "蚌", "摉", "莞", "番", + "盼", "冀", "缠", "学", "馗", "搞", "苛", "羹", "潟", "嬴", "杶", "妖", "↓", "銭", "斄", "猢", + "搂", "芦", "埶", "癜", "铴", "從", "留", "硎", "簇", "臬", "侮", "鳎", "頉", "所", "邝", "哂", + "弛", "垂", "暑", "仿", "療", "轾", "熜", "悃", "勘", "鋫", "泞", "閃", "+", "士", "虐", "盡", + "溯", "劣", "1", "锇", "蜇", "碛", "婴", "8", "捶", "藻", "嫰", "跹", "芋", "淠", "疯", "Й", + "诨", "醢", "痨", "栌", "摧", "噤", "灸", "馉", "蒇", "洲", "孪", "孵", "亿", "枝", "涕", "孟", + "缎", "攒", "湧", "褛", "铺", "廣", "诃", "蕈", "维", "珣", "逖", "瓯", "苘", "榫", "寰", "供", + "铽", "暲", "义", "兖", "喆", "祇", "蝽", "膛", "髭", "尹", "乒", "柈", "抓", "镋", "脏", "乩", + "挎", "酬", "靳", "躔", "霞", "離", "桌", "o", " ", "滨", "懷", "萭", "望", "仆", "怂", "麸", + "槁", "洨", "俬", "孚", "匕", "栩", "t", "被", "邗", "纺", "狄", "国", "苋", "眢", "秣", "畤", + "∵", "创", "嵫", "胖", "垮", "镁", "壑", "A", "趾", "荟", "汝", "嗥", "驰", "向", "磴", "讪", + "溅", "箍", "驾", "讙", "蛐", "眨", "醯", "筣", "鼫", "叠", "沥", "恕", "埽", "甩", "煜", "端", + "蜃", "帏", "丙", "荏", "圻", "夥", "暖", "抛", "岸", "头", "恝", "船", "鞲", "の", "七", "怪", + "诅", "茧", "北", "搓", "皖", "綉", "坪", "簪", "贵", "阍", "刑", "偶", "雷", "體", "髡", "岚", + "剂", "妾", "茬", "鹣", "鲳", "蜊", "假", "认", "嗍", "傈", "焘", "驷", "賀", "氆", "炝", "聋", + "嘡", "悺", "﹐", "僭", "证", "侉", "屐", "吃", "十", "〕", "瀦", "骤", "俳", "舁", "驸", "竿", + "坍", "|", "普", "軒", "瘃", "现", "醾", "铈", "榭", "蓁", "唷", "睫", "绰", "叶", "頤", "锤", + "浸", "杂", "汹", "璟", "蓖", "迦", "截", "錎", "年", "達", "劁", "码", "乃", "捯", "髪", "埚", + "呯", "頭", "镈", "汆", "β", "舷", "菂", "纸", "造", "晁", "卦", "蛎", "枉", "脯", "诛", "生", + "令", "桄", "恶", "鬟", "怯", "囡", "充", "省", "控", "螂", "笕", "邺", "扅", "斲", "骏", "鹋", + "队", "套", "镢", "牖", "I", "援", "封", "泚", "艿", "沮", "铙", "揳", "抄", "帨", "近", "唾", + "珥", "销", "非", "啱", "驼", "瓅", "遢", "筱", "奥", "善", "氩", "盉", "帖", "杜", "鈉", "蕉", + "鳄", "江", "鄂", "矩", "排", "诠", "准", "菼", "刻", "足", "峦", "灰", "僳", "蝢", "孫", "據", + "璆", "孳", "徹", "妆", "坭", "渌", "喏", "钦", "朔", "机", "徼", "掾", "其", "愧", "刹", "迹", + "惹", "闿", "鹘", "窗", "贳", "箓", "奡", "鸮", "翟", "滠", "辄", "夸", "袱", "】", "阿", "摁", + "觽", "垠", "棼", "杉", "甏", "旖", "阜", "猩", "埤", "醛", "馥", "哫", "囝", "晖", "骸", "椭", + "军", "哺", "束", "犄", "遛", "涡", "罄", "赇", "幌", "曙", "契", "饹", "圳", "仝", "爝", "示", + "敝", "漓", "马", "铐", "掳", "鲱", "蟀", "阵", "栒", "b", "轮", "俯", "嬉", "漩", "佟", "捆", + "迩", "液", "炊", "抒", "迭", "换", "菘", "请", "柩", "腓", "妥", "怖", "穆", "骝", "胛", "幺", + "燥", "棹", "孖", "洁", "边", "彥", "睨", "桁", "淆", "醤", "奘", "伙", "刘", "o", "過", "鏖", + "怄", "镗", "蘖", "卩", "龈", "枣", "联", "圊", "贫", "郭", "梗", "赡", "輸", "拼", "冰", "Ë", + "姓", "办", "拉", "富", "对", "肩", "缬", "逻", "瞠", "な", "荚", "宝", "緃", "峋", "鞁", "坉", + "译", "银", "猹", "榞", "借", "楠", "殽", "片", "谸", "雩", "琨", "颏", "晷", ";", "莠", "楽", + "嬗", "啉", "爍", "視", "岽", "荙", "冗", "『", "鯭", "觌", "喹", "药", "腈", "蹰", "–", "泷", + "榷", "卮", "缥", "各", "瘙", "凡", "悍", "劢", "6", "镰", "四", "摈", "驹", "陵", "沟", "麟", + "骊", "椀", "★", "滦", "菌", "彊", "疽", "辫", "璎", "郁", "资", "粼", "萄", "鳁", "鸤", "漁", + "痃", "绌", "蒴", "尊", "哙", "守", "坠", "胯", "泽", "持", "隅", "耧", "逛", "鄯", "瑜", "召", + "眷", "逄", "垦", "窄", "板", "赵", "源", "绹", "總", "适", "轰", "钛", "停", "唝", "燎", "栽", + "燃", "搬", "夬", "掐", "簦", "旃", "更", "蹊", "熙", "埃", "偲", "蒙", "舍", "杭", "朋", "霍", + "谙", "蓥", "赫", "鲏", "純", "缃", "蓓", "è", "萧", "锆", "诉", "恚", "u", "旷", "⑵", "褲", + "鲟", "互", "峂", "绝", "陒", "议", "脽", "态", "岙", "僮", "突", "濯", "犹", "阆", "溧", "宜", + "霣", "呆", "鄉", "觖", "濠", "耐", "橱", "敛", "踮", "怦", "鸠", "授", "滫", "叭", "镤", "仵", + "圖", "救", "变", "寕", "洋", "泃", "晥", "檎", "缦", "鏠", "悬", "彧", "韓", "籽", "磷", "歙", + "÷", "杨", "闯", "罴", "鼠", "陋", "瀣", "揾", "匪", "晚", "丧", "彷", "梏", "诽", "尻", "蹢", + "拊", "氕", "芳", "凸", "懊", "型", "媄", "憝", "骆", "纭", "刺", "悼", "藍", "欧", "葳", "艺", + "±", "紗", "钡", "钭", "首", "栈", "闩", "勃", "喑", "栉", "栟", "焊", "哀", "竖", "肘", "悲", + "鳜", "迨", "怿", "裘", "綮", "蕹", "冕", "无", "鼢", "戽", "鲣", "蜍", "插", "扯", "俣", "袪", + "级", "理", "茵", "矣", "障", "禊", "惯", "䄂", "宏", "韫", "栗", "编", "座", "跫", "、", "捞", + "谠", "車", "袆", "舖", "暝", "9", "混", "蓊", "韂", "拳", "j", "伶", "啦", "0", "诰", "缑", + "郴", "蕲", "谛", "皋", "兢", "件", "隈", "溊", "窈", "檀", "洪", "揭", "油", "颐", "剎", "侠", + "或", "腻", "迪", "舔", "牺", "倦", "夭", "蠋", "鹑", "倜", "喱", "豨", "谨", "翥", "馄", "蔚", + "类", "鳍", "泯", "岷", "張", "紅", "情", "婪", "睡", "诒", "旋", "舱", "列", "求", "姥", "翯", + "锲", "適", "蒡", "㭗", "韵", "撄", "律", "湊", "鲪", "碓", "馓", "汛", "尤", "℃", "泫", "竹", + "溃", "诵", "乡", "楹", "肷", "戋", "獭", "撴", "晤", "嘎", "裢", "轱", "歘", "鼱", "舀", "潵", + "腩", "挽", "至", "骞", "佻", "蕊", "轫", "岘", "斌", "《", "雇", "枘", "贶", "履", "亭", "绍", + "空", "泡", "擒", "蠓", "桼", "舢", "踵", "柢", "躺", "罥", "蔁", "幪", "蒯", "≤", "齉", "況", + "锕", "徇", "儿", "帽", "谕", "抽", "獍", "揪", "膳", "酴", "姊", "作", "弍", "郦", "翮", "髌", + "勝", "孔", "颁", "泩", "衾", "翊", "噉", "∩", "先", "的", "財", "绢", "崇", "饲", "賓", "绾", + "陡", "砾", "纷", "酱", "窎", "浕", "琫", "补", "嗽", "呛", "蚓", "伪", "艨", "搡", "粗", "阱", + "商", "郫", "喵", "缯", "炻", "州", "珽", "芒", "脶", "蕖", "拘", "\\", "蕃", "伏", "蛏", "璘", + "缡", "伞", "吸", "煞", "嗫", "餪", "━", "8", "漠", "衮", "峭", "筌", "阀", "乇", "杞", "镕", + "鹈", "觚", "疋", "猥", "肚", "阃", "地", "鸾", "玚", "镀", "诬", "凇", "惬", "劝", "堠", "睪", + "瞪", "涓", "專", "琢", "蠹", "裂", "芎", "轲", "谯", "畋", "长", "攘", "缁", "吵", "汈", "稂", + "咤", "甸", "瀑", "讣", "翠", "綦", "笑", "掺", "宫", "唆", "旗", "帘", "遵", "唪", "连", "必", + "姬", "枵", "渫", "神", "凱", "虞", "闵", "爭", "迢", "飓", "桴", "冑", "招", "鬶", "赊", "朦", + "薜", "逗", "铩", "焖", "狱", "昕", "犀", "捏", "侓", "爆", "箧", "怠", "缐", "苄", "踯", "暹", + "絮", "裁", "嘶", "诙", "攥", "¥", "痫", "摹", "朕", "薰", "闼", "樨", "需", "蕾", "扔", "服", + "蚩", "漳", "瞻", "陟", "诐", "爽", "耩", "坏", "寶", "瞧", "蘅", "爺", "仇", "瞈", "揉", "隰", + "阏", "皤", "鉏", "郇", "啵", "僧", "渐", "骠", "厾", "谦", "榱", "蓮", "乂", "伷", "觐", "遫", + "畀", "污", "眭", "蝗", "亢", "腾", "遇", "欺", "狸", "籼", "锯", "赚", "槔", "域", "老", "掩", + "锎", "邪", "沬", "袯", "映", "肤", "舒", "箦", "涎", "缔", "孃", "萎", "推", "峧", "嫒", "嵐", + "怒", "闾", "阅", "扢", "絡", "剩", "腢", "晌", "铟", "铚", "燔", "鄜", "墠", "擤", "芸", "鼩", + "食", "朰", "啥", "贿", "券", "垩", "典", "逭", "成", "帧", "侯", "妒", "顷", "晩", "浦", "汳", + "㾄", "坊", "②", "蝼", "倩", "挦", "騠", "蓂", "兹", "渤", "茴", "矶", "煤", "伛", "逃", "堞", + "漭", "闽", "埠", "妗", "烙", "傀", "滢", "堂", "骅", "崮", "兿", "螟", "榴", "蒈", "蟛", "员", + "嗟", "毗", "鹭", "毖", "籍", "傣", "偈", "澴", "耆", "黔", "薷", "俘", "箸", "蒺", "记", "铣", + "拥", "瑰", "抉", "史", "急", "什", "川", "曪", "剖", "罪", "扥", "鱼", "羌", "复", "昵", "朓", + "氪", "矅", "ò", "摒", "催", "{", "懂", "莉", "屃", "症", "遒", "璋", "鄒", "玄", "氦", "舳", + "納", "锷", "鲥", "羸", "怵", "嬖", "飚", "倔", "辨", "篌", "娄", "洎", "弟", "悝", "婥", "待", + "梃", "棕", "撞", "肊", "婺", "桥", "慕", "5", "尖", "监", "囊", "腎", "瘁", "⑴", "伢", "邈", + "炷", "籴", "月", "终", "龠", "蹇", "柯", "噜", "多", "玮", "踹", "泣", "圮", "辈", "鄙", "赆", + "蠃", "珈", "鬃", "识", "甑", "藓", "宥", "韧", "隗", "跚", "峁", "晒", "戳", "環", "葓", "筐", + "瑚", "稆", "巩", "葵", "网", "铨", "仡", "呶", "休", "村", "傩", "浡", "祝", "幅", "晳", "岿", + "[", "尃", "响", "咽", "讵", "淹", "糠", "驴", "烹", "甪", "焯", "整", "瘆", "茀", "瑞", "嘁", + "赅", "芼", "震", "怼", "膑", "蒟", "钊", "缷", "獨", "俄", "噪", "亏", "芍", "鲲", "黟", "酃", + "铻", "→", "鲡", "仑", "有", "扌", "治", "聆", "腙", "冬", "剥", "诓", "祃", "棘", "孥", "濆", + "鞋", "赣", "卜", "谆", "投", "琊", "塍", "洗", "津", "肴", "奕", "掴", "螗", "胸", "惦", "赠", + "耶", "蛸", "曷", "名", "栏", "崖", "始", "孤", "篆", "椴", "模", "儙", "袁", "颌", "卤", "寂", + "呸", "蓺", "噶", "钔", "粹", "潸", "郾", "娡", "啖", "芜", "䧳", "缟", "鞅", "哇", "嚄", "熛", + "私", "住", "鉄", "U", "失", "蜾", "㺃", "莨", "擂", "沕", "铄", "耰", "炔", "藐", "锈", "苇", + "芯", "檇", "龍", "珀", "筻", "褚", "缀", "棬", "仲", "杧", "铛", "挖", "缸", "嵇", "剟", "觋", + "鬼", "天", "鹪", "豭", "腴", "驿", "粵", "馈", "迸", "夕", "蜚", "禺", "迎", "狞", "嶽", "躯", + "暅", "蹾", "甾", "柆", "e", "欃", "無", "羽", "蛛", "僖", "碲", "遴", "厝", "滂", "眦", "鹅", + "咖", "潜", "媽", "啴", "寨", "琬", "判", "塌", "与", "剧", "掮", "读", "庆", "愚", "氲", "梾", + "稗", "很", "饯", "淘", "灞", "A", "!", "飾", "醚", "壁", "芮", "蔼", "知", "郯", "瞒", "术", + "法", "匠", "┅", "尕", "脂", "琅", "孝", "埙", "濟", "袷", "方", "芾", "驽", "线", "咡", "睿", + "滥", "鞨", "駹", "馎", "蛲", "申", "涣", "牗", "跄", "鲐", "泐", "铍", "肓", "é", "司", "辣", + "慑", "崞", "魏", "髯", "涯", "滃", "薪", "~", "鐵", "町", "芥", "匿", "癞", "嘚", "□", "啪", + "俇", "橛", "巅", "鄞", "痱", "回", "着", "魂", "瘀", "埒", "措", "蚪", "锁", "巴", "芏", "另", + "忏", "洇", "⑾", "箱", "劳", "榈", "B", "毒", "泰", "巍", "寇", "斛", "赖", "酒", "密", "左", + "莜", "茯", "脆", "饴", "洳", "舉", "酪", "鼒", "職", "桫", "螋", "砌", "戬", "前", "豁", "膲", + "鲯", "憋", "珺", "蹂", "亥", "冷", "蜔", "俦", "碇", "慰", "扒", "亮", "弒", "胫", "肠", "弇", + "拣", "丸", "涫", "勉", "帝", "玠", "应", "砜", "鬓", "泮", "鳖", "峇", "辗", "吴", "僡", "玊", + "钘", "惘", "奁", "翰", "爨", "罽", "莶", "纻", "菪", "興", "钧", "鄹", "缌", "嘉", "玲", "蛋", + "倚", "镬", "彳", "氯", "谐", "疗", "魉", "扈", "鏡", "涤", "佑", "勾", "饽", "R", "局", "醉", + "燫", "驱", "崽", "榮", "锄", "脎", "枓", "敲", "俑", "镶", "当", "逦", "寅", "捽", "宗", "茼", + "稿", "躇", "晋", "东", "渭", "闶", "潦", "慊", "蔟", "疑", "蜡", "嬛", "荒", "扪", "拈", "受", + "沱", "螽", "嗣", "瘰", "颖", "百", "楱", "崛", "窿", "蓬", "禨", "螵", "捕", "鳀", "霰", "瘸", + "圄", "陂", "敢", "矗", "炉", "篪", "注", "凉", "摔", "衿", "g", "遘", "鳟", "腚", "泱", "荣", + "池", "杰", "阻", "里", "峥", "葺", "翔", "柁", "飐", "载", "刨", "瘊", "溏", "嚭", "穝", "站", + "笞", "厌", "门", "汞", "雠", "靖", "怨", "葙", "厅", "凉", "荨", "底", "坼", "海", "轩", "秃", + "醭", "莒", "坎", "驺", "瀛", "嵝", "溥", "嚋", "寤", "k", "築", "耔", "跎", "小", "弊", "疭", + "√", "洞", "利", "次", "迕", "鸿", "刁", "媳", "酹", "磋", "勒", "伎", "浔", "斤", "珊", "鸳", + "颊", "塗", "刈", "龛", "縻", "楚", "脓", "南", "伧", "桨", "尸", "退", "亊", "侔", "蓟", "削", + "诲", "瑯", "挝", "绩", "嶂", "耷", "太", "著", "讥", "烂", "哥", "菔", "唳", "筫", "嚷", "斯", + "蔡", "碧", "慵", "搐", "琵", "逶", "菡", "篙", "驭", "莲", "毫", "犯", "坌", "啕", "疴", "傻", + "牧", "肺", "既", "悟", "讳", "练", "钠", "胨", "G", "迁", "帙", "嫦", "哿", "柝", "迤", "庑", + "踟", "粤", "乜", "悭", "霁", "在", "虔", "蓦", "暾", "鲅", "様", "徐", "诫", "料", "蒂", "揎", + "溜", "崎", "玦", "隐", "绳", "幼", "钼", "腧", "槌", "镅", "锿", "蹁", "猱", "狁", "蹈", "S", + "傢", "}", "珉", "浴", "龚", "吇", "肆", "⑩", "臌", "鏢", "―", "定", "哧", "螳", "爹", "摞", + "榍", "苩", "丑", "犴", "璀", "偎", "燹", "洯", "啁", "鱾", "計", "镂", "字", "琉", "壴", "霖", + "蟜", "做", "松", "扣", "徊", "叱", "桑", "≠", "寓", "崔", "茌", "`", "殓", "猖", "慎", "坻", + "皮", "喔", "耕", "拧", "织", "桂", "垝", "约", "飯", "皿", "移", "微", "桅", "钬", "赑", "宓", + "颉", "掂", "希", "沁", "翳", "澝", "崭", "聃", "蔸", "磕", "崚", "奉", "槍", "颠", "任", "飕", + "蛴", "歼", "蛭", "¥", "鉵", "刷", "泓", "頫", "诤", "阈", "诖", "漂", "冯", "柠", "本", "狼", + "芗", "丹", "柒", "饫", "衫", "摩", "桃", "啼", "譄", "醌", "帡", "少", "螃", "祷", "幸", "喘", + "噼", "甲", "刭", "泊", "那", "舄", "畲", "遊", "記", "绠", "蝈", "忒", "耙", "鹌", "搽", "绕", + "镠", "凼", "扫", "鸵", "匡", "缈", "铼", "挢", "踊", "噭", "苴", "貌", "啾", "蒜", "茱", "⒅", + "邛", "棉", "怀", "筵", "笾", "邢", "濱", "蒲", "嫠", "儡", "益", "萊", "歩", "日", "婢", "楔", + "嚎", "髂", "禄", "巫", "懿", "砍", "惆", "袭", "~", "欲", "鳅", "書", "撷", "库", "绻", "⒁", + "蒹", "辜", "屉", "奂", "龇", "诡", "醑", "儀", "讷", "聒", "盖", "浅", "長", "蛑", "念", "辒", + "蚊", "勖", "揣", "岬", "糅", "刊", "蛆", "硌", "柜", "惗", "激", "颈", "閣", "唬", "捧", "蒽", + "爸", "侏", "氧", "蛤", "牡", "瘦", "铉", "撒", "屿", "谔", "钀", "瓦", "恂", "钻", "声", "馨", + "贷", "藁", "闰", "人", "瀹", "间", "炜", "煨", "畴", "鞡", "悔", "量", "原", "屁", "杯", "趋", + "愎", "瓶", "烘", "韬", "姮", "勰", "眛", "饮", "瘐", "决", "版", "際", "俸", "此", "辽", "愫", + "爷", "隘", "螯", "腕", "闟", "厣", "齁", "矿", "女", "扇", "郄", "诚", "焜", "<", "檵", "赙", + "郢", "酌", "恳", "侵", "劍", "徳", "脔", "岍", "倍", "隹", "镲", "僬", "○", "啭", "坳", "谰", + "璪", "昆", "⒆", "惧", "虺", "篡", "锐", "邮", "嵊", "恹", "茄", "黯", "對", "魑", "禀", "添", + "汎", "廉", "戈", "∈", "陈", "肟", "螅", "缰", "啃", "瘾", "辁", "茜", "曝", "C", "餍", "蜴", + "咦", "臺", "扺", "隽", "崴", "遐", "胃", "铕", "楗", "墀", "魈", "淑", "邰", "飧", "勤", "糨", + "你", "铂", "蛰", "锻", "塈", "予", "怏", "鷪", "暂", "诞", "會", "鼐", "辏", "矬", "筜", "蟒", + "柫", "靴", "垒", "樵", "狨", "魋", "查", "掸", "'", "每", "浮", "绞", "疍", "於", "饦", "辐", + "墟", "窳", "养", "墦", "鲔", "黝", "迈", "砟", "伥", "藜", "墅", "喬", "卬", "赶", "眼", "龌", + "主", "嗞", "転", "襕", ",", "杲", "儒", "政", "蹩", "付", "Я", "厢", "点", "如", "茗", "奍", + "嗌", "蕴", "问", "膚", "硒", "佃", "居", "赍", "鯨", "槜", "衡", "廐", "鲾", "慈", "莫", "篮", + "铱", "园", "范", "靠", "叻", "绸", "众", "抑", "浃", "極", "辀", "千", "蔯", "r", "碱", "應", + "夼", "祺", "绣", "澉", "愛", "譬", "刚", "扼", "檫", "时", "荼", "部", "耽", "稀", "琳", "鎮", + "鳃", "疌", "挠", "京", "筴", "胳", "橡", "裱", "栊", "蛩", "流", "猄", "葭", "邯", "伤", "秦", + "孺", "郓", "筏", "茉", "谈", "黥", "鳇", "魅", "秫", "敫", "肄", "俪", "尺", "度", "廊", "昏", + "怎", "钎", "愤", "腿", "Λ", "碘", "囤", "婆", "煋", "桀", "阪", "焒", "砘", "澡", "阒", "臼", + "茭", "纛", "唻", "胗", "歌", "吱", "铸", "種", "礳", "舾", "砰", "即", "慥", "缆", "躞", "卖", + "眆", "搎", "鲁", "稠", "惝", "毶", "耎", "挡", "异", "咨", "歔", "垫", "素", "鳊", "打", "镏", + "耗", "锭", "剀", "讓", "鍋", "歇", "拗", "齿", "聊", "惕", "塔", "况", "汐", "采", "灣", "菁", + "峰", "呋", "阴", "衽", "鹏", "挂", "鲞", "第", "浑", "秭", "铯", "胎", "滔", "雕", "渔", "骍", + "鴻", "眚", "易", "枫", "麥", "罹", "劈", "苣", "蹄", "是", "锛", "饼", "铳", "器", "秒", "開", + "舛", "纳", "庒", "饰", "发", "虎", "乏", "届", "浯", "目", "霪", "氢", "华", "澧", "陴", "誊", + "欷", "瀌", "梵", "嗖", "惩", "妞", "螓", "溇", "嬃", "笼", "嬢", "獠", "辩", "骛", "挪", "礅", + "銎", "趺", "狍", "阑", "擦", "咙", "+", "鼻", "戆", "宿", "霏", "牁", "耦", "枳", "鲸", "阽", + "峯", "瘭", "祁", "镜", "绮", "道", "摭", "﹒", "耠", "限", "轻", "莽", "帛", "唯", "墒", "W", + "荦", "矸", "崃", "洫", "杳", "舌", "涌", "朵", "苑", "瓻", "辂", "凬", "畺", "莩", "奔", "荐", + "撵", "嶲", "憧", "沖", "邱", "瞑", "瘢", "腺", "嵯", "诗", "經", "胚", "谎", "央", "稼", "3", + "冈", "痣", "故", "皎", "珅", "踅", "硇", "通", "鹱", "草", "粕", "而", "梨", "萜", "搛", "鸺", + "托", "倡", "匾", "骷", "桐", "阇", "璃", "抖", "显", "镝", "I", "锣", "辆", "茝", "虫", "谀", + "萤", "帼", "滈", "鮼", "乔", "会", "产", "縢", "纱", "跆", "铤", "圯", "旚", "墓", "棰", "苜", + "聩", "蚍", "筢", "殇", "槚", "阂", "豊", "翚", "犰", "疚", "浠", "礴", "界", "蛙", "吁", "忪", + "讫", "辇", "汧", "澥", "纮", "糺", "拭", "镉", "鄠", "讼", "鎏", "逐", "烝", "扊", "筹", "仪", + "段", "杵", "卲", "钤", "曹", "潘", "浏", "陑", "答", "期", "橋", "位", "梅", "榻", "芨", "汭", + "贇", "杅", "伋", "馁", "皈", "躁", "鲦", "良", "幤", "曺", "榖", "便", "氍", "窍", "槃", "設", + "襦", "菓", "猡", "槲", "觱", "邠", "岩", "骈", "鬲", "睽", "残", "碗", "凯", "览", "伾", "吣", + "峡", "箨", "忡", "岁", "醵", "霸", "焐", "谁", "疟", "樾", "竺", "果", "阝", "花", "•", "耱", + "嗜", "骰", "萋", "甄", "侍", "厦", "辌", "给", "健", "垧", "娩", "校", "又", "临", "揽", "犟", + "蠢", "包", "檬", "穹", "燮", "札", "翏", "领", "深", "诶", "窒", "鸷", "统", "肾", "澍", "畹", + "职", "蝟", "眬", "旎", "朘", "眠", "篚", "贼", "貴", "#", "茆", "磬", "①", "祀", "坞", "盯", + "苹", "痼", "耪", "狺", "妓", "湨", "動", "渚", "售", "鸶", "霄", "某", "×", "铀", "桓", "脲", + "心", "节", "[", "蜩", "剐", "猜", "盂", "穿", "洮", "坜", "掷", "坐", "烜", "冶", "袍", "穴", + "偷", "槽", "面", "媛", "撙", "孩", "询", "苈", "橙", "恙", "吉", "燈", "暇", "杋", "後", "璇", + "喟", "妪", "湄", "贡", "兮", "楫", "锗", "肮", "圉", "参", "烃", "葩", "骀", "锖", "犿", "恼", + "麯", "牮", "溱", "俵", "祢", "割", "羲", "中", "博", "膦", "7", "钙", "耸", "蚋", "嘬", "逝", + "瓿", "且", "苗", "屑", "華", "糯", "吓", "陇", ".", "魆", "d", "拶", "箜", "澳", "蘼", "垸", + "钅", "樯", "侑", "娼", "赛", "恪", "击", "濮", "隔", "似", "惜", "滤", "培", "谩", "坝", "煙", + "馕", "茡", "颼", "啡", "强", "巡", "糗", "芙", "骒", "常", "鳔", "楣", "嫩", "师", "攀", "旭", + "茠", "吏", "剌", "露", "把", "携", "忘", "软", "荩", "弧", "锩", "僦", "掘", "仓", "嵚", "沲", + "傅", "蝴", "爵", "纪", "薮", "參", "荀", "珙", "逞", "蹙", "徉", "佶", "庹", "弢", "锞", "想", + "窕", "躬", "蚡", "闸", "难", "妃", "唶", "V", "蚂", "酐", "]", "羁", "土", "敏", "蝻", "赎", + "闹", "铷", "脬", "攫", "椐", "橹", "(", "暨", "剁", "灵", "咫", "苻", "赈", "萝", "鹮", "颛", + "勿", "臆", "福", "蝠", "烺", "跤", "垓", "庋", "鏊", "彭", "碚", "膂", "鐘", "鸹", "择", "疫", + "暌", "胙", "翘", "仞", "實", "猫", "嘹", "坟", "泺", "靽", "仟", "鲋", "畅", "箪", "箩", "星", + "辍", "餐", "伍", "狃", "蹐", "芴", "龋", "仨", "狩", "诌", "媚", "琚", "❤", "鉰", "仔", "忝", + "垅", "嗤", "氅", "填", "詹", "诿", "皑", "椅", "鲭", "繪", "碑", "选", "廠", "嶓", "迮", "唠", + "赏", "│", "泍", "姑", "晦", "直", "艾", "邂", "裝", "郊", "疡", "」", "鸲", "兕", "县", "邡", + "麤", "旧", "壶", "礼", "梭", "铔", "玕", "硬", "后", "馅", "窠", "俊", "犾", "槭", "姨", "妨", + "幡", "沿", "帮", "爿", "褊", "淅", "册", "诔", "使", "唢", "族", "逮", "蟋", "掣", "红", "颔", + "闲", "咧", "衍", "矛", "蹜", "抱", "雀", "箴", "雙", "茁", "聲", "芰", "瘤", "落", "峨", "秆", + "献", "霭", "胰", "墁", "柽", "跛", "阼", "菝", "谗", "蠊", "懋", "蔷", "拃", "岱", "戡", "逡", + "背", "克", "棱", "栲", "乖", "橄", "炭", "萱", "胲", "摺", "殆", "魍", "宾", "拢", "姁", "祲", + "·", "歹", "胆", "爱", "旰", "抢", "匜", "硚", "愈", "跳", "▲", "跪", "網", "糈", "維", "痹", + "娃", "疸", "痔", "褙", "芭", "鹜", "猷", "檩", "吨", "淖", "竟", "呱", "瘠", "奢", "呐", "扞", + "灼", "家", "饿", "玻", "倾", "锚", "遗", "赝", "去", "跣", "纬", "玢", "梆", "陉", "屎", "上", + "酆", "搤", "併", "腌", "避", "禹", "绅", "帆", "英", "区", "交", "▪", "巧", "豹", "游", "清", + "荧", "娀", "訓", "尾", "觫", "梢", "均", "忤", "继", "變", "喽", "尉", "骚", "趸", "馃", "石", + "置", "毡", "竴", "龄", "掭", "骟", "堡", "确", "街", "沌", "恨", "壮", "弄", "鞴", "剿", "貅", + "路", "杠", "豚", "澜", "靼", "擐", "租", "媪", "彖", "逢", "撺", "盗", "呑", "锥", "栎", "唧", + "翩", "倥", "虽", "郏", "钒", "雉", "捒", "官", "酷", "樽", "房", "屣", "堌", "蒍", "悌", "④", + "蛳", "俱", "慢", "筇", "框", "椽", "债", "吭", "柱", "夤", "嘈", "骺", "趹", "刓", "豕", "噢", + "J", "论", "俞", "仙", "碰", "经", "铋", "⑤", "顽", "曲", "得", "汪", "浒", "际", "嘏", "扮", + "祊", "嵋", "‘", "牒", "禮", "粒", "籀", "闱", "刍", "邕", "美", "苫", "靺", "铹", "莰", "蔑", + "敵", "逑", "锬", "宸", "鞥", "匝", "褀", "菅", "逊", "脱", "晔", "罾", "郝", "恰", "丟", "芩", + "枷", "鹩", "a", "夙", "述", "钢", "瀵", "铧", "翱", "尧", "醮", "&", "鳐", "懲", "濩", "树", + "劵", "虾", "砚", "腄", "罟", "硖", "崩", "埘", "╱", "血", "觯", "巂", "栀", "萏", "雪", "眵", + "白", "新", "靶", "猪", "亻", "窬", "Ⅳ", "麽", "遄", "沏", "茅", "笋", "甬", "潔", "悛", "幕", + "鹤", "悴", "耻", "觜", "滞", "己", "鏂", "肛", "婤", "嘞", "蘸", "胴", "柿", "穗", "咯", "嵕", + "蜣", "僰", "玃", "细", "▏", "戗", "尘", "仄", "子", "历", "翌", "烀", "晞", "桷", "藕", "啄", + "腐", "瘥", "诣", "彗", "捭", "懑", "陛", "傥", "沚", "贯", "﹑", "雒", "航", "跬", "晓", "赢", + "鸭", "臊", "闳", "稲", "阁", "鼋", "‰", "个", "農", "匮", "辚", "滗", "桢", "詈", "绗", "馇", + "蜓", "专", "余", "鳉", "稚", "午", "珍", "癃", "钵", "档", "颍", "厕", "岭", "祓", "诂", "襙", + "炙", "枯", "锦", "袤", "桊", "嗓", "䘵", "嫂", "丰", "苎", "梦", "早", "菱", "钱", "灯", "钮", + "锓", "豐", "蝤", "协", "h", "鼓", "燕", "覺", "涮", "呗", "専", "篓", "玷", "褓", "从", "鲍", + "羧", "俭", "萌", "樣", "颜", "谷", "夹", "囫", "』", "缙", "鹰", "条", "状", "沨", "因", "莺", + "楼", "扰", "禢", "砧", "埔", "纩", "臭", "茶", "妹", "莼", "境", "山", "诘", "蒌", "唤", "仃", + "眄", "田", "畼", "缱", "祘", "痴", "揍", "猾", "甙", "躲", "返", "砝", "叽", "苟", "肭", "悖", + "嫣", "凋", "踞", "勢", "弃", "般", "赤", "佣", "嘘", "智", "寒", "旆", "咎", "戊", "温", "昙", + "蝄", "掉", "冤", "凍", "一", "鋼", "茏", "兼", "昃", "峤", "挟", "0", "顾", "颅", "*", "遆", + "硅", "烯", "眊", "鳘", "下", "雾", "癖", "贮", "缴", "升", "劲", "婞", "掇", "梯", "壬", "撮", + "绑", "氣", "薤", "兔", "赟", "漕", "签", "顇", "砭", "鸼", "明", "佧", "鹗", "哉", "席", "趁", + "砖", "澌", "撤", "萨", "熔", "蚝", "狮", "夔", "介", "青", "喈", "郂", "埝", "狗", "哚", "咪", + "材", "跑", "炗", "龉", "髓", "衣", "觀", "淋", "寄", "羮", "抵", "恁", "藿", "蜢", "甜", "兽", + "洒", "眶", "薯", "绷", "颀", "骑", "鲻", "|", "q", "繄", "丝", "焙", "瑕", "童", "豸", "讨", + "钿", "艮", "踧", "幽", "焰", "宽", "址", "鸩", "堉", "音", "擅", "铞", "埌", "宙", "_", "钥", + "承", "率", "噬", "凌", "程", "蚕", "嘣", "饭", "橉", "径", "1", "鄏", "袜", "孙", "樊", "窦", + "牦", "歡", "罕", "蓉", "诩", "㧎", "责", "豢", "逅", "甘", "礶", "镥", "穂", "到", "檑", "皇", + "泖", "腱", "郤", "竞", "竽", "溴", "木", "蛀", "蛟", "燧", "鹳", "谵", "钳", "魔", "链", "咆", + "荡", "婳", "冢", "鲧", "昝", "※", "倫", "才", "簿", "醫", "吕", "姗", "L", "俺", "隳", "鮮", + "衩", "鲆", "崟", "鲹", "岗", "镇", "嗄", "硪", "盎", "氟", "笪", "今", "公", "尽", "佬", "骧", + "驻", "翼", "咚", "盱", "镎", "浈", "谅", "洟", "嘭", "跶", "蔹", "咭", "妁", "殚", "砷", "购", + "犸", "哄", "笸", "喂", "赋", "倓", "项", "臧", "梳", "笏", "鹝", "昭", "罿", "镄", "П", "湯", + "U", "绐", "绂", "鸬", "毐", "台", "鈴", "憾", "痰", "缭", "绒", "赁", "效", "哝", "─", "偆", + "泗", "谇", "貘", "搜", "阗", "個", "艟", "嗔", "正", "筛", "鼷", "摛", "馀", "坡", "卓", "厥", + "睾", "雯", "篷", "狰", "掀", "夫", "靛", "伻", "茇", "顧", "猕", "占", "俟", "兄", "垡", "兆", + "铃", "屙", "轵", "銮", "磲", "桤", "跷", "缳", "粘", "袢", "尬", "獘", "社", "彬", "哨", "煳", + "莊", "教", "鸸", "窖", "晰", "捻", "环", "廿", "驶", "椠", "熟", "赓", "挥", "兵", "洚", "桧", + "埼", "嘀", "哎", "柞", "悄", "调", "洼", "蛇", "铬", "蝇", "倆", "谂", "姻", "怕", "瑙", "算", + "惮", "遥", "惟", "甫", "玺", "袈", "税", "玟", "械", "擗", "淤", "溟", "揞", "纲", "谤", "條", + "翕", "荛", "忾", "馿", "糖", "檗", "垱", "┐", "躜", "缒", "您", "蹶", "合", "数", "斟", "粲", + "玖", "淞", "孰", "觎", "M", "嫪", "毽", "桩", "蹦", "亹", "胾", "亲", "痉", "莙", "捐", "烁", + "瓣", "邀", "但", "误", "饻", "妄", "镱", "民", "嗳", "竦", "柰", "脒", "斓", "瞟", "拱", "霾", + "粜", "腽", "咬", "唿", "礻", "y", "褒", "郪", "熰", "梻", "甭", "处", "拖", "蜉", "鄱", "絲", + "宠", "瞵", "荷", "靓", "喻", "阢", "伫", "担", "朐", "墙", "儣", "胄", "簏", "皆", "踌", "萃", + "命", "滟", "睹", "叁", "蟮", "東", "﹖", "式", "營", "疠", "醳", "尔", "購", "吒", "柴", "途", + "力", "疰", "寳", "萬", "挨", "碥", "牍", "嘻", "柃", "剡", "徝", "杖", "螺", "祈", "産", "煽", + "讽", "瞭", "由", "牀", "涉", "暴", "枚", "仰", "它", "胤", "驯", "港", "寵", "熄", "蛮", "务", + "殃", "亸", "涢", "妫", "粥", "扦", "寺", "抿", "湃", "C", "脚", "涸", "动", "務", "镭", "检", + "釂", "耳", "榦", "怆", "氨", "瘳", "钽", "牚", "负", "纂", "獬", "息", "婄", "襞", "囹", "酰", + "扑", "臛", "价", "褡", "篼", "媢", "酊", "腋", "愣", "垯", "喃", "牾", "犨", "蜂", "诹", "迂", + "槑", "好", "褰", "咝", "③", "劐", "骄", "腉", "仕", "叵", "磅", "金", "皁", "勍", "煮", "鍪", + "筚", "吲", "艰", "床", "叛", "﹔", "喜", "齑", "昧", "乎", "谲", "匈", "麒", "身", "唑", "鲤", + "栂", "垭", "殪", "沪", "苌", "濡", "蒎", "遏", "®", "质", "纫", "罐", "瞍", "柄", "呼", "锱", + "盔", "搋", "烛", "喉", "奈", "赦", "轘", "鉴", "瓒", "铰", "恽", "腠", "韶", "胼", "侄", "珂", + "鹕", "䝉", "呤", "椁", "岳", "汲", "疤", "绊", "涂", "乾", "噎", "兑", "絜", "嘧", "蚯", "们", + "蝉", "玛", "魁", "黻", "振", "冥", "报", "窟", "笱", "喊", "瓴", "喾", "説", "雹", "恫", "a", + "颧", "給", "宅", "鞧", "嬷", "鼾", "笔", "鲉", "匹", "蠕", "愍", "氽", "赐", "畔", "絪", "洴", + "审", "窂", "褔", "狯", "谑", "毳", "右", "疣", "鲙", "堃", "瓜", "…", "崆", "钫", "樭", "鲛", + "砂", "筋", "犏", "乱", "入", "浐", "膙", "厚", "獗", "覌", "焦", "罃", "宬", "隍", "荃", "醜", + "厉", "艇", "娟", "樂", "筲", "洛", "唼", "诜", "馑", "香", "缛", "运", "祟", "踩", "陲", "叔", + "潞", "二", "搠", "祼", "瀘", "蒋", "樗", "麦", "鸦", "棻", "古", "鹠", "怊", "裾", "够", "璧", + "晡", "擘", "毂", "御", "葚", "忱", "觞", "瑁", "唇", "罡", "剽", "殡", "沛", "帻", "举", "瞓", + "谬", "溝", "言", "哽", "婿", "猿", "跗", "獴", "俜", "呙", "弗", "凿", "窭", "铌", "友", "唉", + "怫", "荘", +]; diff --git a/ddddocr-core/src/ocr/metadata.rs b/ddddocr-core/src/ocr/metadata.rs index aad5d71..9b465c8 100644 --- a/ddddocr-core/src/ocr/metadata.rs +++ b/ddddocr-core/src/ocr/metadata.rs @@ -88,6 +88,37 @@ impl ModelMetadata { normalization, } } + /// 使用内置旧版字符集(与官方旧版模型配套)。 + pub fn from_builtin_old( + word: bool, + resize: Resize, + channel: u8, + normalization: Normalization, + ) -> Self { + Self::from_static_slice( + super::builtin::CHARSET_OLD, + word, + resize, + channel, + normalization, + ) + } + + /// 使用内置 Beta 字符集(与官方 Beta 模型配套)。 + pub fn from_builtin_beta( + word: bool, + resize: Resize, + channel: u8, + normalization: Normalization, + ) -> Self { + Self::from_static_slice( + super::builtin::CHARSET_BETA, + word, + resize, + channel, + normalization, + ) + } } #[cfg(test)] diff --git a/ddddocr-core/src/traits.rs b/ddddocr-core/src/traits.rs index ab16993..29bdd29 100644 --- a/ddddocr-core/src/traits.rs +++ b/ddddocr-core/src/traits.rs @@ -15,7 +15,7 @@ pub trait Info { fn model_info(&self) -> crate::error::Result; } -/// 推理引擎统一抽象接口,由 ddddocr-tract、ddddocr-ort 等引擎 crate 实现。 +/// 推理引擎统一抽象接口,由 ddddocr-tract2、ddddocr-ort 等引擎 crate 实现。 pub trait InferenceEngine { /// 引擎产出的输出枚举(OCR 为 [`crate::OcrOutput`],检测为 [`crate::DetOutput`])。 type Output; diff --git a/ddddocr-ort/Cargo.toml b/ddddocr-ort/Cargo.toml index fdcea1e..7875d8f 100644 --- a/ddddocr-ort/Cargo.toml +++ b/ddddocr-ort/Cargo.toml @@ -1,23 +1,25 @@ [package] name = "ddddocr-ort" -version.workspace = true -edition.workspace = true -license.workspace = true +version = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +description = "ddddocr-rs 的 ONNX Runtime 推理引擎实现" +keywords = ["ocr", "captcha", "ddddocr", "onnxruntime", "ort"] +categories = ["multimedia::images", "computer-vision"] +# repository = "https://github.com/<用户名>/<仓库名>" # 发布前请补充 +readme = "../README.md" [dependencies] -ddddocr-core = { path = "../ddddocr-core" } # 引入兄弟库 -ort = { workspace = true ,features = ["cuda"]} -ndarray = { workspace = true } # 继承自工作空间 - +ddddocr-core = { path = "../ddddocr-core", version = "0.2.4" } +ort = { workspace = true } +ndarray = { workspace = true } image = { workspace = true } - serde = { workspace = true } serde_json = { workspace = true } - anyhow = { workspace = true } -thiserror = { workspace = true } # 刚好可以开始接入你需要的标准库错误处理 +thiserror = { workspace = true } +tracing = { workspace = true } [features] -# 1. 声明 cuda feature -# 2. 当开启 ddddocr-ort 的 cuda feature 时,自动开启底层 ort 库的 cuda 支持(如果 ort 库支持的话) -cuda = ["ort/cuda"] \ No newline at end of file +# 开启后启用底层 ort 库的 CUDA 执行提供者支持。 +cuda = ["ort/cuda"] diff --git a/ddddocr-ort/src/det.rs b/ddddocr-ort/src/det.rs index 3e7b3f8..f52f1c4 100644 --- a/ddddocr-ort/src/det.rs +++ b/ddddocr-ort/src/det.rs @@ -1 +1 @@ -pub mod session; \ No newline at end of file +pub mod session; diff --git a/ddddocr-ort/src/det/session.rs b/ddddocr-ort/src/det/session.rs index ee55b78..8548925 100644 --- a/ddddocr-ort/src/det/session.rs +++ b/ddddocr-ort/src/det/session.rs @@ -1,63 +1,40 @@ +use crate::runtime::{extract_tensor, lock_session, run_session}; use crate::types::Session; use ddddocr_core::DetOutput; use ddddocr_core::error::{Result, TensorError}; use ddddocr_core::traits::{DetEngine, InferenceEngine}; use ndarray::Ix3; -use ort::inputs; -use ort::value::TensorRef; +use tracing::debug; +/// 目标检测推理运行时:持有 ORT 会话,输出 [`DetOutput`]。 #[derive(Debug)] pub struct DetRuntime { + /// ORT 会话句柄。 pub session: Session, } impl DetRuntime { + /// 基于已构建的会话创建检测运行时。 pub fn new(session: Session) -> Self { Self { session } } } impl InferenceEngine for DetRuntime { - type Output = DetOutput; // 明确绑定 OCR 小枚举 + type Output = DetOutput; fn inference(&self, input_array: ndarray::Array4) -> Result { - // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 - // let result = self.ocr.run(tvec!(tensor.into()))?; - let mut session_guard = self - .session - .lock() - .map_err(|_| TensorError::Engine("获取 Session 锁失败 (Poisoned)".to_string()))?; - - let result = session_guard - .run(inputs![TensorRef::from_array_view(&input_array).map_err( - |e| TensorError::Engine(format!("构建输入失败: {e}")) - )?]) - .map_err(|e| TensorError::Engine(format!("执行模型推理失败: {e}")))?; - // .context("执行模型推理失败")?; - println!("模型输出原始数据: {:?}", result); - - // Ok(result.swap_remove(0).into_tensor()) - let raw_value = &result[0]; - - // raw_tensor.into_plain_array()? - let (shape_ref, slice) = raw_value.try_extract_tensor::().map_err(|_| { - TensorError::Engine("Tract 实体张量无法转换为 ndarray::ArrayD".to_string()) - })?; - // 提前利用克隆(Clone)备份好当前未转维度前的真实 shape (Vec) - let shape_vec: Vec = shape_ref.to_vec().iter().map(|v| *v as usize).collect(); - let shape_vec_slice = shape_vec.as_slice(); - - let view = ndarray::ArrayViewD::from_shape(shape_vec_slice, slice) - .map_err(|_| TensorError::Engine("构建 ndarray ArrayViewD 失败".to_string()))?; + let mut session_guard = lock_session(&self.session)?; + let result = run_session(&mut session_guard, &input_array)?; + debug!("模型输出原始数据: {:?}", result); + let (view, shape_vec) = extract_tensor::(&result[0])?; let array3 = view.to_owned().into_dimensionality::().map_err(|_| { TensorError::DimensionMismatch { expected: "3D 检测矩阵 [Batch, Box_Count, Box_Attributes]".to_string(), - actual: shape_vec, // 优雅降维失败时动态捕获 + actual: shape_vec, } })?; Ok(DetOutput::Detection(array3)) - - // 在引擎内部消化掉 DatumType 强耦合 } } diff --git a/ddddocr-ort/src/lib.rs b/ddddocr-ort/src/lib.rs index 3c0d256..280e415 100644 --- a/ddddocr-ort/src/lib.rs +++ b/ddddocr-ort/src/lib.rs @@ -1,9 +1,20 @@ +//! # ddddocr-ort +//! +//! 基于 ONNX Runtime(ORT)的推理引擎实现:通过 [`loader::ModelLoader`] 构建会话, +//! 再由 [`OcrRuntime`] / [`DetRuntime`] 实现 core 的 +//! [`ddddocr_core::traits::InferenceEngine`] 接口。 +//! 同时重导出 core 的 [`OcrBuilder`]、[`Slider`]、[`SlideResult`] 等便捷 API。 + +#![warn(missing_docs)] + mod det; +/// 模型加载器:从路径或字节流构建 ORT 会话。 pub mod loader; mod ocr; +mod runtime; mod types; - -pub use ddddocr_core::{SlideResult, Slider,OcrBuilder}; +pub use ddddocr_core::{OcrBuilder, SlideResult, Slider}; pub use det::session::DetRuntime; -pub use ocr::session::OcrRuntime; \ No newline at end of file +pub use ocr::session::OcrRuntime; +pub use types::Session; diff --git a/ddddocr-ort/src/loader.rs b/ddddocr-ort/src/loader.rs index 4bdafe9..094c247 100644 --- a/ddddocr-ort/src/loader.rs +++ b/ddddocr-ort/src/loader.rs @@ -3,5 +3,5 @@ mod metadata; mod model; pub use error::{Error, ParseError, Result}; -pub use metadata::{ModelMetadataDto, NormalizationDto, Metadata}; -pub use model::ModelLoader; \ No newline at end of file +pub use metadata::{Metadata, ModelMetadataDto, NormalizationDto}; +pub use model::ModelLoader; diff --git a/ddddocr-ort/src/loader/error.rs b/ddddocr-ort/src/loader/error.rs index 1e9fba2..bd9e53d 100644 --- a/ddddocr-ort/src/loader/error.rs +++ b/ddddocr-ort/src/loader/error.rs @@ -1,7 +1,10 @@ use ort::Error as OrtError; +/// 模型加载与解析的通用结果类型。 pub type Result = std::result::Result; #[derive(thiserror::Error, Debug)] +/// 模型加载、解析与 Session 构建阶段的错误。 pub enum Error { + /// 底层构建器配置失败。 #[error("builder构建失败")] Build(#[from] BuildError), /// 解析 ONNX 模型/路径失败(如文件损坏、算子不支持、路径非法) @@ -9,11 +12,11 @@ pub enum Error { ModelParse(#[from] ParseError), /// 模型计算图优化失败(如常量折叠、形状推导失败) - #[error("优化 Tract 模型图失败: {0}")] + #[error("优化 ORT 模型图失败: {0}")] OptimizationFailed(#[source] OrtError), /// 构建可执行 Session 失败(如输入输出 Tensor 类型/形状未确定) - #[error("构建可运行 Tract 实例失败: {0}")] + #[error("构建可运行的 ORT Session 失败: {0}")] RunnableBuildFailed(#[source] OrtError), /// JSON 反序列化失败(自动透传 serde_json 报错) @@ -24,6 +27,7 @@ pub enum Error { #[error("Metadata 字节流不是合法的 UTF-8 编码: {0}")] InvalidUtf8(#[from] std::str::Utf8Error), + /// 模型元数据内容解析失败。 #[error("模型元数据解析失败: {0}")] MetadataParse(String), @@ -32,8 +36,6 @@ pub enum Error { Other(String, #[source] Box), } - - impl Error { /// 方便将任何第三方 Error 包装为 Error::Other pub fn new(msg: impl Into, err: E) -> Self @@ -44,6 +46,7 @@ impl Error { } } #[derive(thiserror::Error, Debug)] +/// 从路径或字节流解析 ONNX 模型失败的错误。 pub enum ParseError { /// 策略 A:从文件路径加载失败(附带路径上下文信息,方便排查是找不到文件还是格式不对) #[error("从路径 '{0}' 加载 ONNX 模型失败: {1}")] @@ -54,13 +57,45 @@ pub enum ParseError { Bytes(#[source] OrtError), } #[derive(thiserror::Error, Debug)] -pub enum BuildError{ - #[error("builder构建失败")] +pub enum BuildError { + /// 底层 SessionBuilder 构建失败。 + #[error("构建 ORT SessionBuilder 失败: {0}")] BuildFailed(#[from] OrtError), - #[error("builder构建失败")] + /// 线程数配置失败。 + #[error("{0}")] Threads(String), - #[error("builder构建失败")] + /// 启用 CUDA 执行提供者失败。 + #[error("{0}")] EnabledCudaFailed(String), - #[error("builder构建失败")] - NotEnabledCuda(String) -} \ No newline at end of file + /// 未编译 CUDA 支持时尝试启用 GPU。 + #[error("{0}")] + NotEnabledCuda(String), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn wraps_external_error_via_new() { + let io_err = std::io::Error::other("boom"); + let err = Error::new("自定义错误", io_err); + assert!(matches!(err, Error::Other(_, _))); + assert!(err.to_string().contains("自定义错误")); + } + + #[test] + fn serde_json_error_converts_to_error() { + let json_err = serde_json::from_str::("{").unwrap_err(); + let err: Error = json_err.into(); + assert!(matches!(err, Error::JsonParse(_))); + } + + #[test] + fn ut8_error_converts_to_error() { + let bytes = vec![0xffu8]; + let utf8_err = std::str::from_utf8(&bytes).unwrap_err(); + let err: Error = utf8_err.into(); + assert!(matches!(err, Error::InvalidUtf8(_))); + } +} diff --git a/ddddocr-ort/src/loader/metadata.rs b/ddddocr-ort/src/loader/metadata.rs index 3f2dd1e..7effe4a 100644 --- a/ddddocr-ort/src/loader/metadata.rs +++ b/ddddocr-ort/src/loader/metadata.rs @@ -1,13 +1,12 @@ use crate::loader::error::{Error, Result}; -use ddddocr_core::ModelMetadata; -use ddddocr_core::Resize; -use ddddocr_core::{Charset, Normalization}; +use ddddocr_core::{Charset, ModelMetadata, Normalization, Resize}; use serde::Deserialize; use std::borrow::Cow; #[derive(Deserialize)] #[serde(rename_all = "snake_case")] // 支持 json 中写 "zero_to_one" 或 "minus_one_to_one" +/// 归一化策略的 JSON 反序列化中间表示。 pub enum NormalizationDto { /// 映射到 [0.0, 1.0] -> pixel / 255.0 ZeroToOne, @@ -41,8 +40,9 @@ fn default_normalization() -> NormalizationDto { NormalizationDto::ZeroToOne } -/// Tract 专属扩展trait 或 工具函数 +/// 从 JSON 字符串或字节流解析模型元数据的扩展接口。 pub trait Metadata: Sized { + /// 从 JSON 字符串解析模型元数据。 fn from_json_str(json_str: &str) -> Result; /// 机制 2:从内存字节流加载(极大地方便 include_bytes! 或网络下载) fn from_json_bytes(bytes: &[u8]) -> Result { @@ -56,8 +56,7 @@ impl Metadata for ModelMetadata { let dto: ModelMetadataDto = serde_json::from_str(json_str)?; // 1. 将 DTO 的字符串数组转化为强类型的 Charset - let tokens: Vec> = - dto.charset.into_iter().map(|s| Cow::Owned(s)).collect(); + let tokens: Vec> = dto.charset.into_iter().map(Cow::Owned).collect(); let charset = Charset::new(tokens); // 2. 解析 resize 策略(重现 Python 的复杂条件判断) @@ -91,3 +90,104 @@ impl Metadata for ModelMetadata { )) } } + +#[cfg(test)] +mod tests { + use super::*; + + const MINIMAL_JSON: &str = r#"{ + "charset": ["a", "b", "c"], + "word": false, + "resize": [-1, 64], + "channel": 1 + }"#; + + #[test] + fn parses_minimal_json_with_default_normalization() { + let meta = ModelMetadata::from_json_str(MINIMAL_JSON).unwrap(); + assert_eq!(meta.charset.size(), 3); + assert!(!meta.word); + assert_eq!(meta.channel, 1); + assert!(matches!(meta.resize, Resize::DynamicWidth(64))); + assert!(matches!(meta.normalization, Normalization::ZeroToOne)); + } + + #[test] + fn parses_minus_one_to_one_normalization() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [-1, 64], + "channel": 1, + "normalization": "minus_one_to_one" + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.normalization, Normalization::MinusOneToOne)); + } + + #[test] + fn parses_word_model_as_square_resize() { + let json = r#"{ + "charset": ["a"], + "word": true, + "resize": [-1, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Square(64))); + } + + #[test] + fn parses_fixed_resize() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [100, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Fixed(100, 64))); + } + + #[test] + fn parses_image_alias() { + let json = r#"{ + "charset": ["a"], + "word": false, + "image": [200, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Fixed(200, 64))); + } + + #[test] + fn rejects_resize_with_wrong_length() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [1, 2, 3], + "channel": 1 + }"#; + assert!(matches!( + ModelMetadata::from_json_str(json), + Err(Error::MetadataParse(_)) + )); + } + + #[test] + fn rejects_invalid_json() { + assert!(matches!( + ModelMetadata::from_json_str("not json"), + Err(Error::JsonParse(_)) + )); + } + + #[test] + fn rejects_invalid_utf8_bytes() { + assert!(matches!( + ModelMetadata::from_json_bytes(&[0xff, 0xfe]), + Err(Error::InvalidUtf8(_)) + )); + } +} diff --git a/ddddocr-ort/src/loader/model.rs b/ddddocr-ort/src/loader/model.rs index 3afc75c..92c44f3 100644 --- a/ddddocr-ort/src/loader/model.rs +++ b/ddddocr-ort/src/loader/model.rs @@ -6,30 +6,13 @@ use ort::session::Session as OrtSession; use ort::session::builder::SessionBuilder; use std::sync::{Arc, Mutex}; -// pub struct OrtModelLoader; -// -// impl OrtModelLoader { -// /// 获取针对 ORT 后端的链式构建器 -// pub fn builder() -> OrtModelBuilder { -// OrtModelBuilder::default() -// } -// } /// ORT 专用的链式构建器 -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct ModelLoader { use_gpu: bool, device_id: i32, intra_threads: Option, } -impl Default for ModelLoader { - fn default() -> Self { - Self { - use_gpu: false, - device_id: 0, - intra_threads: None, - } - } -} impl ModelLoader { /// 开启或关闭 GPU 加速 pub fn use_gpu(mut self, enable: bool) -> Self { @@ -42,6 +25,7 @@ impl ModelLoader { self.device_id = id; self } + /// 指定 ORT 内部线程数。 pub fn num_threads(mut self, threads: usize) -> Self { self.intra_threads = Some(threads); self @@ -49,7 +33,7 @@ impl ModelLoader { /// 内部辅助方法:根据当前的配置构建 ORT 底层的 SessionBuilder fn create_session_builder(&self) -> Result { - let mut builder = OrtSession::builder().map_err(|e| BuildError::BuildFailed(e))?; + let mut builder = OrtSession::builder().map_err(BuildError::BuildFailed)?; // 如果用户显式设置了线程数,则配置给 ORT if let Some(threads) = self.intra_threads { builder = builder @@ -99,7 +83,7 @@ impl Loader for ModelLoader { .commit_from_file(path_ref) .map_err(|e| ParseError::Path(path_ref.display().to_string(), e))?; - Ok(Arc::new(Mutex::new(session))) // 这里的session需要包装下 + Ok(Arc::new(Mutex::new(session))) } /// 策略 B:从内存字节流加载模型(配合 include_bytes! 使用) fn build_from_bytes(&self, model_bytes: &[u8]) -> Result { @@ -112,3 +96,36 @@ impl Loader for ModelLoader { Ok(Arc::new(Mutex::new(session))) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn default_config() { + let loader = ModelLoader::default(); + assert!(!loader.use_gpu); + assert_eq!(loader.device_id, 0); + assert!(loader.intra_threads.is_none()); + } + + #[test] + fn builder_configures_fields() { + let loader = ModelLoader::default() + .use_gpu(true) + .device_id(2) + .num_threads(4); + assert!(loader.use_gpu); + assert_eq!(loader.device_id, 2); + assert_eq!(loader.intra_threads, Some(4)); + } + + #[test] + fn builder_is_chainable_and_immutable() { + let base = ModelLoader::default(); + let _configured = base.clone().use_gpu(true).device_id(1).num_threads(8); + assert!(!base.use_gpu); + assert_eq!(base.device_id, 0); + assert!(base.intra_threads.is_none()); + } +} diff --git a/ddddocr-ort/src/ocr/session.rs b/ddddocr-ort/src/ocr/session.rs index f2e5e98..6eb3d8e 100644 --- a/ddddocr-ort/src/ocr/session.rs +++ b/ddddocr-ort/src/ocr/session.rs @@ -1,107 +1,87 @@ +use crate::runtime::{extract_tensor, lock_session, run_session}; use crate::types::Session; use ddddocr_core::ModelMetadata; use ddddocr_core::OcrOutput; -use ddddocr_core::error::{DdddError, Result, TensorError}; +use ddddocr_core::error::{Result, TensorError}; use ddddocr_core::traits::{InferenceEngine, Info, OcrEngine}; use ddddocr_core::types::{AxisDim, ModelInfo, TensorInfo, TensorType}; use ddddocr_core::utils::normalize_ocr_logits; -use ort::inputs; -use ort::value::{TensorElementType, TensorRef}; -use std::sync::Mutex; -// 引入核心层的统一错误类型 -/// 明确命名为 AxisDim,代表模型某一个轴的维度特征 -// #[derive(Clone, PartialEq, Eq)] -// pub enum AxisDim { -// /// 静态固定维度(如通道数固定为 1,高度固定为 64) -// Static(usize), -// /// 动态符号维度(如宽度是动态的 "image_width") -// Dynamic(String), -// } +use ort::value::{Outlet, TensorElementType, ValueType}; +use tracing::debug; -// impl AxisDim { -// /// 便捷方法:判断是否为动态维度 -// pub fn is_dynamic(&self) -> bool { -// matches!(self, AxisDim::Dynamic(_)) -// } -// } -// /// 自定义 Debug 格式化输出,彻底融化套娃外壳,保证日志干净漂亮 -// impl std::fmt::Debug for AxisDim { -// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -// match self { -// AxisDim::Static(size) => write!(f, "{}", size), -// AxisDim::Dynamic(expr) => write!(f, "Dynamic(\"{}\")", expr), -// } -// } -// } -/// 模拟 Python 的 input_info 和 output_info 结构 -// #[derive(Debug, Clone)] -// pub struct TensorInfo { -// pub name: String, -// pub shape: Vec, // 既包含 Fixed 静态维度,也包含 Dynamic 动态符号 -// pub data_type: TensorElementType, // 对应 Python 的 type -// } -// -// /// 最终返回的模型完整信息 -// #[derive(Debug, Clone)] -// pub struct ModelInfo { -// pub inputs: Vec, -// pub outputs: Vec, -// /// 硬件执行提供者(采用 Option 兼容不同底层的推理引擎) -// pub providers: Option>, -// } +/// OCR 推理运行时:持有 ORT 会话与模型元数据,输出 [`OcrOutput`]。 pub struct OcrRuntime { + /// ORT 会话句柄。 pub session: Session, + /// 模型元数据(字符集、归一化策略等)。 pub metadata: ModelMetadata, } + impl OcrRuntime { + /// 基于已构建的会话与元数据创建 OCR 运行时。 pub fn new(session: Session, metadata: ModelMetadata) -> Self { Self { session, metadata } } + + /// 将 ORT 输入/输出出口解析为 core 的 [`TensorInfo`] 列表。 + fn resolve_outlets(&self, outlets: &[Outlet]) -> Result> { + Ok(outlets + .iter() + .map(|outlet| TensorInfo { + name: outlet.name().to_string(), + shape: resolve_shape(outlet.dtype()), + tensor_type: tensor_type_from_ort(outlet.dtype()), + }) + .collect()) + } } + +/// 将 ORT 值类型映射为 core 的 [`TensorType`]。 +fn tensor_type_from_ort(dtype: &ValueType) -> TensorType { + match dtype.tensor_type() { + Some(TensorElementType::Float32) => TensorType::F32, + Some(TensorElementType::Int64) => TensorType::I64, + _ => TensorType::Other, + } +} + +/// 将 ORT 张量形状解析为 [`AxisDim`] 列表,动态维度(`-1`)标记为符号维度。 +fn resolve_shape(dtype: &ValueType) -> Vec { + dtype + .tensor_shape() + .map(|shape| { + shape + .iter() + .map(|&dim| { + if dim >= 0 { + AxisDim::Static(dim as usize) + } else { + AxisDim::Dynamic("dynamic".to_string()) + } + }) + .collect() + }) + .unwrap_or_default() +} + impl OcrEngine for OcrRuntime { fn metadata(&self) -> &ModelMetadata { &self.metadata } } + impl InferenceEngine for OcrRuntime { type Output = OcrOutput; - /// 对应 Python 的 _inference - fn inference(&self, input_array: ndarray::Array4) -> Result { - // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 - // let result = self.ocr.run(tvec!(tensor.into()))?; - // let tensor = Tensor::from(input_array); - let mut session_guard = self - .session - .lock() - .map_err(|_| TensorError::Engine("获取 Session 锁失败 (Poisoned)".to_string()))?; - let result = session_guard - .run(inputs![TensorRef::from_array_view(&input_array).map_err( - |e| TensorError::Engine(format!("构建输入失败: {e}")) - )?]) - .map_err(|e| TensorError::Engine(format!("执行模型推理失败: {e}")))?; - // .context("执行模型推理失败")?; - println!("模型输出原始数据: {:?}", result); - // Ok(result.swap_remove(0).into_tensor()) + fn inference(&self, input_array: ndarray::Array4) -> Result { + let mut session_guard = lock_session(&self.session)?; + let result = run_session(&mut session_guard, &input_array)?; + debug!("模型输出原始数据: {:?}", result); let raw_value = &result[0]; - match raw_value.dtype().tensor_type().unwrap() { - TensorElementType::Int64 => { - let (array_d, slice) = raw_value - .try_extract_tensor::() - .map_err(|_| TensorError::Engine("Tract 无法获取 i64 内存视图".to_string()))?; - // .context("Tract 无法获取 i64 内存视图")?; - - // 提前提取真实维度 - let actual_shape = array_d - .to_vec() - .iter() - .map(|v| *v as usize) - .collect::>(); - - let view = ndarray::ArrayViewD::from_shape(actual_shape.as_slice(), slice) - .map_err(|_| TensorError::Engine("构建 ndarray ArrayViewD 失败".to_string()))?; - // 转成标准的 Array1 传给 core + match raw_value.dtype().tensor_type() { + Some(TensorElementType::Int64) => { + let (view, actual_shape) = extract_tensor::(raw_value)?; let array1 = view .to_owned() .into_dimensionality::() @@ -111,40 +91,98 @@ impl InferenceEngine for OcrRuntime { })?; Ok(OcrOutput::Indices(array1)) } - TensorElementType::Float32 => { + Some(TensorElementType::Float32) => { let shape = raw_value.shape(); - println!("模型输出shape数据: {:?}", shape); - // raw_tensor.to_plain_array_view() - let (shape_ref, slice) = raw_value - .try_extract_tensor::() - .map_err(|_| TensorError::Engine("Tract 无法获取 f32 内存视图".to_string()))?; - // 1. 极其纯粹的、无拷贝的多维 Shape 压扁清洗 - let shape_vec: Vec = - shape_ref.to_vec().iter().map(|v| *v as usize).collect(); - let shape_vec_slice = shape_vec.as_slice(); - - let view = ndarray::ArrayViewD::from_shape(shape_vec_slice, slice) - .map_err(|_| TensorError::Engine("构建 ndarray ArrayViewD 失败".to_string()))?; - - normalize_ocr_logits(view, shape_vec_slice) + debug!("模型输出 shape 数据: {:?}", shape); + let (view, shape_vec) = extract_tensor::(raw_value)?; + normalize_ocr_logits(view, shape_vec.as_slice()) } - _ => Err( - // anyhow::anyhow!("不支持的模型输出数据类型: {:?}",raw_tensor.datum_type()) - TensorError::UnknownOutputFormat, - ), + _ => Err(TensorError::UnknownOutputFormat), } } } + impl Info for OcrRuntime { fn input_info(&self) -> Result> { - todo!() + let session_guard = lock_session(&self.session)?; + self.resolve_outlets(session_guard.inputs()) } fn output_info(&self) -> Result> { - todo!() + let session_guard = lock_session(&self.session)?; + self.resolve_outlets(session_guard.outputs()) } fn model_info(&self) -> Result { - todo!() + Ok(ModelInfo { + inputs: self.input_info()?, + outputs: self.output_info()?, + providers: None, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ort::value::{Shape, SymbolicDimensions, TensorElementType}; + + fn tensor_dtype(ty: TensorElementType) -> ValueType { + ValueType::Tensor { + ty, + shape: Shape::new([1, 64]), + dimension_symbols: SymbolicDimensions::new([String::new(), String::new()]), + } + } + + #[test] + fn maps_tensor_element_types() { + assert!(matches!( + tensor_type_from_ort(&tensor_dtype(TensorElementType::Float32)), + TensorType::F32 + )); + assert!(matches!( + tensor_type_from_ort(&tensor_dtype(TensorElementType::Int64)), + TensorType::I64 + )); + assert!(matches!( + tensor_type_from_ort(&tensor_dtype(TensorElementType::Uint8)), + TensorType::Other + )); + } + + #[test] + fn resolves_static_shape() { + let shape = resolve_shape(&tensor_dtype(TensorElementType::Float32)); + assert_eq!(shape, vec![AxisDim::Static(1), AxisDim::Static(64)]); + } + + #[test] + fn resolves_dynamic_dimension_as_symbol() { + let dtype = ValueType::Tensor { + ty: TensorElementType::Float32, + shape: Shape::new([1, 64, -1]), + dimension_symbols: SymbolicDimensions::new([ + String::new(), + String::new(), + String::from("width"), + ]), + }; + let shape = resolve_shape(&dtype); + assert_eq!( + shape, + vec![ + AxisDim::Static(1), + AxisDim::Static(64), + AxisDim::Dynamic("dynamic".to_string()) + ] + ); + } + + #[test] + fn non_tensor_dtype_yields_empty_shape() { + let dtype = ValueType::Sequence(Box::new(tensor_dtype(TensorElementType::Float32))); + assert!(resolve_shape(&dtype).is_empty()); + assert!(matches!(tensor_type_from_ort(&dtype), TensorType::Other)); } } diff --git a/ddddocr-ort/src/runtime.rs b/ddddocr-ort/src/runtime.rs new file mode 100644 index 0000000..007e62c --- /dev/null +++ b/ddddocr-ort/src/runtime.rs @@ -0,0 +1,41 @@ +//! 会话执行相关的共享工具函数。 + +use crate::types::Session; +use ddddocr_core::error::TensorError; +use ort::inputs; +use ort::session::Session as OrtSession; +use ort::session::SessionOutputs; +use ort::value::{PrimitiveTensorElementType, TensorRef, Value}; +use std::sync::MutexGuard; + +/// 获取会话互斥锁,失败时转换为引擎错误。 +pub(crate) fn lock_session(session: &Session) -> Result, TensorError> { + session + .lock() + .map_err(|_| TensorError::Engine("获取 Session 锁失败 (Poisoned)".to_string())) +} + +/// 对输入张量执行一次 ORT 推理,返回原始输出值列表。 +pub(crate) fn run_session<'a>( + session: &'a mut OrtSession, + input_array: &ndarray::Array4, +) -> Result, TensorError> { + session + .run(inputs![TensorRef::from_array_view(input_array).map_err( + |e| { TensorError::Engine(format!("构建输入失败: {e}")) } + )?]) + .map_err(|e| TensorError::Engine(format!("执行模型推理失败: {e}"))) +} + +/// 从输出值中提取类型化张量视图,同时返回其真实维度。 +pub(crate) fn extract_tensor( + value: &Value, +) -> Result<(ndarray::ArrayViewD<'_, T>, Vec), TensorError> { + let (shape_ref, slice) = value + .try_extract_tensor::() + .map_err(|_| TensorError::Engine("无法获取张量内存视图".to_string()))?; + let shape: Vec = shape_ref.iter().map(|v| *v as usize).collect(); + let view = ndarray::ArrayViewD::from_shape(shape.as_slice(), slice) + .map_err(|_| TensorError::Engine("构建 ndarray ArrayViewD 失败".to_string()))?; + Ok((view, shape)) +} diff --git a/ddddocr-ort/src/types.rs b/ddddocr-ort/src/types.rs index f22a5f0..5171455 100644 --- a/ddddocr-ort/src/types.rs +++ b/ddddocr-ort/src/types.rs @@ -1,4 +1,7 @@ +//! ORT 会话共享类型。 + use ort::session::Session as OrtSession; use std::sync::{Arc, Mutex}; +/// ORT 会话句柄:由 [`crate::loader::ModelLoader`] 构建,推理时通过互斥锁串行访问。 pub type Session = Arc>; diff --git a/ddddocr-ort/tests/api_surface.rs b/ddddocr-ort/tests/api_surface.rs new file mode 100644 index 0000000..206e73a --- /dev/null +++ b/ddddocr-ort/tests/api_surface.rs @@ -0,0 +1,76 @@ +//! 外部视角 API 测试:验证 `ddddocr-ort` 的公开类型与方法在外部 crate 中可正常使用。 + +use ddddocr_core::traits::{Info, Loader}; +use ddddocr_core::types::AxisDim; +use ddddocr_core::{ModelMetadata, Normalization, OcrBuilder, Resize, SlideResult, Slider}; +use ddddocr_ort::loader::ModelLoader; +use ddddocr_ort::{DetRuntime, OcrRuntime, Session}; +use std::path::{Path, PathBuf}; + +fn model_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("models") + .join(name) +} + +/// 验证对外导出的类型(含 `Session` 与 core 便捷重导出)均可直接命名。 +#[test] +fn public_types_are_nameable() { + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _slider = Slider::new(); +} + +/// 验证构建器链式 API 可组合使用,且返回的会话类型可显式标注。 +#[test] +fn loader_chain_builds_session() -> anyhow::Result<()> { + let path = model_path("common_sml2h3_f32.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let _session: Session = ModelLoader::default() + .use_gpu(false) + .device_id(0) + .num_threads(4) + .build_for_path(path)?; + Ok(()) +} + +/// 验证 `Info` trait 能从真实会话中解析输入/输出信息。 +#[test] +fn info_trait_returns_model_metadata() -> anyhow::Result<()> { + let path = model_path("common_sml2h3_f32.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let session: Session = ModelLoader::default().build_for_path(path)?; + let metadata = ModelMetadata::from_static_slice( + &["a", "b"], + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let inputs = ocr.input_info()?; + let outputs = ocr.output_info()?; + assert!(!inputs.is_empty()); + assert!(!outputs.is_empty()); + assert!(matches!(inputs[0].shape[0], AxisDim::Static(1))); + assert!(matches!(inputs[0].shape[2], AxisDim::Static(64))); + + let model_info = ocr.model_info()?; + assert_eq!(model_info.inputs.len(), inputs.len()); + assert_eq!(model_info.outputs.len(), outputs.len()); + assert!(model_info.providers.is_none()); + Ok(()) +} + +/// 验证检测运行时可以从构建的会话创建。 +#[test] +fn det_runtime_builds_from_session() -> anyhow::Result<()> { + let path = model_path("common_det.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let session: Session = ModelLoader::default().build_for_path(path)?; + let _det = DetRuntime::new(session); + Ok(()) +} diff --git a/ddddocr-ort/tests/char_slice.rs b/ddddocr-ort/tests/char_slice.rs deleted file mode 100644 index cec0056..0000000 --- a/ddddocr-ort/tests/char_slice.rs +++ /dev/null @@ -1,600 +0,0 @@ -use std::borrow::Cow; -use std::fs::File; -use std::path::Path; -use anyhow::anyhow; -use ddddocr_core::Charset; -use ddddocr_core::{Normalization, Resize}; - -pub const CHARSET_BETA: &[&str] = &[ - "", "笤", "谴", "膀", "荔", "佰", "电", "臁", "矍", "同", "奇", "芄", "吠", "6", "曛", "荇", - "砥", "蹅", "晃", "厄", "殣", "c", "辱", "钋", "杻", "價", "眙", "鴿", "⒄", "裙", "训", "涛", - "酉", "挞", "忙", "怍", "︰", "镍", "檐", "眯", "茓", "辖", "淩", "啟", "蜀", "芟", "裟", "楝", - "彘", "嶪", "费", "亞", "滁", "榉", "朝", "f", "倻", "裎", "谧", "崂", "卑", "助", "触", "氐", - "锟", "铢", "膪", "脐", "渲", "荫", "佾", "琯", "钣", "珰", "翦", "膻", "娥", "浥", "淄", "猸", - "内", "消", "粞", "反", "苪", "冽", "酵", "玩", "父", "存", "屯", "殷", "俐", "篱", "俛", "塮", - "苕", "耲", "输", "壖", "溶", "琤", "氏", "真", "黩", "瑄", "阶", "茔", "眩", "浙", "痄", "噔", - "烤", "楯", "²", "铆", "裈", "偬", "盏", "祐", "伯", "庙", "獯", "榀", "裒", "综", "蒸", "架", - "蜱", "鹖", "涴", "肌", "廖", "祾", "蔗", "破", "!", "鑫", "瓷", "H", "宛", "倪", "贝", "酝", - "倞", "榼", "菊", "帕", "胍", "淌", "抨", "倕", "味", "独", "à", "庐", "蹲", "肸", "洹", "騳", - "绖", "觉", "蝙", "铜", "選", "郚", "奄", "手", "篦", "忮", "潺", "歁", "湖", "貔", "缚", "癫", - "捣", "翎", "勇", "徒", "杪", "捃", "纴", "郞", "蛱", "浓", "講", "薇", "汊", "彻", "琖", "觇", - "驩", "野", "闺", "彩", "膊", "簸", "瑭", "龏", "栓", "攸", "堕", "鹿", "檠", "锽", "晟", "煊", - "衖", "p", "L", "侞", "吹", "岵", "捡", "邃", "曩", "泼", "娌", "磙", "鞮", "號", "苤", "骁", - "感", "氙", "榜", "菟", "蠲", "∶", "焌", "漯", "胪", "以", "剜", "=", "衰", "剔", "疏", "韩", - "邋", "探", "搌", "握", "舵", "腰", "咐", "郎", "鈺", "赴", "斩", "铥", "棂", "褫", "秾", "城", - "葬", "缺", "甓", "沙", "鴨", "恧", "吩", "膈", "俗", "引", "濑", "坛", "蛘", "谍", "飘", "鎚", - "貋", "袅", "圃", "肽", "祖", "瑢", "鄣", "卡", "恸", "饷", "撖", "阖", "碌", "墉", "⇋", "抗", - "僇", "撩", "狷", "静", "荽", "憯", "虻", "滹", "簧", "Y", "汾", "嫁", "蚴", "岈", "榔", "邶", - "挛", "火", "w", "旌", "線", "3", "跏", "F", "楸", "瞬", "證", "現", "符", "鲀", "窸", "朗", - "m", "劉", "襄", "鸻", "敖", "憩", "濛", "胶", "雏", "禽", "缜", "鐀", "澄", "泉", "懈", "鹟", - "牙", "叟", "镖", "膨", "硷", "钏", "嵌", "冲", "橪", "厨", "溘", "妻", "贺", "耀", "潲", "瞳", - "惺", "涑", "鄄", "舡", "战", "钹", "盍", "窀", "凳", "锋", "(", "绤", "翻", "》", "嶷", "戛", - "照", "设", "两", "霹", "風", "格", "栖", "椹", "№", "蔌", "达", "悠", "旒", "函", "抔", "逆", - "疙", "玫", "箢", "恩", "樘", "远", "考", "荭", "殒", "靡", "蝾", "舅", "䀲", "偾", "灿", "埴", - "瀍", "特", "诸", "搦", "恒", "妊", "课", "劂", "殊", "艋", "柚", "硕", "捅", "钍", "芘", "脖", - "襁", "募", "卅", "疆", "嫖", "黹", "臀", "豇", "瘗", "憎", "嗯", "Θ", "跺", "喧", "捺", "爪", - "鲠", "縠", "屋", "撑", "者", "娶", "喝", "墼", "丶", "茚", "髅", "瓢", "农", "橼", "攰", "折", - "诋", "镒", "赂", "捲", "耑", "沐", "窜", "亰", "煌", "阕", "羯", "纤", "滇", "值", "琥", "渴", - "祗", "鳌", "蛞", "庄", "鹇", "訄", "犷", "弋", "琐", "佗", "氛", "揄", "旺", "聱", "榨", "湿", - "蟥", "湎", "敕", "轷", "耿", "三", "運", "瑶", "困", "勁", "蚱", "泸", "螫", "斜", "蟠", "轨", - "镞", "霆", "嶙", "烷", "瘩", "敦", "塾", "僚", "澙", "關", "酩", "殴", "—", "例", "筷", "乘", - "颗", "核", "孬", "舣", "糇", "劾", "黧", "镌", "罅", "X", "仅", "哐", "蟊", "呻", "呕", "粟", - "配", "伊", "槊", "昌", "宰", "盘", "肫", "鳥", "圾", "恬", "辘", "绿", "時", "丐", "扃", "敓", - "摄", "陕", "滿", "鹆", "嗬", "龅", "渣", "釣", "萦", "督", "孑", "∧", "疥", "噱", "蝎", "君", - "笮", "泌", "镔", "称", "柘", "鬣", "罨", "潍", "垣", "顔", "褶", "礓", "△", "骐", "湍", "獾", - "羖", "戾", "预", "祭", "鹨", "凤", "茕", "珏", "蛊", "毛", "枰", "鄭", "娲", "丕", "蜜", "纟", - "蛹", "粮", "嚰", "嚓", "螨", "裰", "G", "集", "删", "郜", "舻", "嵛", "鵰", "腊", "峄", "脸", - "鲺", "坢", "寞", "撰", "顸", "枋", "荠", "夡", "豆", "馆", "赭", "傎", "淼", "镪", "許", "礌", - "带", "訂", "饧", "锜", "及", "漾", "編", "究", "仍", "糜", "喳", "嗝", "醦", "堅", "企", "烔", - "图", "垲", "枥", "畿", "踱", "槟", "◆", "酽", "溢", "酥", "谚", "缨", "死", "镑", "干", "用", - "紊", "坑", "副", "枭", "琮", "鸨", "獻", "弈", "伺", "醍", "氓", "宁", "臻", "贾", "啐", "玉", - "咀", "孀", "烆", "嘱", "频", "蜥", "楡", "瞩", "委", "锺", "赀", "睬", "旅", "刿", "韪", "抹", - "鞘", "x", "钝", "倌", "奖", "蟭", "灌", "肼", "曰", "啊", "属", "唐", "彦", "煦", "鄘", "坦", - "鬻", "告", "单", "菽", "匏", "浚", "仺", "怜", "拦", "鸡", "拄", "乍", "燠", "暧", "竭", "⒂", - "济", "Ⓡ", "趑", "舴", "体", "拒", "罂", "说", "猎", "闫", "鄗", "妲", "鑙", "葶", "匍", "等", - "略", "盲", "唔", "钰", "渠", "镦", "葫", "蹒", "姘", "婵", "夯", "实", "何", "株", "锌", "礁", - "桺", "捉", "鮕", "莓", "轶", "辉", "溋", "视", "嗒", "猞", "猁", "杓", "怡", "咴", "巷", "仂", - "婉", "睛", "?", "淡", "/", "郛", "绨", "较", "毁", "沓", "瞎", "馏", "蕙", "戏", "i", "董", - "臣", "鹫", "栳", "锹", "裕", "蜷", "唣", "9", "缂", "螬", "笥", "惶", "蚰", "徨", "忭", "传", - "绛", "离", "锑", "候", "拓", "德", "损", "附", "紡", "徕", "錾", "蕻", "⑧", "構", "镊", "脘", - "靸", "涒", "镡", "光", "廒", "尴", "荥", "佳", "弼", "暮", "榆", "鼑", "辅", "钆", "湝", "佤", - "瘌", "炽", "筰", "嗈", "電", "飙", "坶", "椿", "俾", "灊", "泵", "像", "咅", "樓", "苒", "烨", - "溺", "棽", "戒", "箅", "愔", "缢", "楞", "庤", "塑", "湮", "沽", "蝌", "赌", "薨", "锾", "圜", - "骥", "秉", "瞌", "惇", "诊", "圣", "睢", "我", "廰", "苠", "襻", "鲚", "酮", "厮", "评", "沈", - "愀", "垞", "习", "敷", "比", "欢", "尚", "钪", "卣", "她", ",", "伴", "赃", "蚬", "喇", "醇", - "嚅", "T", "姝", "鍊", "悯", "N", "抚", "颡", "獐", "趟", "洑", "缝", "喁", "帷", "憷", "获", - "阉", "镫", "臨", "炮", "奴", "揩", "叩", "恺", "粱", "胁", "憬", "痿", "´", "沘", "彀", "饩", - "滋", "竑", "嗑", "鸟", "T", "璠", "快", "銀", "舶", "羞", "桞", "飛", "茹", "師", "偌", "節", - "冁", "叡", "臑", "踔", "酔", "養", "溦", "岐", "豉", "杌", "胩", "仳", "沾", "窑", "曳", "闷", - "垢", "垆", "磨", "髹", "態", "丽", "見", "洃", "遣", "场", "铭", "溉", "衬", "橦", "详", "馊", - "濂", "瑾", "鲫", "贞", "搴", "胺", " ", "景", "执", "袴", "炖", "箭", "楂", "婚", "镧", "厩", - "宣", "缣", "跃", "痘", "亓", "宦", "豪", "侣", "郧", "與", "痳", "挚", "殻", "嘢", "洽", "蹉", - "孽", "森", "俚", "八", "砹", "凹", "訇", "屹", "啰", "宴", "廨", "沇", "麇", "泅", "绡", "辛", - "鹲", "鋆", "旮", "婀", "幔", "赞", ":", "永", "活", "萸", "霉", "←", "媲", "阚", "鲮", "佝", - "獒", "圹", "隋", "征", "蚶", "龊", "搀", "嫫", "鬏", "幞", "學", "然", "沧", "萑", "襜", "撻", - "苯", "狳", "鞠", "咋", "壹", "栅", "款", "镘", "阳", "蚜", "荬", "糊", "疳", "糕", "镵", "寐", - "褴", "v", "醋", "诀", "汰", "啸", "备", "娘", "氚", "镓", "室", "簟", "硝", "嘌", "釐", "争", - "男", "疬", "鹄", "艳", "倒", "忸", "庶", "葒", "岖", "涨", "羝", "诼", "纨", "纰", "扉", "酎", - "藉", "疮", "枞", "黜", "戮", "芽", "鳑", "末", "蒿", "茈", "透", "渊", "秷", "〈", "试", "络", - "羼", "滪", "奋", "虏", "脁", "沫", "蓰", "襆", "披", "鲌", "艚", "逹", "炳", "泔", "叹", "轳", - "锵", "嫜", "佥", "严", "迅", "筠", "逵", "铿", "钇", "拇", "诏", "绯", "吊", "纠", "蟾", "c", - "涝", "汩", "盐", "跋", "拤", "邹", "镨", "羚", "龆", "脊", "攉", "傕", "短", "團", "蹬", "嘤", - "奎", "熨", "芪", "鸢", "濉", "''", "莴", "義", "赜", "踺", "皂", "努", "偏", "狡", "遭", "吞", - "嘿", "婊", "媸", "增", "殿", "刮", "燘", "劫", "娜", "瞄", "寡", "优", "捋", "佴", "菰", "蓠", - "笙", "镃", "樇", "瘫", "B", "橇", "逯", "堍", "О", "磐", "腼", "て", "送", "狭", "皓", "亡", - "嗉", "菠", "顺", "連", "嶶", "瑪", "辟", "婷", "牛", "笫", "窅", "萁", "戟", "覃", "馍", "建", - "謇", "旘", "镣", "燏", "葉", "轺", "倏", "堪", "见", "葛", "钕", "键", "押", "僊", "槐", "戎", - "窨", "洙", "鲢", "鞒", "慒", "雁", "圭", "D", "陌", "肱", "蜿", "洧", "惑", "祛", "樟", "矧", - "呵", "峻", "凝", "蕨", "拯", "珮", "塥", "展", "贻", "囐", "弱", "庳", "嫔", "緣", "呈", "策", - "漉", "瑗", "鲂", "鹂", "吾", "灶", "并", "挲", "重", "奭", "皙", "侪", "埗", "烬", "纾", "椒", - "技", "ɔ", "擀", "恍", "遨", "订", "雨", "卵", "锏", "猗", "癸", ")", "谡", "稷", "枨", "蹽", - "荑", "沅", "稽", "間", "冉", "颇", "酺", "份", "瞾", "毯", "藥", "蕞", "狲", "吡", "慷", "卯", - "摽", "肿", "嗛", "悒", "丨", "横", "鳡", "仫", "狎", "砗", "聿", "腥", "酡", "飱", "柳", "遽", - "汇", "湔", "麋", "垃", "粽", "坷", "鳗", "迫", "丢", "\"", "⒀", "嗲", "肐", "結", "署", "飨", - "蠡", "涩", "挈", "浿", "鐾", "姞", "隧", "铘", "呜", "蜕", "鷄", "逼", "哌", "病", "係", "偿", - "Ⅲ", "埋", "妤", "赘", "悉", "陷", "沸", "呲", "誓", "舆", "髀", "挫", "羑", "据", "顿", "淝", - "抟", "珧", "郑", "仗", "怛", "掠", "稳", "尥", "祙", "找", "郐", "锔", "轹", "钓", "黙", "饸", - "谌", "斐", "龙", "噫", "駆", "浼", "峒", "育", "纣", "溠", "铊", "亨", "杮", "呓", "钌", "业", - "繻", "溪", "戌", "蓿", "椱", "悱", "仉", "阮", "芈", "濋", "搔", "纽", "琛", "趄", "双", "镯", - "☆", "敉", "啬", "讦", "娱", "爾", "遶", "漱", "郗", "锪", "颃", "靰", "醊", "驊", "呢", "術", - "妙", "蚣", "溽", "酇", "巾", "舐", "却", "废", "邾", "砣", "乙", "鲜", "蒤", "囍", "璈", "稔", - "蘘", "匐", "業", "碟", "渺", "贤", "绋", "畑", "颞", "侥", "盟", "鼍", "阊", "蔽", "标", "吮", - "淬", "鏾", "圗", "夜", "乕", "娇", "瞿", "循", "讲", "懒", "熘", "禚", "观", "钷", "万", "n", - "未", "藝", "愿", "圈", "浩", "伦", "扛", "暄", "饶", "梧", "欣", "咿", "檔", "吼", "妮", "覆", - "辰", "誤", "允", "危", "硗", "惫", "瘪", "李", "焱", "沣", "坯", "穄", "归", "画", "营", ":", - "色", "哔", "矢", "巯", "祆", "傍", "享", "悻", "取", "凫", "铒", "唅", "眈", "疹", "败", "晴", - "顼", "绶", "剃", "斗", "禾", "4", "誜", "俨", "2", "患", "结", "可", "帇", "抍", "筝", "衢", - "鹛", "跸", "颢", "钾", "渡", "棒", "丛", "皱", "梓", "将", "压", "#", "岛", "?", "砺", "过", - "党", "挣", "瞋", "谶", "妯", "羡", "化", "淫", "歪", "鼗", "阄", "蔓", "烩", "餘", "猊", ".", - "畯", "祧", "狒", "碁", "咛", "鲈", "叨", "哞", "5", "娈", "半", "免", "拿", "畎", "媾", "棚", - "丈", "周", "匋", "酯", "奚", "爇", "摇", "搭", "蓇", "陽", "岢", "禤", "藠", "雅", "哲", "弹", - "按", "↑", "蹀", "察", "螾", "渎", "褂", "觳", "耍", "皲", "骗", "箫", "蕺", "亚", "保", "棵", - "放", "踪", "了", "熣", "亦", "痛", "币", "馐", "夢", "诱", "梱", "鲰", "郕", "璜", "祯", "颦", - "走", "踣", "嫚", "旯", "雲", "湟", "墨", "笃", "肇", "撝", "腦", "账", "舞", "⑨", "噻", "幂", - "僵", "崦", "’", "牢", "号", "嫡", "囱", "肥", "代", "锶", "掏", "随", "棓", "殉", "嘅", "掰", - "功", "垛", "踶", "娠", "霜", "碣", "鲼", "伉", "凄", "骋", "鹞", "洺", "乌", "赧", "瑛", "黎", - "曚", "鲴", "髫", "瘴", "藏", "雍", "畐", "蔻", "爼", "蹴", "巨", "贱", "汜", "胡", "虬", "椎", - "逸", "魇", "亶", "Φ", "忆", "赉", "塞", "潢", "垌", "简", "鼹", "發", "枢", "麝", "虹", "惭", - "唛", "春", "瑟", "郰", "桡", "捩", "堙", "嗨", "驳", "F", "荪", "忑", "贪", "躅", "步", "揜", - "闪", "垟", "晶", "分", "韭", "戴", "泪", "啧", "機", "峙", "和", "鸱", "绎", "屠", "阋", "黍", - "淸", "萩", "汉", "吐", "匙", "铗", "蠔", "簠", "鲵", "须", "蛣", "躏", "完", "咻", "釜", "馼", - "崤", "欻", "珐", "于", "郅", "焓", "轴", "递", "堰", "嗷", "儇", "壕", "嘟", "酸", "庾", "龂", - "妍", "锅", "雳", "桦", "抬", "谄", "气", "六", "诎", "绀", "张", "復", "客", "荞", "鳚", "衔", - "亁", "昂", "漤", "鞚", "筘", "绫", "彝", "枪", "苊", "榟", "饺", "苦", "顶", "衷", "聚", "寮", - "揆", "轪", "栋", "臂", "葖", "颋", "镐", "愕", "贸", "Q", "琼", "糥", "世", "莪", "龁", "禁", - "绲", "陶", "弑", "黢", "铵", "睐", "沄", "紬", "防", "癣", "曾", "钉", "纶", "膘", "句", "莸", - "踝", "躐", "酤", "腑", "雄", "堤", "喀", "姣", "孢", "阡", "褐", "胂", "髙", ";", "骖", "膺", - "糙", "辢", "⒃", "险", "砻", "缫", "骎", "低", "蚵", "箐", "苞", "劭", "峪", "工", "盈", "腹", - "袄", "祉", "癔", "笨", "R", "乚", "畏", "虍", "臾", "泛", "噙", "杷", "麗", "蹋", "逍", "迓", - "摅", "页", "戥", "胞", "艄", "壅", "啶", "趼", "牟", "翙", "蓝", "府", "轿", "砼", "荜", "杆", - "惊", "起", "瘅", "墈", "氖", "匀", "麃", "阘", "虮", "蘇", "蚤", "汗", "鳞", "籁", "缲", "畈", - "亟", "劬", "課", "蓄", "缅", "楮", "湜", "珩", "斋", "塬", "殁", "魃", "脞", "H", "澼", "钚", - "饕", "缕", "Ⅱ", "攮", "卿", "莅", "镆", "熹", "藩", "汁", "順", "趿", "拆", "蟹", "砒", "惴", - "㎡", "忖", "寝", "戕", "螭", "酿", "™", "柬", "枧", "凶", "蚁", "島", "殄", "鲊", "忠", "肉", - "辕", "叫", "徙", "漆", "缞", "夀", "楦", "佪", "兴", "粉", "裳", "蘧", "國", "旬", "看", "Ⅰ", - "剑", "痭", "襟", "恐", "遹", "◎", "窃", "穰", "澎", "敬", "旱", "燚", "坩", "彤", "尜", "猃", - "夏", "穈", "媒", "柑", "駡", "孛", "脉", "车", "零", "菩", "痊", "卉", "桔", "距", "吧", "漦", - "启", "仁", "滬", "馋", "帅", "鳈", "鄌", "超", "芡", "窘", "刽", "掌", "氤", "梽", "拎", "踏", - "勋", "甍", "玑", "稱", "鞍", "浍", "翅", "饟", "鼎", "罩", "加", "虚", "蕰", "簉", "堇", "巢", - "疲", "蟑", "狝", "瓮", "潋", "行", "饥", "散", "糌", "牵", "貢", "偉", "咄", "痕", "沃", "苓", - "锂", "狻", "褿", "畸", "姿", "煎", "胜", "觅", "烊", "質", "疵", "擢", "椤", "米", "累", "诳", - "斡", "K", "恻", "匦", "烫", "湾", "鹎", "吟", "摘", "涞", "恿", "嫉", "炎", "婧", "朽", "铑", - "ㆍ", "讧", "曜", "挑", "〇", "搅", "鹐", "丁", "彼", "棠", "饪", "箬", "祎", "魄", "囿", "犬", - "市", "髃", "勚", "桶", "辎", "瓞", "财", "缄", "園", "睒", "护", "尿", "融", "围", "水", "糍", - "虢", "呦", "越", "棺", "砮", "邓", "鹦", "稣", "呃", "柙", "鎌", "转", "袋", "湉", "亘", "俩", - "腆", "谣", "飔", "撂", "鄳", "爲", "盦", "谳", "卸", "W", "嚆", "婕", "卫", "拚", "呀", "汽", - "洣", "冻", "鳝", "录", "毋", "閥", "熬", "谜", "齐", "匳", "慧", "猴", "撬", "妳", "諾", "蠼", - "瘟", "伐", "颤", "奶", "陧", "麾", "岌", "浇", "邸", "「", "不", "哼", "热", "旳", "慙", "&", - "苔", "郿", "钗", "氡", "纹", "侬", "霓", "靈", "扁", "聢", "疼", "岣", "甥", "恭", "喷", "芫", - "骂", "肪", "熥", "揠", "鲷", "遁", "霎", "娆", "圩", "爬", "傲", "贽", "紫", "觑", "琇", "蟆", - "怙", "玙", "庼", "筮", "慗", "层", "娓", "蚨", "糟", "璩", "隼", "锧", "疱", "铎", "祠", "绁", - "速", "湛", "蝮", "立", "媵", "禇", "撸", "禳", ">", "恋", "⑥", "鹡", "蓑", "樱", "奸", "蝣", - "埭", "聪", "慭", "睑", "肢", "焗", "骃", "毵", "潼", "塘", "烧", "劓", "栾", "牯", "〉", "毓", - "釉", "庞", "宕", "磚", "夺", "畜", "俏", "筼", "虱", "釆", "计", "陀", "诧", "臱", "牌", "固", - "鹉", "凰", "擞", "■", "㛃", "词", "店", "當", "许", "妣", "耋", "硼", "根", "焅", "砸", "霈", - "锃", "巳", "誉", "咕", "锊", "P", "云", "乞", "为", "姆", "桕", "丞", "鳤", "楷", "醒", "趔", - "怔", "砉", "潏", "肝", "拷", "也", "璐", "厘", "致", "昇", "绥", "抃", "佩", "斥", "⑶", "断", - "纵", "翁", "耄", "沭", "洄", "别", "吻", "渍", "r", "愦", "替", "骓", "攻", "旦", "来", "案", - "坫", "辞", "班", "锝", "拜", "掎", "穸", "笛", "痂", "笈", "鲶", "僻", "依", "碎", "蕤", "炕", - "寥", "拔", "髑", "慨", "眺", "⑿", "珞", "歧", "湲", "錦", "拮", "哭", "爰", "验", "寸", "%", - "口", "阔", "积", "篝", "狴", "殂", "痧", "绽", "搪", "祸", "缘", "遯", "祜", "种", "缓", "冒", - "庵", "窥", "颂", "哕", "谘", "蜗", "掖", "驮", "郎", "跂", "蝓", "贲", "馔", "琰", "大", "芊", - "粝", "啻", "蒉", "谒", "羔", "蘑", "菑", "布", "徂", "l", "炬", "蘩", "弭", "嵎", "補", "岑", - "佯", "棍", "没", "志", "裣", "咸", "权", "豺", "韦", "優", "紧", "嚚", "牴", "酚", "沤", "睥", - "葆", "乓", "划", "犒", "惚", "埕", "锴", "就", "滓", "汕", "冏", "缵", "囟", "旸", "麂", "接", - "餮", "瓤", "偕", "灏", "溻", "揶", "钯", "荸", "宪", "泠", "槠", "抺", "威", "燴", "井", "骣", - "耜", "磔", "懜", "淇", "瘘", "蹼", "觏", "圬", "纔", "恤", "铝", "薏", "鞫", "衉", "E", "球", - "姽", "毹", "嵘", "睦", "蛉", "伽", "橥", "痤", "卞", "警", "则", "芬", "磉", "悢", "逾", "吆", - "朿", "锒", "卧", "E", "焉", "纥", "髦", "鞯", "牞", "蹿", "琪", "洌", "幛", "淳", "菲", "涔", - "噗", "勺", "势", "哓", "毪", "刖", "雜", "浪", "懵", "棁", "秋", "◇", "玡", "埯", "谥", "芑", - "拌", "Z", "埂", "寻", "虼", "豫", "蛄", "蜞", "椟", "〔", "哩", "絷", "咱", "郈", "湫", "抡", - "矮", "庖", "锰", "鎖", "葸", "棣", "砑", "题", "棋", "晕", "兠", "蓣", "貂", "裤", "昊", "扳", - "讴", "弩", "蚀", "尓", "暗", "莘", "黏", "寖", "蛔", "И", "痪", "饳", "妈", "Z", "秏", "矽", - "蘭", "艴", "菖", "寿", "撅", "秤", "颓", "廪", "醪", "耢", "螣", "椰", "麈", "听", "敞", "铠", - "润", "穑", "涟", "澹", "茨", "昨", "嚯", "钟", "護", "榇", "曦", "蜎", "呷", "邦", "瘵", "鲬", - "谖", "概", "九", "飞", "潇", "高", "锫", "钐", "徘", "诟", "缧", "剞", "【", "簋", "噍", "痋", - "关", "糁", "鹊", "潤", "邬", "赔", "序", "盤", "拙", "盾", "鸫", "迟", "氇", "塄", "庀", "噩", - "臃", "绔", "岔", "珠", "癀", "骡", "隶", "堋", "笆", "影", "昶", "飗", "α", "薄", "碜", "瞅", - "奠", "鲽", "牂", "裆", "刀", "遑", "隙", "沔", "訾", "旇", "s", "诮", "炱", "榚", "些", "縯", - "提", "甚", "埏", "峣", "意", "出", "郡", "摊", "哦", "轼", "嚒", "杈", "痢", "裥", "袖", "陔", - "溷", "裀", "迄", "枇", "筑", "貊", "鲃", "鸪", "V", "鞭", "粳", "菥", "盒", "毙", "风", "壽", - "胝", "章", "泄", "浜", "菇", "釘", "揖", "蝰", "榧", "掊", "瘿", "亍", "欤", "髻", "歃", "朱", - "撇", "铁", "兜", "喋", "趵", "瘼", "芤", "邳", "除", "滌", "么", "践", "矜", "曆", "炒", "咔", - "促", "姐", "酦", "货", "箔", "锡", "吝", "医", "汀", "精", "馘", "骶", "碉", "啷", "缉", "褪", - "阙", "滕", "蓐", "搏", "俅", "癌", "股", "圪", "孕", "鳕", "话", "鳳", "妩", "馬", "鞣", "璁", - "测", "螠", "圆", "颥", "卒", "钲", "䨱", "骢", "批", "陨", "婶", "熵", "鸣", "梁", "怅", "滑", - "驵", "帑", "鑽", "痈", "鲑", "犍", "茑", "糧", "谫", "咒", "绘", "塆", "耖", "铮", "殳", "角", - "齮", "挻", "捎", "2", "З", "廋", "泻", "犊", "儋", "椋", "聍", "鼬", "鳏", "收", "跞", "盥", - "信", "嘴", "眉", "黠", "纡", "Ω", "愆", "桹", "昽", "讠", "蚧", "龀", "鳓", "麓", "括", "蘊", - "鈇", "写", "焕", "哒", "忌", "咳", "蜮", "衄", "氰", "邘", "缇", "缮", "表", "续", "篇", "旄", - "闻", "門", "偃", "茳", "晗", "鋪", "讶", "衙", "闭", "管", "傒", "藔", "鳯", "萼", "泥", "汔", - "浆", "姚", "几", "含", "沆", "繇", "灾", "嗦", "饬", "系", "熠", "漶", "潭", "牲", "湘", "稁", - "宄", "亳", "杏", "豳", "監", "印", "旁", "辙", "播", "让", "乳", "镚", "腒", "衅", "铅", "殛", - "形", "颚", "茸", "绚", "铲", "贬", "溆", "寘", "傫", "解", "事", "旻", "差", "竣", "篃", "渥", - "嵩", "@", "鹀", "哈", "痍", "绪", "囔", "渗", "帐", "叙", "⑦", "跖", "貝", "盅", "碶", "哗", - "裼", "窝", "滙", "郸", "延", "炼", "芹", "簃", "谭", "莱", "佞", "猝", "褥", "陆", "王", "碴", - "粑", "怃", "倭", "貉", "硈", "裴", "溍", "坂", "勐", "踬", "敌", "改", "膠", "罘", "罚", "繁", - "幢", "煸", "扩", "黑", "氮", "孓", "饔", "姹", "蠖", "倬", "慝", "沩", "嚏", "雌", "琏", "莹", - "觊", "颟", "坤", "筅", "桉", "肈", "幻", "”", "烽", "蓅", "噌", "桎", "矻", "指", "瀚", "羊", - "邒", "筒", "匣", "旨", "葑", "团", "偻", "镛", "忉", "帱", "往", "刎", "害", "母", "串", "酢", - "舟", "栝", "娣", "⒉", "装", "笊", "篑", "垄", "镳", "牝", "煲", "氵", "遂", "骜", "钜", "屡", - "宇", "z", "惨", "潆", "鹃", "豌", "浞", "幄", "麺", "暽", "弁", "菤", "酲", "虑", "样", "访", - "睁", "黼", "悞", "禧", "涠", "舂", "駕", "屈", "噀", "邽", "炅", "欸", "隆", "描", "绦", "派", - "溲", "颙", "忐", "鹺", "只", "诈", "腭", "亵", "这", "炀", "趣", "喙", "跨", "場", "全", "搢", - "舨", "踢", "巿", "糸", "乐", "澈", "羰", "匯", "D", "濒", "莛", "癯", "娴", "姒", "祥", "渖", - "庭", "渑", "挹", "狉", "萍", "鹚", "焻", "自", "舸", "岫", "飑", "戍", "淙", "愠", "导", "賣", - "进", "赳", "鱿", "硂", "僤", "O", "拟", "钨", "笳", "汴", "挤", "稞", "柏", "阐", "弥", "艽", - "爻", "魭", "俶", "聂", "鲎", "齌", "菀", "僜", "煅", "满", "兀", "辔", "舊", "胥", "卢", "额", - "膝", "嵬", "昼", "唏", "璨", "苷", "舫", "倨", "耵", "碳", "鄺", "橘", "裔", "裸", "宋", "窋", - "悚", "昱", "错", "咣", "檄", "硁", "莆", "肃", "曼", "垍", "绵", "役", "內", "館", "规", "犋", - "毅", "锨", "瓘", "丘", "疝", "杀", "袗", "屏", "阎", "衹", "嚣", "冼", "铪", "熏", "t", "储", - "傧", "髁", "邙", "窴", "泾", "止", "晾", "涵", "庸", "庠", "靿", "睚", "减", "衲", "思", "簖", - "耘", "之", "斑", "扬", "袼", "缗", "菏", "滍", "研", "垚", "艘", "黇", "蜘", "汨", "侦", "疃", - "再", "沂", "榛", "励", "嚼", "拴", "钴", "珑", "撕", "鸯", "共", "醐", "揿", "醴", "凭", "菹", - "鹬", "捷", "掼", "芝", "缪", "咏", "挺", "蒗", "疖", "伸", "索", "黉", "髋", "習", "姜", "蔺", - "扶", "忽", "锉", "戚", "珲", "摸", "黛", "跌", "螈", "冚", "洱", "鼯", "庡", "痒", "哆", "品", - "歆", "登", "呔", "追", "鉫", "碾", "祚", "总", "帚", "薹", "趴", "容", "滘", "❋", "迷", "拾", - "炯", "析", "佼", "嗾", "-", "针", "滩", "禅", "讯", "織", "饱", "哟", "蹓", "侧", "蹯", "踽", - "趙", "漫", "卷", "朴", "卺", "狈", "绉", "浉", "玳", "榕", "畛", "蛾", "帔", "欠", "劙", "矾", - "進", "蚺", "骨", "捂", "疾", "璱", "圠", "坚", "弯", "秩", "逧", "烟", "佛", "嫱", "鳢", "裹", - "耥", "潮", "巽", "嶝", "廷", "鳆", "五", "西", "壤", "慌", "鴈", "爡", "‧", "儆", "萘", "愁", - "昔", "咩", "侃", "炫", "迳", "构", "缶", "皴", "捱", "菜", "秀", "粢", "畵", "辊", "伟", "榄", - "嗪", "已", "聖", "枕", "恢", "厍", "涅", "鄢", "饨", "鲨", "谪", "礤", "搁", "疔", "雎", "羿", - "犁", "硐", "盹", "若", "操", "昀", "亩", "凑", "睃", "贰", "穷", "荆", "葹", "嘃", "廓", "憔", - "制", "胧", "染", "麿", "镴", "砀", "组", "茎", "畫", "哑", "坨", "罱", "刳", "嘲", "瞰", "缏", - "侩", "谝", "谮", "还", "惋", "佈", "谏", "酗", "怩", "i", "秽", "抻", "蟪", "狠", "辑", "羟", - "娉", "肯", "毕", "枸", "啮", "鳙", "要", "娑", "蜈", "忍", "侗", "Р", "凛", "巉", "拽", "该", - "俎", "惠", "薅", "猬", "忲", "●", "哏", "柔", "沉", "磁", "脾", "龃", "鲩", "钞", "厂", "鱽", - "濞", "群", "唱", "攝", "刃", "蹻", "剕", "朊", "啜", "语", "蜻", "遠", "呖", "都", "嫄", "戢", - "丫", "酞", "修", "户", "膏", "侈", "浣", "捍", "馒", "谱", "點", "滏", "跟", "鹁", "书", "愉", - "扭", "票", "耒", "燁", "魚", "拨", "鞑", "匆", "最", "憨", "晨", "癍", "邻", "醅", "骘", "骇", - "蔫", "。", "珪", "安", "歉", "邑", "淦", "胱", "漏", "咂", "叮", "瘛", "钺", "聘", "玎", "荻", - "涰", "淏", "烈", "囚", "㙟", "矫", "嗵", "澶", "磛", "肖", "蹑", "支", "哪", "久", "嗅", "稍", - "抠", "具", "裨", "韨", "虿", "漪", "外", "埸", "ä", "葡", "鲇", "廛", "蝥", "广", "兒", "涧", - "阌", "谊", "嵴", "拂", "悸", "哳", "4", "佘", "篁", "基", "赪", "掬", "演", "谋", "酣", "植", - "波", "恅", "杼", "胀", "纯", "缩", "盆", "芷", "绺", "施", "礞", "莳", "稻", "狐", "馌", "椑", - "恃", "镩", "骼", "孱", "硭", "曈", "焼", "秕", "觥", "茛", "射", "肣", "蟞", "′", "彰", "罔", - "麻", "逋", "谓", "革", "藤", "堆", "忿", "茂", "屦", "炟", "碹", "啤", "垤", "文", "佐", "叼", - "蹭", "踉", "眍", "龟", "黾", "崋", "氘", "尼", "瞢", "悦", "罢", "瑀", "睇", "贴", "涿", "拍", - "庥", "粪", "陳", "闌", "蓍", "元", "磊", "忻", "葴", "买", "诺", "㐂", "沦", "苏", "岂", "浊", - "脍", "誠", "嚬", "蔬", "黄", "銘", "钩", "劃", "嫘", "嵖", "笄", "鸰", "熳", "堑", "河", "遮", - "尝", "灭", "愬", "娅", "鸽", "锢", "狂", "弓", "侨", "滚", "释", "晏", "徵", "苡", "佚", "切", - "惰", "降", "槎", "脑", "磺", "谟", "裉", "弘", "醺", "眇", "顒", "兰", "忧", "础", "-", "茫", - "袒", "喤", "慶", "話", "跽", "堵", "能", "武", "壳", "汤", "橐", "圧", "嗡", "簌", "斧", "林", - "楊", "净", "嫌", "猛", "炸", "冠", "弦", "洵", "°", "創", "葜", "苁", "顏", "薛", "平", "舜", - "崧", "撼", "哮", "窣", "殖", "象", "飒", "瞥", "玥", "斝", "胭", "葱", "擎", "踰", "盛", "稇", - "斫", "滴", "硫", "胬", "唁", "拐", "殍", "冱", "陪", "鋈", "烦", "辋", "妇", "轸", "潴", "荤", - "碡", "徭", "膜", "秧", "淀", "缤", "琶", "^", "肋", "违", "轭", "$", "箕", "墩", "罗", "摆", - "槛", "笠", "塃", "畚", "嘛", "秸", "≥", "剪", "羅", "帜", "庇", "骙", "酾", "康", "陬", "蝶", - "闇", "圏", "琴", "鬈", "苶", "黡", "瓠", "酋", "琎", "奏", "科", "搒", "億", "翡", "熊", "性", - "痞", "篾", "邴", "篥", "饵", "揸", "狙", "鳂", "否", "煺", "畦", "凖", "鹧", "宵", "庛", "鬯", - "袂", "昴", "徽", "奧", "鸥", "锸", "庚", "彪", "槿", "趱", "铡", "讹", "莎", "約", "璞", "┌", - "铫", "鸈", "瞀", "鼙", "廙", "估", "屺", "锘", "渝", "汶", "囵", "跻", "酏", "扎", "孜", "腔", - "吗", "块", "潽", "“", "焚", "倘", "靥", "默", "笺", "遍", "剅", "桠", "极", "夷", "眸", "泳", - "谢", "懦", ")", "泜", "物", "开", "淮", "邵", "卟", "徜", "轧", "苍", "酶", "捌", "耨", "膄", - "琦", "痦", "涪", "舰", "迥", "涘", "季", "悫", "初", "贩", "碍", "沼", "腮", "勻", "恣", "他", - "院", "7", "蜒", "叉", "昉", "瞽", "疢", "蓼", "相", "臜", "ü", "秘", "蚌", "摉", "莞", "番", - "盼", "冀", "缠", "学", "馗", "搞", "苛", "羹", "潟", "嬴", "杶", "妖", "↓", "銭", "斄", "猢", - "搂", "芦", "埶", "癜", "铴", "從", "留", "硎", "簇", "臬", "侮", "鳎", "頉", "所", "邝", "哂", - "弛", "垂", "暑", "仿", "療", "轾", "熜", "悃", "勘", "鋫", "泞", "閃", "+", "士", "虐", "盡", - "溯", "劣", "1", "锇", "蜇", "碛", "婴", "8", "捶", "藻", "嫰", "跹", "芋", "淠", "疯", "Й", - "诨", "醢", "痨", "栌", "摧", "噤", "灸", "馉", "蒇", "洲", "孪", "孵", "亿", "枝", "涕", "孟", - "缎", "攒", "湧", "褛", "铺", "廣", "诃", "蕈", "维", "珣", "逖", "瓯", "苘", "榫", "寰", "供", - "铽", "暲", "义", "兖", "喆", "祇", "蝽", "膛", "髭", "尹", "乒", "柈", "抓", "镋", "脏", "乩", - "挎", "酬", "靳", "躔", "霞", "離", "桌", "o", " ", "滨", "懷", "萭", "望", "仆", "怂", "麸", - "槁", "洨", "俬", "孚", "匕", "栩", "t", "被", "邗", "纺", "狄", "国", "苋", "眢", "秣", "畤", - "∵", "创", "嵫", "胖", "垮", "镁", "壑", "A", "趾", "荟", "汝", "嗥", "驰", "向", "磴", "讪", - "溅", "箍", "驾", "讙", "蛐", "眨", "醯", "筣", "鼫", "叠", "沥", "恕", "埽", "甩", "煜", "端", - "蜃", "帏", "丙", "荏", "圻", "夥", "暖", "抛", "岸", "头", "恝", "船", "鞲", "の", "七", "怪", - "诅", "茧", "北", "搓", "皖", "綉", "坪", "簪", "贵", "阍", "刑", "偶", "雷", "體", "髡", "岚", - "剂", "妾", "茬", "鹣", "鲳", "蜊", "假", "认", "嗍", "傈", "焘", "驷", "賀", "氆", "炝", "聋", - "嘡", "悺", "﹐", "僭", "证", "侉", "屐", "吃", "十", "〕", "瀦", "骤", "俳", "舁", "驸", "竿", - "坍", "|", "普", "軒", "瘃", "现", "醾", "铈", "榭", "蓁", "唷", "睫", "绰", "叶", "頤", "锤", - "浸", "杂", "汹", "璟", "蓖", "迦", "截", "錎", "年", "達", "劁", "码", "乃", "捯", "髪", "埚", - "呯", "頭", "镈", "汆", "β", "舷", "菂", "纸", "造", "晁", "卦", "蛎", "枉", "脯", "诛", "生", - "令", "桄", "恶", "鬟", "怯", "囡", "充", "省", "控", "螂", "笕", "邺", "扅", "斲", "骏", "鹋", - "队", "套", "镢", "牖", "I", "援", "封", "泚", "艿", "沮", "铙", "揳", "抄", "帨", "近", "唾", - "珥", "销", "非", "啱", "驼", "瓅", "遢", "筱", "奥", "善", "氩", "盉", "帖", "杜", "鈉", "蕉", - "鳄", "江", "鄂", "矩", "排", "诠", "准", "菼", "刻", "足", "峦", "灰", "僳", "蝢", "孫", "據", - "璆", "孳", "徹", "妆", "坭", "渌", "喏", "钦", "朔", "机", "徼", "掾", "其", "愧", "刹", "迹", - "惹", "闿", "鹘", "窗", "贳", "箓", "奡", "鸮", "翟", "滠", "辄", "夸", "袱", "】", "阿", "摁", - "觽", "垠", "棼", "杉", "甏", "旖", "阜", "猩", "埤", "醛", "馥", "哫", "囝", "晖", "骸", "椭", - "军", "哺", "束", "犄", "遛", "涡", "罄", "赇", "幌", "曙", "契", "饹", "圳", "仝", "爝", "示", - "敝", "漓", "马", "铐", "掳", "鲱", "蟀", "阵", "栒", "b", "轮", "俯", "嬉", "漩", "佟", "捆", - "迩", "液", "炊", "抒", "迭", "换", "菘", "请", "柩", "腓", "妥", "怖", "穆", "骝", "胛", "幺", - "燥", "棹", "孖", "洁", "边", "彥", "睨", "桁", "淆", "醤", "奘", "伙", "刘", "o", "過", "鏖", - "怄", "镗", "蘖", "卩", "龈", "枣", "联", "圊", "贫", "郭", "梗", "赡", "輸", "拼", "冰", "Ë", - "姓", "办", "拉", "富", "对", "肩", "缬", "逻", "瞠", "な", "荚", "宝", "緃", "峋", "鞁", "坉", - "译", "银", "猹", "榞", "借", "楠", "殽", "片", "谸", "雩", "琨", "颏", "晷", ";", "莠", "楽", - "嬗", "啉", "爍", "視", "岽", "荙", "冗", "『", "鯭", "觌", "喹", "药", "腈", "蹰", "–", "泷", - "榷", "卮", "缥", "各", "瘙", "凡", "悍", "劢", "6", "镰", "四", "摈", "驹", "陵", "沟", "麟", - "骊", "椀", "★", "滦", "菌", "彊", "疽", "辫", "璎", "郁", "资", "粼", "萄", "鳁", "鸤", "漁", - "痃", "绌", "蒴", "尊", "哙", "守", "坠", "胯", "泽", "持", "隅", "耧", "逛", "鄯", "瑜", "召", - "眷", "逄", "垦", "窄", "板", "赵", "源", "绹", "總", "适", "轰", "钛", "停", "唝", "燎", "栽", - "燃", "搬", "夬", "掐", "簦", "旃", "更", "蹊", "熙", "埃", "偲", "蒙", "舍", "杭", "朋", "霍", - "谙", "蓥", "赫", "鲏", "純", "缃", "蓓", "è", "萧", "锆", "诉", "恚", "u", "旷", "⑵", "褲", - "鲟", "互", "峂", "绝", "陒", "议", "脽", "态", "岙", "僮", "突", "濯", "犹", "阆", "溧", "宜", - "霣", "呆", "鄉", "觖", "濠", "耐", "橱", "敛", "踮", "怦", "鸠", "授", "滫", "叭", "镤", "仵", - "圖", "救", "变", "寕", "洋", "泃", "晥", "檎", "缦", "鏠", "悬", "彧", "韓", "籽", "磷", "歙", - "÷", "杨", "闯", "罴", "鼠", "陋", "瀣", "揾", "匪", "晚", "丧", "彷", "梏", "诽", "尻", "蹢", - "拊", "氕", "芳", "凸", "懊", "型", "媄", "憝", "骆", "纭", "刺", "悼", "藍", "欧", "葳", "艺", - "±", "紗", "钡", "钭", "首", "栈", "闩", "勃", "喑", "栉", "栟", "焊", "哀", "竖", "肘", "悲", - "鳜", "迨", "怿", "裘", "綮", "蕹", "冕", "无", "鼢", "戽", "鲣", "蜍", "插", "扯", "俣", "袪", - "级", "理", "茵", "矣", "障", "禊", "惯", "䄂", "宏", "韫", "栗", "编", "座", "跫", "、", "捞", - "谠", "車", "袆", "舖", "暝", "9", "混", "蓊", "韂", "拳", "j", "伶", "啦", "0", "诰", "缑", - "郴", "蕲", "谛", "皋", "兢", "件", "隈", "溊", "窈", "檀", "洪", "揭", "油", "颐", "剎", "侠", - "或", "腻", "迪", "舔", "牺", "倦", "夭", "蠋", "鹑", "倜", "喱", "豨", "谨", "翥", "馄", "蔚", - "类", "鳍", "泯", "岷", "張", "紅", "情", "婪", "睡", "诒", "旋", "舱", "列", "求", "姥", "翯", - "锲", "適", "蒡", "㭗", "韵", "撄", "律", "湊", "鲪", "碓", "馓", "汛", "尤", "℃", "泫", "竹", - "溃", "诵", "乡", "楹", "肷", "戋", "獭", "撴", "晤", "嘎", "裢", "轱", "歘", "鼱", "舀", "潵", - "腩", "挽", "至", "骞", "佻", "蕊", "轫", "岘", "斌", "《", "雇", "枘", "贶", "履", "亭", "绍", - "空", "泡", "擒", "蠓", "桼", "舢", "踵", "柢", "躺", "罥", "蔁", "幪", "蒯", "≤", "齉", "況", - "锕", "徇", "儿", "帽", "谕", "抽", "獍", "揪", "膳", "酴", "姊", "作", "弍", "郦", "翮", "髌", - "勝", "孔", "颁", "泩", "衾", "翊", "噉", "∩", "先", "的", "財", "绢", "崇", "饲", "賓", "绾", - "陡", "砾", "纷", "酱", "窎", "浕", "琫", "补", "嗽", "呛", "蚓", "伪", "艨", "搡", "粗", "阱", - "商", "郫", "喵", "缯", "炻", "州", "珽", "芒", "脶", "蕖", "拘", "\\", "蕃", "伏", "蛏", "璘", - "缡", "伞", "吸", "煞", "嗫", "餪", "━", "8", "漠", "衮", "峭", "筌", "阀", "乇", "杞", "镕", - "鹈", "觚", "疋", "猥", "肚", "阃", "地", "鸾", "玚", "镀", "诬", "凇", "惬", "劝", "堠", "睪", - "瞪", "涓", "專", "琢", "蠹", "裂", "芎", "轲", "谯", "畋", "长", "攘", "缁", "吵", "汈", "稂", - "咤", "甸", "瀑", "讣", "翠", "綦", "笑", "掺", "宫", "唆", "旗", "帘", "遵", "唪", "连", "必", - "姬", "枵", "渫", "神", "凱", "虞", "闵", "爭", "迢", "飓", "桴", "冑", "招", "鬶", "赊", "朦", - "薜", "逗", "铩", "焖", "狱", "昕", "犀", "捏", "侓", "爆", "箧", "怠", "缐", "苄", "踯", "暹", - "絮", "裁", "嘶", "诙", "攥", "¥", "痫", "摹", "朕", "薰", "闼", "樨", "需", "蕾", "扔", "服", - "蚩", "漳", "瞻", "陟", "诐", "爽", "耩", "坏", "寶", "瞧", "蘅", "爺", "仇", "瞈", "揉", "隰", - "阏", "皤", "鉏", "郇", "啵", "僧", "渐", "骠", "厾", "谦", "榱", "蓮", "乂", "伷", "觐", "遫", - "畀", "污", "眭", "蝗", "亢", "腾", "遇", "欺", "狸", "籼", "锯", "赚", "槔", "域", "老", "掩", - "锎", "邪", "沬", "袯", "映", "肤", "舒", "箦", "涎", "缔", "孃", "萎", "推", "峧", "嫒", "嵐", - "怒", "闾", "阅", "扢", "絡", "剩", "腢", "晌", "铟", "铚", "燔", "鄜", "墠", "擤", "芸", "鼩", - "食", "朰", "啥", "贿", "券", "垩", "典", "逭", "成", "帧", "侯", "妒", "顷", "晩", "浦", "汳", - "㾄", "坊", "②", "蝼", "倩", "挦", "騠", "蓂", "兹", "渤", "茴", "矶", "煤", "伛", "逃", "堞", - "漭", "闽", "埠", "妗", "烙", "傀", "滢", "堂", "骅", "崮", "兿", "螟", "榴", "蒈", "蟛", "员", - "嗟", "毗", "鹭", "毖", "籍", "傣", "偈", "澴", "耆", "黔", "薷", "俘", "箸", "蒺", "记", "铣", - "拥", "瑰", "抉", "史", "急", "什", "川", "曪", "剖", "罪", "扥", "鱼", "羌", "复", "昵", "朓", - "氪", "矅", "ò", "摒", "催", "{", "懂", "莉", "屃", "症", "遒", "璋", "鄒", "玄", "氦", "舳", - "納", "锷", "鲥", "羸", "怵", "嬖", "飚", "倔", "辨", "篌", "娄", "洎", "弟", "悝", "婥", "待", - "梃", "棕", "撞", "肊", "婺", "桥", "慕", "5", "尖", "监", "囊", "腎", "瘁", "⑴", "伢", "邈", - "炷", "籴", "月", "终", "龠", "蹇", "柯", "噜", "多", "玮", "踹", "泣", "圮", "辈", "鄙", "赆", - "蠃", "珈", "鬃", "识", "甑", "藓", "宥", "韧", "隗", "跚", "峁", "晒", "戳", "環", "葓", "筐", - "瑚", "稆", "巩", "葵", "网", "铨", "仡", "呶", "休", "村", "傩", "浡", "祝", "幅", "晳", "岿", - "[", "尃", "响", "咽", "讵", "淹", "糠", "驴", "烹", "甪", "焯", "整", "瘆", "茀", "瑞", "嘁", - "赅", "芼", "震", "怼", "膑", "蒟", "钊", "缷", "獨", "俄", "噪", "亏", "芍", "鲲", "黟", "酃", - "铻", "→", "鲡", "仑", "有", "扌", "治", "聆", "腙", "冬", "剥", "诓", "祃", "棘", "孥", "濆", - "鞋", "赣", "卜", "谆", "投", "琊", "塍", "洗", "津", "肴", "奕", "掴", "螗", "胸", "惦", "赠", - "耶", "蛸", "曷", "名", "栏", "崖", "始", "孤", "篆", "椴", "模", "儙", "袁", "颌", "卤", "寂", - "呸", "蓺", "噶", "钔", "粹", "潸", "郾", "娡", "啖", "芜", "䧳", "缟", "鞅", "哇", "嚄", "熛", - "私", "住", "鉄", "U", "失", "蜾", "㺃", "莨", "擂", "沕", "铄", "耰", "炔", "藐", "锈", "苇", - "芯", "檇", "龍", "珀", "筻", "褚", "缀", "棬", "仲", "杧", "铛", "挖", "缸", "嵇", "剟", "觋", - "鬼", "天", "鹪", "豭", "腴", "驿", "粵", "馈", "迸", "夕", "蜚", "禺", "迎", "狞", "嶽", "躯", - "暅", "蹾", "甾", "柆", "e", "欃", "無", "羽", "蛛", "僖", "碲", "遴", "厝", "滂", "眦", "鹅", - "咖", "潜", "媽", "啴", "寨", "琬", "判", "塌", "与", "剧", "掮", "读", "庆", "愚", "氲", "梾", - "稗", "很", "饯", "淘", "灞", "A", "!", "飾", "醚", "壁", "芮", "蔼", "知", "郯", "瞒", "术", - "法", "匠", "┅", "尕", "脂", "琅", "孝", "埙", "濟", "袷", "方", "芾", "驽", "线", "咡", "睿", - "滥", "鞨", "駹", "馎", "蛲", "申", "涣", "牗", "跄", "鲐", "泐", "铍", "肓", "é", "司", "辣", - "慑", "崞", "魏", "髯", "涯", "滃", "薪", "~", "鐵", "町", "芥", "匿", "癞", "嘚", "□", "啪", - "俇", "橛", "巅", "鄞", "痱", "回", "着", "魂", "瘀", "埒", "措", "蚪", "锁", "巴", "芏", "另", - "忏", "洇", "⑾", "箱", "劳", "榈", "B", "毒", "泰", "巍", "寇", "斛", "赖", "酒", "密", "左", - "莜", "茯", "脆", "饴", "洳", "舉", "酪", "鼒", "職", "桫", "螋", "砌", "戬", "前", "豁", "膲", - "鲯", "憋", "珺", "蹂", "亥", "冷", "蜔", "俦", "碇", "慰", "扒", "亮", "弒", "胫", "肠", "弇", - "拣", "丸", "涫", "勉", "帝", "玠", "应", "砜", "鬓", "泮", "鳖", "峇", "辗", "吴", "僡", "玊", - "钘", "惘", "奁", "翰", "爨", "罽", "莶", "纻", "菪", "興", "钧", "鄹", "缌", "嘉", "玲", "蛋", - "倚", "镬", "彳", "氯", "谐", "疗", "魉", "扈", "鏡", "涤", "佑", "勾", "饽", "R", "局", "醉", - "燫", "驱", "崽", "榮", "锄", "脎", "枓", "敲", "俑", "镶", "当", "逦", "寅", "捽", "宗", "茼", - "稿", "躇", "晋", "东", "渭", "闶", "潦", "慊", "蔟", "疑", "蜡", "嬛", "荒", "扪", "拈", "受", - "沱", "螽", "嗣", "瘰", "颖", "百", "楱", "崛", "窿", "蓬", "禨", "螵", "捕", "鳀", "霰", "瘸", - "圄", "陂", "敢", "矗", "炉", "篪", "注", "凉", "摔", "衿", "g", "遘", "鳟", "腚", "泱", "荣", - "池", "杰", "阻", "里", "峥", "葺", "翔", "柁", "飐", "载", "刨", "瘊", "溏", "嚭", "穝", "站", - "笞", "厌", "门", "汞", "雠", "靖", "怨", "葙", "厅", "凉", "荨", "底", "坼", "海", "轩", "秃", - "醭", "莒", "坎", "驺", "瀛", "嵝", "溥", "嚋", "寤", "k", "築", "耔", "跎", "小", "弊", "疭", - "√", "洞", "利", "次", "迕", "鸿", "刁", "媳", "酹", "磋", "勒", "伎", "浔", "斤", "珊", "鸳", - "颊", "塗", "刈", "龛", "縻", "楚", "脓", "南", "伧", "桨", "尸", "退", "亊", "侔", "蓟", "削", - "诲", "瑯", "挝", "绩", "嶂", "耷", "太", "著", "讥", "烂", "哥", "菔", "唳", "筫", "嚷", "斯", - "蔡", "碧", "慵", "搐", "琵", "逶", "菡", "篙", "驭", "莲", "毫", "犯", "坌", "啕", "疴", "傻", - "牧", "肺", "既", "悟", "讳", "练", "钠", "胨", "G", "迁", "帙", "嫦", "哿", "柝", "迤", "庑", - "踟", "粤", "乜", "悭", "霁", "在", "虔", "蓦", "暾", "鲅", "様", "徐", "诫", "料", "蒂", "揎", - "溜", "崎", "玦", "隐", "绳", "幼", "钼", "腧", "槌", "镅", "锿", "蹁", "猱", "狁", "蹈", "S", - "傢", "}", "珉", "浴", "龚", "吇", "肆", "⑩", "臌", "鏢", "―", "定", "哧", "螳", "爹", "摞", - "榍", "苩", "丑", "犴", "璀", "偎", "燹", "洯", "啁", "鱾", "計", "镂", "字", "琉", "壴", "霖", - "蟜", "做", "松", "扣", "徊", "叱", "桑", "≠", "寓", "崔", "茌", "`", "殓", "猖", "慎", "坻", - "皮", "喔", "耕", "拧", "织", "桂", "垝", "约", "飯", "皿", "移", "微", "桅", "钬", "赑", "宓", - "颉", "掂", "希", "沁", "翳", "澝", "崭", "聃", "蔸", "磕", "崚", "奉", "槍", "颠", "任", "飕", - "蛴", "歼", "蛭", "¥", "鉵", "刷", "泓", "頫", "诤", "阈", "诖", "漂", "冯", "柠", "本", "狼", - "芗", "丹", "柒", "饫", "衫", "摩", "桃", "啼", "譄", "醌", "帡", "少", "螃", "祷", "幸", "喘", - "噼", "甲", "刭", "泊", "那", "舄", "畲", "遊", "記", "绠", "蝈", "忒", "耙", "鹌", "搽", "绕", - "镠", "凼", "扫", "鸵", "匡", "缈", "铼", "挢", "踊", "噭", "苴", "貌", "啾", "蒜", "茱", "⒅", - "邛", "棉", "怀", "筵", "笾", "邢", "濱", "蒲", "嫠", "儡", "益", "萊", "歩", "日", "婢", "楔", - "嚎", "髂", "禄", "巫", "懿", "砍", "惆", "袭", "~", "欲", "鳅", "書", "撷", "库", "绻", "⒁", - "蒹", "辜", "屉", "奂", "龇", "诡", "醑", "儀", "讷", "聒", "盖", "浅", "長", "蛑", "念", "辒", - "蚊", "勖", "揣", "岬", "糅", "刊", "蛆", "硌", "柜", "惗", "激", "颈", "閣", "唬", "捧", "蒽", - "爸", "侏", "氧", "蛤", "牡", "瘦", "铉", "撒", "屿", "谔", "钀", "瓦", "恂", "钻", "声", "馨", - "贷", "藁", "闰", "人", "瀹", "间", "炜", "煨", "畴", "鞡", "悔", "量", "原", "屁", "杯", "趋", - "愎", "瓶", "烘", "韬", "姮", "勰", "眛", "饮", "瘐", "决", "版", "際", "俸", "此", "辽", "愫", - "爷", "隘", "螯", "腕", "闟", "厣", "齁", "矿", "女", "扇", "郄", "诚", "焜", "<", "檵", "赙", - "郢", "酌", "恳", "侵", "劍", "徳", "脔", "岍", "倍", "隹", "镲", "僬", "○", "啭", "坳", "谰", - "璪", "昆", "⒆", "惧", "虺", "篡", "锐", "邮", "嵊", "恹", "茄", "黯", "對", "魑", "禀", "添", - "汎", "廉", "戈", "∈", "陈", "肟", "螅", "缰", "啃", "瘾", "辁", "茜", "曝", "C", "餍", "蜴", - "咦", "臺", "扺", "隽", "崴", "遐", "胃", "铕", "楗", "墀", "魈", "淑", "邰", "飧", "勤", "糨", - "你", "铂", "蛰", "锻", "塈", "予", "怏", "鷪", "暂", "诞", "會", "鼐", "辏", "矬", "筜", "蟒", - "柫", "靴", "垒", "樵", "狨", "魋", "查", "掸", "'", "每", "浮", "绞", "疍", "於", "饦", "辐", - "墟", "窳", "养", "墦", "鲔", "黝", "迈", "砟", "伥", "藜", "墅", "喬", "卬", "赶", "眼", "龌", - "主", "嗞", "転", "襕", ",", "杲", "儒", "政", "蹩", "付", "Я", "厢", "点", "如", "茗", "奍", - "嗌", "蕴", "问", "膚", "硒", "佃", "居", "赍", "鯨", "槜", "衡", "廐", "鲾", "慈", "莫", "篮", - "铱", "园", "范", "靠", "叻", "绸", "众", "抑", "浃", "極", "辀", "千", "蔯", "r", "碱", "應", - "夼", "祺", "绣", "澉", "愛", "譬", "刚", "扼", "檫", "时", "荼", "部", "耽", "稀", "琳", "鎮", - "鳃", "疌", "挠", "京", "筴", "胳", "橡", "裱", "栊", "蛩", "流", "猄", "葭", "邯", "伤", "秦", - "孺", "郓", "筏", "茉", "谈", "黥", "鳇", "魅", "秫", "敫", "肄", "俪", "尺", "度", "廊", "昏", - "怎", "钎", "愤", "腿", "Λ", "碘", "囤", "婆", "煋", "桀", "阪", "焒", "砘", "澡", "阒", "臼", - "茭", "纛", "唻", "胗", "歌", "吱", "铸", "種", "礳", "舾", "砰", "即", "慥", "缆", "躞", "卖", - "眆", "搎", "鲁", "稠", "惝", "毶", "耎", "挡", "异", "咨", "歔", "垫", "素", "鳊", "打", "镏", - "耗", "锭", "剀", "讓", "鍋", "歇", "拗", "齿", "聊", "惕", "塔", "况", "汐", "采", "灣", "菁", - "峰", "呋", "阴", "衽", "鹏", "挂", "鲞", "第", "浑", "秭", "铯", "胎", "滔", "雕", "渔", "骍", - "鴻", "眚", "易", "枫", "麥", "罹", "劈", "苣", "蹄", "是", "锛", "饼", "铳", "器", "秒", "開", - "舛", "纳", "庒", "饰", "发", "虎", "乏", "届", "浯", "目", "霪", "氢", "华", "澧", "陴", "誊", - "欷", "瀌", "梵", "嗖", "惩", "妞", "螓", "溇", "嬃", "笼", "嬢", "獠", "辩", "骛", "挪", "礅", - "銎", "趺", "狍", "阑", "擦", "咙", "+", "鼻", "戆", "宿", "霏", "牁", "耦", "枳", "鲸", "阽", - "峯", "瘭", "祁", "镜", "绮", "道", "摭", "﹒", "耠", "限", "轻", "莽", "帛", "唯", "墒", "W", - "荦", "矸", "崃", "洫", "杳", "舌", "涌", "朵", "苑", "瓻", "辂", "凬", "畺", "莩", "奔", "荐", - "撵", "嶲", "憧", "沖", "邱", "瞑", "瘢", "腺", "嵯", "诗", "經", "胚", "谎", "央", "稼", "3", - "冈", "痣", "故", "皎", "珅", "踅", "硇", "通", "鹱", "草", "粕", "而", "梨", "萜", "搛", "鸺", - "托", "倡", "匾", "骷", "桐", "阇", "璃", "抖", "显", "镝", "I", "锣", "辆", "茝", "虫", "谀", - "萤", "帼", "滈", "鮼", "乔", "会", "产", "縢", "纱", "跆", "铤", "圯", "旚", "墓", "棰", "苜", - "聩", "蚍", "筢", "殇", "槚", "阂", "豊", "翚", "犰", "疚", "浠", "礴", "界", "蛙", "吁", "忪", - "讫", "辇", "汧", "澥", "纮", "糺", "拭", "镉", "鄠", "讼", "鎏", "逐", "烝", "扊", "筹", "仪", - "段", "杵", "卲", "钤", "曹", "潘", "浏", "陑", "答", "期", "橋", "位", "梅", "榻", "芨", "汭", - "贇", "杅", "伋", "馁", "皈", "躁", "鲦", "良", "幤", "曺", "榖", "便", "氍", "窍", "槃", "設", - "襦", "菓", "猡", "槲", "觱", "邠", "岩", "骈", "鬲", "睽", "残", "碗", "凯", "览", "伾", "吣", - "峡", "箨", "忡", "岁", "醵", "霸", "焐", "谁", "疟", "樾", "竺", "果", "阝", "花", "•", "耱", - "嗜", "骰", "萋", "甄", "侍", "厦", "辌", "给", "健", "垧", "娩", "校", "又", "临", "揽", "犟", - "蠢", "包", "檬", "穹", "燮", "札", "翏", "领", "深", "诶", "窒", "鸷", "统", "肾", "澍", "畹", - "职", "蝟", "眬", "旎", "朘", "眠", "篚", "贼", "貴", "#", "茆", "磬", "①", "祀", "坞", "盯", - "苹", "痼", "耪", "狺", "妓", "湨", "動", "渚", "售", "鸶", "霄", "某", "×", "铀", "桓", "脲", - "心", "节", "[", "蜩", "剐", "猜", "盂", "穿", "洮", "坜", "掷", "坐", "烜", "冶", "袍", "穴", - "偷", "槽", "面", "媛", "撙", "孩", "询", "苈", "橙", "恙", "吉", "燈", "暇", "杋", "後", "璇", - "喟", "妪", "湄", "贡", "兮", "楫", "锗", "肮", "圉", "参", "烃", "葩", "骀", "锖", "犿", "恼", - "麯", "牮", "溱", "俵", "祢", "割", "羲", "中", "博", "膦", "7", "钙", "耸", "蚋", "嘬", "逝", - "瓿", "且", "苗", "屑", "華", "糯", "吓", "陇", ".", "魆", "d", "拶", "箜", "澳", "蘼", "垸", - "钅", "樯", "侑", "娼", "赛", "恪", "击", "濮", "隔", "似", "惜", "滤", "培", "谩", "坝", "煙", - "馕", "茡", "颼", "啡", "强", "巡", "糗", "芙", "骒", "常", "鳔", "楣", "嫩", "师", "攀", "旭", - "茠", "吏", "剌", "露", "把", "携", "忘", "软", "荩", "弧", "锩", "僦", "掘", "仓", "嵚", "沲", - "傅", "蝴", "爵", "纪", "薮", "參", "荀", "珙", "逞", "蹙", "徉", "佶", "庹", "弢", "锞", "想", - "窕", "躬", "蚡", "闸", "难", "妃", "唶", "V", "蚂", "酐", "]", "羁", "土", "敏", "蝻", "赎", - "闹", "铷", "脬", "攫", "椐", "橹", "(", "暨", "剁", "灵", "咫", "苻", "赈", "萝", "鹮", "颛", - "勿", "臆", "福", "蝠", "烺", "跤", "垓", "庋", "鏊", "彭", "碚", "膂", "鐘", "鸹", "择", "疫", - "暌", "胙", "翘", "仞", "實", "猫", "嘹", "坟", "泺", "靽", "仟", "鲋", "畅", "箪", "箩", "星", - "辍", "餐", "伍", "狃", "蹐", "芴", "龋", "仨", "狩", "诌", "媚", "琚", "❤", "鉰", "仔", "忝", - "垅", "嗤", "氅", "填", "詹", "诿", "皑", "椅", "鲭", "繪", "碑", "选", "廠", "嶓", "迮", "唠", - "赏", "│", "泍", "姑", "晦", "直", "艾", "邂", "裝", "郊", "疡", "」", "鸲", "兕", "县", "邡", - "麤", "旧", "壶", "礼", "梭", "铔", "玕", "硬", "后", "馅", "窠", "俊", "犾", "槭", "姨", "妨", - "幡", "沿", "帮", "爿", "褊", "淅", "册", "诔", "使", "唢", "族", "逮", "蟋", "掣", "红", "颔", - "闲", "咧", "衍", "矛", "蹜", "抱", "雀", "箴", "雙", "茁", "聲", "芰", "瘤", "落", "峨", "秆", - "献", "霭", "胰", "墁", "柽", "跛", "阼", "菝", "谗", "蠊", "懋", "蔷", "拃", "岱", "戡", "逡", - "背", "克", "棱", "栲", "乖", "橄", "炭", "萱", "胲", "摺", "殆", "魍", "宾", "拢", "姁", "祲", - "·", "歹", "胆", "爱", "旰", "抢", "匜", "硚", "愈", "跳", "▲", "跪", "網", "糈", "維", "痹", - "娃", "疸", "痔", "褙", "芭", "鹜", "猷", "檩", "吨", "淖", "竟", "呱", "瘠", "奢", "呐", "扞", - "灼", "家", "饿", "玻", "倾", "锚", "遗", "赝", "去", "跣", "纬", "玢", "梆", "陉", "屎", "上", - "酆", "搤", "併", "腌", "避", "禹", "绅", "帆", "英", "区", "交", "▪", "巧", "豹", "游", "清", - "荧", "娀", "訓", "尾", "觫", "梢", "均", "忤", "继", "變", "喽", "尉", "骚", "趸", "馃", "石", - "置", "毡", "竴", "龄", "掭", "骟", "堡", "确", "街", "沌", "恨", "壮", "弄", "鞴", "剿", "貅", - "路", "杠", "豚", "澜", "靼", "擐", "租", "媪", "彖", "逢", "撺", "盗", "呑", "锥", "栎", "唧", - "翩", "倥", "虽", "郏", "钒", "雉", "捒", "官", "酷", "樽", "房", "屣", "堌", "蒍", "悌", "④", - "蛳", "俱", "慢", "筇", "框", "椽", "债", "吭", "柱", "夤", "嘈", "骺", "趹", "刓", "豕", "噢", - "J", "论", "俞", "仙", "碰", "经", "铋", "⑤", "顽", "曲", "得", "汪", "浒", "际", "嘏", "扮", - "祊", "嵋", "‘", "牒", "禮", "粒", "籀", "闱", "刍", "邕", "美", "苫", "靺", "铹", "莰", "蔑", - "敵", "逑", "锬", "宸", "鞥", "匝", "褀", "菅", "逊", "脱", "晔", "罾", "郝", "恰", "丟", "芩", - "枷", "鹩", "a", "夙", "述", "钢", "瀵", "铧", "翱", "尧", "醮", "&", "鳐", "懲", "濩", "树", - "劵", "虾", "砚", "腄", "罟", "硖", "崩", "埘", "╱", "血", "觯", "巂", "栀", "萏", "雪", "眵", - "白", "新", "靶", "猪", "亻", "窬", "Ⅳ", "麽", "遄", "沏", "茅", "笋", "甬", "潔", "悛", "幕", - "鹤", "悴", "耻", "觜", "滞", "己", "鏂", "肛", "婤", "嘞", "蘸", "胴", "柿", "穗", "咯", "嵕", - "蜣", "僰", "玃", "细", "▏", "戗", "尘", "仄", "子", "历", "翌", "烀", "晞", "桷", "藕", "啄", - "腐", "瘥", "诣", "彗", "捭", "懑", "陛", "傥", "沚", "贯", "﹑", "雒", "航", "跬", "晓", "赢", - "鸭", "臊", "闳", "稲", "阁", "鼋", "‰", "个", "農", "匮", "辚", "滗", "桢", "詈", "绗", "馇", - "蜓", "专", "余", "鳉", "稚", "午", "珍", "癃", "钵", "档", "颍", "厕", "岭", "祓", "诂", "襙", - "炙", "枯", "锦", "袤", "桊", "嗓", "䘵", "嫂", "丰", "苎", "梦", "早", "菱", "钱", "灯", "钮", - "锓", "豐", "蝤", "协", "h", "鼓", "燕", "覺", "涮", "呗", "専", "篓", "玷", "褓", "从", "鲍", - "羧", "俭", "萌", "樣", "颜", "谷", "夹", "囫", "』", "缙", "鹰", "条", "状", "沨", "因", "莺", - "楼", "扰", "禢", "砧", "埔", "纩", "臭", "茶", "妹", "莼", "境", "山", "诘", "蒌", "唤", "仃", - "眄", "田", "畼", "缱", "祘", "痴", "揍", "猾", "甙", "躲", "返", "砝", "叽", "苟", "肭", "悖", - "嫣", "凋", "踞", "勢", "弃", "般", "赤", "佣", "嘘", "智", "寒", "旆", "咎", "戊", "温", "昙", - "蝄", "掉", "冤", "凍", "一", "鋼", "茏", "兼", "昃", "峤", "挟", "0", "顾", "颅", "*", "遆", - "硅", "烯", "眊", "鳘", "下", "雾", "癖", "贮", "缴", "升", "劲", "婞", "掇", "梯", "壬", "撮", - "绑", "氣", "薤", "兔", "赟", "漕", "签", "顇", "砭", "鸼", "明", "佧", "鹗", "哉", "席", "趁", - "砖", "澌", "撤", "萨", "熔", "蚝", "狮", "夔", "介", "青", "喈", "郂", "埝", "狗", "哚", "咪", - "材", "跑", "炗", "龉", "髓", "衣", "觀", "淋", "寄", "羮", "抵", "恁", "藿", "蜢", "甜", "兽", - "洒", "眶", "薯", "绷", "颀", "骑", "鲻", "|", "q", "繄", "丝", "焙", "瑕", "童", "豸", "讨", - "钿", "艮", "踧", "幽", "焰", "宽", "址", "鸩", "堉", "音", "擅", "铞", "埌", "宙", "_", "钥", - "承", "率", "噬", "凌", "程", "蚕", "嘣", "饭", "橉", "径", "1", "鄏", "袜", "孙", "樊", "窦", - "牦", "歡", "罕", "蓉", "诩", "㧎", "责", "豢", "逅", "甘", "礶", "镥", "穂", "到", "檑", "皇", - "泖", "腱", "郤", "竞", "竽", "溴", "木", "蛀", "蛟", "燧", "鹳", "谵", "钳", "魔", "链", "咆", - "荡", "婳", "冢", "鲧", "昝", "※", "倫", "才", "簿", "醫", "吕", "姗", "L", "俺", "隳", "鮮", - "衩", "鲆", "崟", "鲹", "岗", "镇", "嗄", "硪", "盎", "氟", "笪", "今", "公", "尽", "佬", "骧", - "驻", "翼", "咚", "盱", "镎", "浈", "谅", "洟", "嘭", "跶", "蔹", "咭", "妁", "殚", "砷", "购", - "犸", "哄", "笸", "喂", "赋", "倓", "项", "臧", "梳", "笏", "鹝", "昭", "罿", "镄", "П", "湯", - "U", "绐", "绂", "鸬", "毐", "台", "鈴", "憾", "痰", "缭", "绒", "赁", "效", "哝", "─", "偆", - "泗", "谇", "貘", "搜", "阗", "個", "艟", "嗔", "正", "筛", "鼷", "摛", "馀", "坡", "卓", "厥", - "睾", "雯", "篷", "狰", "掀", "夫", "靛", "伻", "茇", "顧", "猕", "占", "俟", "兄", "垡", "兆", - "铃", "屙", "轵", "銮", "磲", "桤", "跷", "缳", "粘", "袢", "尬", "獘", "社", "彬", "哨", "煳", - "莊", "教", "鸸", "窖", "晰", "捻", "环", "廿", "驶", "椠", "熟", "赓", "挥", "兵", "洚", "桧", - "埼", "嘀", "哎", "柞", "悄", "调", "洼", "蛇", "铬", "蝇", "倆", "谂", "姻", "怕", "瑙", "算", - "惮", "遥", "惟", "甫", "玺", "袈", "税", "玟", "械", "擗", "淤", "溟", "揞", "纲", "谤", "條", - "翕", "荛", "忾", "馿", "糖", "檗", "垱", "┐", "躜", "缒", "您", "蹶", "合", "数", "斟", "粲", - "玖", "淞", "孰", "觎", "M", "嫪", "毽", "桩", "蹦", "亹", "胾", "亲", "痉", "莙", "捐", "烁", - "瓣", "邀", "但", "误", "饻", "妄", "镱", "民", "嗳", "竦", "柰", "脒", "斓", "瞟", "拱", "霾", - "粜", "腽", "咬", "唿", "礻", "y", "褒", "郪", "熰", "梻", "甭", "处", "拖", "蜉", "鄱", "絲", - "宠", "瞵", "荷", "靓", "喻", "阢", "伫", "担", "朐", "墙", "儣", "胄", "簏", "皆", "踌", "萃", - "命", "滟", "睹", "叁", "蟮", "東", "﹖", "式", "營", "疠", "醳", "尔", "購", "吒", "柴", "途", - "力", "疰", "寳", "萬", "挨", "碥", "牍", "嘻", "柃", "剡", "徝", "杖", "螺", "祈", "産", "煽", - "讽", "瞭", "由", "牀", "涉", "暴", "枚", "仰", "它", "胤", "驯", "港", "寵", "熄", "蛮", "务", - "殃", "亸", "涢", "妫", "粥", "扦", "寺", "抿", "湃", "C", "脚", "涸", "动", "務", "镭", "检", - "釂", "耳", "榦", "怆", "氨", "瘳", "钽", "牚", "负", "纂", "獬", "息", "婄", "襞", "囹", "酰", - "扑", "臛", "价", "褡", "篼", "媢", "酊", "腋", "愣", "垯", "喃", "牾", "犨", "蜂", "诹", "迂", - "槑", "好", "褰", "咝", "③", "劐", "骄", "腉", "仕", "叵", "磅", "金", "皁", "勍", "煮", "鍪", - "筚", "吲", "艰", "床", "叛", "﹔", "喜", "齑", "昧", "乎", "谲", "匈", "麒", "身", "唑", "鲤", - "栂", "垭", "殪", "沪", "苌", "濡", "蒎", "遏", "®", "质", "纫", "罐", "瞍", "柄", "呼", "锱", - "盔", "搋", "烛", "喉", "奈", "赦", "轘", "鉴", "瓒", "铰", "恽", "腠", "韶", "胼", "侄", "珂", - "鹕", "䝉", "呤", "椁", "岳", "汲", "疤", "绊", "涂", "乾", "噎", "兑", "絜", "嘧", "蚯", "们", - "蝉", "玛", "魁", "黻", "振", "冥", "报", "窟", "笱", "喊", "瓴", "喾", "説", "雹", "恫", "a", - "颧", "給", "宅", "鞧", "嬷", "鼾", "笔", "鲉", "匹", "蠕", "愍", "氽", "赐", "畔", "絪", "洴", - "审", "窂", "褔", "狯", "谑", "毳", "右", "疣", "鲙", "堃", "瓜", "…", "崆", "钫", "樭", "鲛", - "砂", "筋", "犏", "乱", "入", "浐", "膙", "厚", "獗", "覌", "焦", "罃", "宬", "隍", "荃", "醜", - "厉", "艇", "娟", "樂", "筲", "洛", "唼", "诜", "馑", "香", "缛", "运", "祟", "踩", "陲", "叔", - "潞", "二", "搠", "祼", "瀘", "蒋", "樗", "麦", "鸦", "棻", "古", "鹠", "怊", "裾", "够", "璧", - "晡", "擘", "毂", "御", "葚", "忱", "觞", "瑁", "唇", "罡", "剽", "殡", "沛", "帻", "举", "瞓", - "谬", "溝", "言", "哽", "婿", "猿", "跗", "獴", "俜", "呙", "弗", "凿", "窭", "铌", "友", "唉", - "怫", "荘", -]; - -pub const CHARSET_OLD: &[&str] = &["", "笤", "谴", "膀", "荔"]; - - - - -// pub fn from_builtin_old() -> Self { -// Self::from_static_slice( -// CHARSET_OLD, -// false, -// Resize::DynamicWidth(64), -// 1, -// Normalization::ZeroToOne, -// ) -// } -// -// /// 从预设的 Beta 版字符集创建 -// pub fn from_builtin_beta() -> Self { -// Self::from_static_slice( -// CHARSET_BETA, -// false, -// Resize::DynamicWidth(64), -// 1, -// Normalization::MinusOneToOne, -// ) -// } - - -// /// 从外部外部 JSON 文件动态加载字符集(在后续优化中移除) -// pub fn from_json_file>(path: P) -> anyhow::Result { -// let path = path.as_ref(); -// if !path.exists() { -// return Err(anyhow!("模型元数据配置文件不存在: {:?}", path)); -// } -// -// let mut file = File::open(path)?; -// let mut content = String::new(); -// file.read_to_string(&mut content)?; -// -// let dto: ModelMetadataDto = serde_json::from_str(&content) -// .map_err(|e| anyhow!("JSON 反序列化失败,请检查字段是否完整: {}", e))?; -// -// // 1. 将 DTO 的字符串数组转化为强类型的 Charset -// let tokens: Vec> = -// dto.charset.into_iter().map(|s| Cow::Owned(s)).collect(); -// let charset = Charset::new(tokens); -// -// // 2. 解析 resize 策略(重现 Python 的复杂条件判断) -// if dto.resize.len() != 2 { -// return Err(anyhow!( -// "'resize (or image)' 字段必须是包含两个元素的数组,例如 [-1, 64]" -// )); -// } -// let r0 = dto.resize[0]; -// let r1 = dto.resize[1]; -// -// let resize = if r0 == -1 { -// if dto.word { -// // 如果 word 为 true,且包含 -1,Python 里是 resize 为 (r1, r1) 的正方形 -// Resize::Square(r1 as u32) -// } else { -// // 如果 word 为 false,且包含 -1,Python 里是高度固定为 r1,宽度按原图比例缩放 -// Resize::DynamicWidth(r1 as u32) -// } -// } else { -// // 正常的固定宽高 -// Resize::Fixed(r0 as u32, r1 as u32) -// }; -// -// Ok(Self { -// charset, -// word: dto.word, -// resize, -// channel: dto.channel, -// normalization: dto.normalization, -// }) -// } \ No newline at end of file diff --git a/ddddocr-ort/tests/common/mod.rs b/ddddocr-ort/tests/common/mod.rs new file mode 100644 index 0000000..8c8cb5f --- /dev/null +++ b/ddddocr-ort/tests/common/mod.rs @@ -0,0 +1,25 @@ +//! 集成测试共享工具。 + +use std::path::{Path, PathBuf}; + +/// 仓库根目录 `models/` 下模型文件的路径。 +pub fn model_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("models") + .join(name) +} + +/// 仓库根目录 `samples/` 下样例图片的路径。 +pub fn sample_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("samples") + .join(name) +} + +/// 加载图片,失败时附带路径上下文。 +pub fn load_image>(path: P) -> anyhow::Result { + let path_ref = path.as_ref(); + image::open(path_ref).map_err(|e| anyhow::anyhow!("无法加载图片 {:?}: {}", path_ref, e)) +} diff --git a/ddddocr-ort/tests/det.rs b/ddddocr-ort/tests/det.rs new file mode 100644 index 0000000..b925ee7 --- /dev/null +++ b/ddddocr-ort/tests/det.rs @@ -0,0 +1,33 @@ +//! 目标检测集成测试。 + +mod common; + +use common::{model_path, sample_path}; +use ddddocr_core::Detector; +use ddddocr_core::traits::Loader; +use ddddocr_ort::DetRuntime; +use ddddocr_ort::loader::ModelLoader; +use image::GenericImageView; + +/// 检测模型应能从样例图片中找到至少一个目标,且坐标在图片范围内。 +#[test] +fn det_model_detects_targets_in_image() -> anyhow::Result<()> { + let session = ModelLoader::default() + .build_for_path(model_path("common_det.onnx")) + .expect("模型加载失败"); + let det = DetRuntime::new(session); + let img = image::open(sample_path("det1.png")).expect("测试图片不存在"); + + let bboxes = Detector::new(&det).predict(&img)?; + assert!(!bboxes.is_empty(), "应检测到至少一个目标"); + + let (width, height) = img.dimensions(); + for bbox in &bboxes { + assert!(bbox.x1 >= 0 && bbox.y1 >= 0, "检测框左上角不应为负"); + assert!( + bbox.x2 <= width as i32 && bbox.y2 <= height as i32, + "检测框右下角不应超出图片范围" + ); + } + Ok(()) +} diff --git a/ddddocr-ort/tests/ocr.rs b/ddddocr-ort/tests/ocr.rs new file mode 100644 index 0000000..608cb34 --- /dev/null +++ b/ddddocr-ort/tests/ocr.rs @@ -0,0 +1,56 @@ +//! OCR 识别与模型信息集成测试。 + +mod common; + +use common::{model_path, sample_path}; +use ddddocr_core::traits::{Info, Loader}; +use ddddocr_core::{ModelMetadata, Normalization, Ocr, Resize}; +use ddddocr_ort::OcrRuntime; +use ddddocr_ort::loader::ModelLoader; + +/// 用官方 sml2h3 f32 模型识别验证码图片,结果不应为空。 +#[test] +fn ocr_classification_recognizes_code_image() { + let session = ModelLoader::default() + .use_gpu(false) + .build_for_path(model_path("common_sml2h3_f32.onnx")) + .expect("模型加载失败"); + let metadata = ModelMetadata::from_builtin_beta( + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let img = image::open(sample_path("code2.png")).expect("测试图片不存在"); + let text = Ocr::builder() + .build_with(&ocr) + .predict(&img) + .expect("识别过程出错") + .into_text(); + + println!("识别结果: {text}"); + assert!(!text.is_empty(), "识别结果不应为空"); +} + +/// 真实模型应能通过 `Info` trait 返回输入/输出张量信息。 +#[test] +fn model_info_lists_inputs_and_outputs() -> anyhow::Result<()> { + let session = ModelLoader::default() + .build_for_path(model_path("common_huashi666_i64.onnx")) + .expect("建立测试模型图失败"); + let metadata = ModelMetadata::from_builtin_beta( + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let inputs = ocr.input_info()?; + let outputs = ocr.output_info()?; + assert!(!inputs.is_empty(), "模型应有输入张量信息"); + assert!(!outputs.is_empty(), "模型应有输出张量信息"); + Ok(()) +} diff --git a/ddddocr-ort/tests/ocr_test.rs b/ddddocr-ort/tests/ocr_test.rs deleted file mode 100644 index 23d2bad..0000000 --- a/ddddocr-ort/tests/ocr_test.rs +++ /dev/null @@ -1,253 +0,0 @@ -use anyhow::Context; -use ddddocr_core::{DetectionResult, Ocr}; -use ddddocr_core::traits::Loader; -use ddddocr_core::{Detector, ModelMetadata, Normalization, Slider}; -// 假设你的包名是这个 -use ddddocr_ort::{DetRuntime, OcrBuilder, OcrRuntime}; -use image::{DynamicImage, ImageBuffer, Luma, Rgb}; -use std::fs; -use std::path::Path; - -mod char_slice; -use char_slice::CHARSET_BETA; -use ddddocr_core::Resize; - -use ddddocr_ort::loader::ModelLoader as OrtModelLoader; - -fn load_image>(path: P) -> anyhow::Result { - // 1. 先将泛型转为具体的 &Path 引用 - let path_ref = path.as_ref(); - - // 2. 调用 open 时传入引用(utils::open 支持 AsRef) - image::open(path_ref).map_err(|e| { - // 3. 此时 path_ref 依然有效,可以安全地在闭包中使用 - anyhow::anyhow!("无法加载图片 {:?}: {}", path_ref, e) - }) -} -/// 将检测结果绘制在图像上并保存 -fn save_debug_image( - dynamic_img: &DynamicImage, // 【优化点 1】直接传入解码好的引用,拒绝重复解码 - bboxes: &[DetectionResult], // 【修改点 1】类型改为自定义结构体切片 - output_path: &str, -) -> anyhow::Result<()> { - // 删除了原本的 let dynamic_img = image::load_from_memory(image_bytes)?; - let mut img = dynamic_img.to_rgb8(); - let (width, height) = img.dimensions(); - let red = Rgb([255u8, 0, 0]); - - for bbox in bboxes { - // 【修改点 2】将原来的索引 bbox[0].. 改为结构体字段访问 .x1, .y1 .. - let x1 = bbox.x1.max(0).min(width as i32 - 1) as u32; - let y1 = bbox.y1.max(0).min(height as i32 - 1) as u32; - let x2 = bbox.x2.max(0).min(width as i32 - 1) as u32; - let y2 = bbox.y2.max(0).min(height as i32 - 1) as u32; - - // 绘制横向线条 - for x in x1..=x2 { - img.put_pixel(x, y1, red); - img.put_pixel(x, y2, red); - if y1 + 1 < height { - img.put_pixel(x, y1 + 1, red); - } - if y2.saturating_sub(1) > 0 { - img.put_pixel(x, y2 - 1, red); - } - } - // 绘制纵向线条 - for y in y1..=y2 { - img.put_pixel(x1, y, red); - img.put_pixel(x2, y, red); - if x1 + 1 < width { - img.put_pixel(x1 + 1, y, red); - } - if x2.saturating_sub(1) > 0 { - img.put_pixel(x2 - 1, y, red); - } - } - } - - img.save(output_path)?; - Ok(()) -} -#[allow(dead_code)] -fn save_rust_result(result: &ImageBuffer, Vec>, filename: &str) { - let (width, height) = result.dimensions(); - - // 1. 寻找最值进行归一化 - let mut max_val = f32::MIN; - let mut min_val = f32::MAX; - for p in result.pixels() { - if p.0[0] > max_val { - max_val = p.0[0]; - } - if p.0[0] < min_val { - min_val = p.0[0]; - } - } - - // 2. 创建 8 位灰度图 - let mut out_buf = ImageBuffer::new(width, height); - for y in 0..height { - for x in 0..width { - let val = result.get_pixel(x, y).0[0]; - let normalized = if max_val > min_val { - ((val - min_val) / (max_val - min_val) * 255.0) as u8 - } else { - 0u8 - }; - out_buf.put_pixel(x, y, Luma([normalized])); - } - } - - // 3. 保存 - DynamicImage::ImageLuma8(out_buf).save(filename).unwrap(); - println!("Rust 结果热力图已保存至: {}", filename); -} -#[test] -fn test_full_classification() { - let session = OrtModelLoader::default().use_gpu(false) - .build_for_path("D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_sml2h3_f32.onnx") - // .build_for_path("D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_old.onnx") - .expect("模型加载失败"); - let metadata = ModelMetadata::from_static_slice( - CHARSET_BETA, - false, - Resize::DynamicWidth(64), - 1, - Normalization::MinusOneToOne, - ); - // 1. 初始化模型 - let ocr = OcrRuntime::new(session, metadata); - // 2. 加载测试图片 - let img = - image::open("D:/CNWei/CNW/Rust/ddddocr-rs/samples/code2.png").expect("测试图片不存在"); - - // 3. 执行识别 - // let result = Ocr::new(&ocr) - // .predict(&img) - // .expect("识别过程出错") - // .into_text(); - // let result = OcrBuilder::new() - // .build(&ocr) - // .predict(&img) - // .expect("识别过程出错") - // .into_text(); - let res=Ocr::builder().build_with(&ocr).predict(&img).expect("s").into_text(); - - // println!("识别结果: {}", result); - println!("识别结果: {}", res); - // assert!(!result.is_empty()); - assert!(!res.is_empty()); -} -#[test] -fn test_det_load() -> anyhow::Result<()> { - let session = OrtModelLoader::default() - .build_for_path("D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_det.onnx") - .expect("模型加载失败"); - let det = DetRuntime::new(session); - let image_path = "D:/CNWei/CNW/Rust/ddddocr-rs/samples/det1.png"; - let image_bytes = - fs::read(image_path).map_err(|e| anyhow::anyhow!("无法读取图片 {}: {}", image_path, e))?; - - println!("图片读取成功,字节大小: {}", image_bytes.len()); - - // 【修改点 1】将字节流解码为统一的 DynamicImage - let img = image::load_from_memory(&image_bytes) - .map_err(|e| anyhow::anyhow!("图片解码失败: {}", e))?; - - // 【修改点 2】传入统一的 &DynamicImage 引用 - let bboxes = Detector::new(&det).predict(&img)?; - // println!("{:?}", det); - println!("检测到的目标数量: {}", bboxes.len()); - - if bboxes.is_empty() { - println!("未检测到任何目标。"); - } else { - // 如果 save_debug_image 报错,记得去把它的入参类型和内部访问也改为 DetectionResult - save_debug_image( - &img, - &bboxes, - "D:/CNWei/CNW/Rust/ddddocr-rs/samples/result.jpg", - )?; - - for (i, bbox) in bboxes.iter().enumerate() { - // 【修改点 3】将原来的 bbox[0].. 索引访问改为结构体字段访问 - println!("目标 [{}]: {}", i, bbox); - } - } - Ok(()) -} - -#[test] -fn test_real_slide_match() { - let engine = Slider::new(); - - // 1. 加载你准备好的测试图 - // 假设图片放在项目根目录下的 assets 文件夹 - let target_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/hua.png") - .expect("请确保 samples/hua.png 存在"); - let bg_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/huatu.png") - .expect("请确保 samples/huatu.png 存在"); - - // 2. 执行匹配 - // 如果是那种带有明显阴影边缘的复杂滑块,建议 simple_target 传 false - let start = std::time::Instant::now(); - let result = engine - .slide_match(&target_img, &bg_img, false) - .expect("Slide match 执行失败"); - let duration = start.elapsed(); - - // 3. 打印结果 - println!("-------------------------------------------"); - println!("{}", result); - println!("耗时: {:?}", duration); - println!("-------------------------------------------"); - - // 验证基本逻辑:坐标不应为 0 (除非匹配失败) - assert_eq!(result.target_x, 237); - assert_eq!(result.target_y, 77); - assert!(result.confidence > 0.0); -} - -#[test] -fn test_real_slide_comparison() { - let engine = Slider::new(); - - // 1. 加载你准备好的测试图 - // 假设图片放在项目根目录下的 assets 文件夹 - let target_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/ken.jpg") - .expect("请确保 samples/ken.jpg 存在"); - let bg_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/kenyuan.jpg") - .expect("请确保 samples/kenyuan.jpg 存在"); - - // 2. 执行匹配 - // 如果是那种带有明显阴影边缘的复杂滑块,建议 simple_target 传 false - let start = std::time::Instant::now(); - let result = engine - .slide_comparison(&target_img, &bg_img) - .expect("Slide match 执行失败"); - let duration = start.elapsed(); - - // 3. 打印结果 - println!("-------------------------------------------"); - println!("滑块匹配测试结果:"); - println!("检测坐标: [x: {}, y: {}]", result.target_x, result.target_y); - println!("置信度: {:.4}", result.confidence); - println!("耗时: {:?}", duration); - println!("-------------------------------------------"); - - // 验证基本逻辑:坐标不应为 0 (除非匹配失败) - assert_eq!(result.target_x, 171); - assert_eq!(result.target_y, 90); - assert!(result.confidence > 0.0); -} -#[test] -fn test_resolve_shape_logic_direct() { - // 创建一个哑 ModelLoader 实例(session 用不上,因为我们直接测私有方法) - let loader = OrtModelLoader::default() - .build_for_path( - // "D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_sml2h3_f32.onnx", - "D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_huashi666_i64.onnx", - ) - .expect("建立测试模型图失败"); -} diff --git a/ddddocr-ort/tests/slide.rs b/ddddocr-ort/tests/slide.rs new file mode 100644 index 0000000..37ae13d --- /dev/null +++ b/ddddocr-ort/tests/slide.rs @@ -0,0 +1,52 @@ +//! 滑块匹配集成测试。 + +mod common; + +use common::{load_image, sample_path}; +use ddddocr_core::Slider; + +/// 边缘模式匹配应定位到预期坐标。 +#[test] +fn slide_match_locates_target_position() { + let engine = Slider::new(); + let target = load_image(sample_path("target1.png")).expect("请确保 samples/target1.png 存在"); + let background = load_image(sample_path("background1.png")).expect("请确保 samples/background1.png 存在"); + + let start = std::time::Instant::now(); + let result = engine + .slide_match(&target, &background, false) + .expect("Slide match 执行失败"); + let elapsed = start.elapsed(); + + println!("边缘模式匹配: {result}"); + println!("耗时: {elapsed:?}"); + + assert_eq!(result.target_x, 237); + assert_eq!(result.target_y, 77); + assert!(result.confidence > 0.0); +} + +/// 灰度对比匹配应定位到预期坐标。 +#[test] +fn slide_comparison_locates_target_position() { + let engine = Slider::new(); + let target = load_image(sample_path("target2.jpg")).expect("请确保 samples/target2.jpg 存在"); + let background = + load_image(sample_path("background2.jpg")).expect("请确保 samples/background2.jpg 存在"); + + let start = std::time::Instant::now(); + let result = engine + .slide_comparison(&target, &background) + .expect("Slide comparison 执行失败"); + let elapsed = start.elapsed(); + + println!( + "灰度对比匹配: 坐标 [x: {}, y: {}], 置信度 {:.4}", + result.target_x, result.target_y, result.confidence + ); + println!("耗时: {elapsed:?}"); + + assert_eq!(result.target_x, 171); + assert_eq!(result.target_y, 90); + assert!(result.confidence > 0.0); +} diff --git a/ddddocr-tract/Cargo.toml b/ddddocr-tract/Cargo.toml deleted file mode 100644 index 7f9a569..0000000 --- a/ddddocr-tract/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "ddddocr-tract" -version = { workspace = true } -edition = { workspace = true } -license = { workspace = true } - -[dependencies] - -ddddocr-core = { path = "../ddddocr-core" } # 引入兄弟库 -tract-onnx = { workspace = true } -tract-linalg = {workspace = true } -ndarray = { workspace = true } # 继承自工作空间 - -image = { workspace = true } - -serde = { workspace = true } -serde_json = { workspace = true } - -anyhow = { workspace = true } -thiserror = { workspace = true } # 刚好可以开始接入你需要的标准库错误处理 - - - -[features] -default = [] -embed-models = [] # 这是一个留给有特殊需求、且自己下载了模型放入 models/ 目录的人的后门 \ No newline at end of file diff --git a/ddddocr-tract/src/det.rs b/ddddocr-tract/src/det.rs deleted file mode 100644 index 3e7b3f8..0000000 --- a/ddddocr-tract/src/det.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod session; \ No newline at end of file diff --git a/ddddocr-tract/src/det/session.rs b/ddddocr-tract/src/det/session.rs deleted file mode 100644 index 36072b6..0000000 --- a/ddddocr-tract/src/det/session.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::types::Session; -use ddddocr_core::error::{Result, TensorError}; -use ddddocr_core::{ DetOutput}; -use ddddocr_core::traits::{DetEngine, InferenceEngine}; -use ndarray::Ix3; -use tract_onnx::prelude::*; -#[derive(Debug)] -pub struct DetRuntime { - pub session: Session, -} - -impl DetRuntime { - pub fn new(session: Session) -> Self { - Self { session } - } - -} - -impl InferenceEngine for DetRuntime { - type Output = DetOutput; // 明确绑定 OCR 小枚举 - fn inference(&self, input_array: ndarray::Array4) -> Result { - // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 - // let result = self.ocr.run(tvec!(tensor.into()))?; - let tensor = Tensor::from(input_array); - - let mut result = self - .session - .run(tvec!(tensor.into())) - .map_err(|_| TensorError::Engine("执行模型推理失败".to_string()))?; - println!("模型输出原始数据: {:?}", result); - // Ok(result.swap_remove(0).into_tensor()) - let raw_tensor = result.swap_remove(0).into_tensor(); - // raw_tensor.into_plain_array()? - let array_d = raw_tensor.into_plain_array::().map_err(|_| { - TensorError::Engine("Tract 实体张量无法转换为 ndarray::ArrayD".to_string()) - })?; - // 提前利用克隆(Clone)备份好当前未转维度前的真实 shape (Vec) - let actual_shape = array_d.shape().to_vec(); - - let array3 = array_d.into_dimensionality::().map_err(|_| { - TensorError::DimensionMismatch { - expected: "3D 检测矩阵 [Batch, Box_Count, Box_Attributes]".to_string(), - actual: actual_shape, // 优雅降维失败时动态捕获 - } - })?; - Ok(DetOutput::Detection(array3)) - - // 在引擎内部消化掉 DatumType 强耦合 - } -} - -impl DetEngine for DetRuntime {} diff --git a/ddddocr-tract/src/error.rs b/ddddocr-tract/src/error.rs deleted file mode 100644 index 91daa51..0000000 --- a/ddddocr-tract/src/error.rs +++ /dev/null @@ -1,8 +0,0 @@ -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum TensorError { - /// 替换原有的 anyhow::Error,明确将 Tract/ONNX 引擎底层报错序列化为干净的 String - #[error("推理引擎内部发生异常: {0}")] - Engine(String), -} diff --git a/ddddocr-tract/src/lib.rs b/ddddocr-tract/src/lib.rs deleted file mode 100644 index 0b1d679..0000000 --- a/ddddocr-tract/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod det; -mod error; -pub mod loader; -mod ocr; -mod types; - -pub use ddddocr_core::{ - DetectionResult, Detector, ModelMetadata, Normalization, Ocr, OcrBuilder, SlideResult, Slider, -}; -pub use det::session::DetRuntime; -pub use ocr::session::OcrRuntime; diff --git a/ddddocr-tract/src/ocr/session.rs b/ddddocr-tract/src/ocr/session.rs deleted file mode 100644 index 6ef947b..0000000 --- a/ddddocr-tract/src/ocr/session.rs +++ /dev/null @@ -1,153 +0,0 @@ -use crate::types::Session; -use ddddocr_core::ModelMetadata; -use ddddocr_core::OcrOutput; -use ddddocr_core::error::{DdddError, Result, TensorError}; -use ddddocr_core::traits::{InferenceEngine, Info, OcrEngine}; -use ddddocr_core::types::{AxisDim, ModelInfo, TensorInfo, TensorType}; -use ddddocr_core::utils::normalize_ocr_logits; -use tract_onnx::prelude::{DatumType, OutletId, ShapeFact, TypedModel}; -use tract_onnx::prelude::{IntoTensor, Tensor, tvec}; - -pub struct OcrRuntime { - pub session: Session, - pub metadata: ModelMetadata, -} -impl OcrRuntime { - pub fn new(session: Session, metadata: ModelMetadata) -> Self { - Self { session, metadata } - } - /// 获取模型输入的节点信息列表 - - /// 提取出来的公共转换逻辑:将一组 OutletId 解析为 TensorInfo 列表 - fn resolve_tensors(&self, model: &TypedModel, outlets: &[OutletId]) -> Result> { - outlets - .iter() - .map(|&outlet_id| { - let fact = model.outlet_fact(outlet_id).map_err(DdddError::new)?; - // .map_err(|e| { - // DdddError::InternalError(format!("解析节点 Fact 失败: {:?}", e)) - // })?; - - let shape = self.resolve_shape(&fact.shape); - let node_name = model.node(outlet_id.node).name.clone(); - let tensor_type = match fact.datum_type { - DatumType::F32 => TensorType::F32, - DatumType::I64 => TensorType::I64, - _ => TensorType::Other, - }; - - Ok(TensorInfo { - name: node_name, - shape, - tensor_type, - }) - }) - .collect() // 函数式声明:自动传播第一处发生的错误 - } - - /// 安全还原 Tract 维度至 Vec - fn resolve_shape(&self, shape_fact: &ShapeFact) -> Vec { - let tract_shape = shape_fact.to_tvec(); - - let resolved = tract_shape - .iter() - .map(|dim| { - // 防御性编程:必须同时满足能够转换为 i64 且 大于等于 0 - if let Ok(size) = dim.to_i64() { - if size >= 0 { - AxisDim::Static(size as usize) - } else { - // 如果 ONNX 导出时某些动态维度被标记为了 -1,安全地作为动态符号捕获 - AxisDim::Dynamic(dim.to_string()) - } - } else { - AxisDim::Dynamic(dim.to_string()) - } - }) - .collect(); - - resolved - } -} -impl OcrEngine for OcrRuntime { - fn metadata(&self) -> &ModelMetadata { - &self.metadata - } -} -impl InferenceEngine for OcrRuntime { - type Output = OcrOutput; - /// 对应 Python 的 _inference - fn inference(&self, input_array: ndarray::Array4) -> Result { - // tract 的 run 会返回一个 Vec,我们通常只需要第一个输出 - // let result = self.ocr.run(tvec!(tensor.into()))?; - let tensor = Tensor::from(input_array); - - let mut result = self - .session - .run(tvec!(tensor.into())) - .map_err(|_| TensorError::Engine("执行模型推理失败".to_string()))?; - // .context("执行模型推理失败")?; - println!("模型输出原始数据: {:?}", result); - // Ok(result.swap_remove(0).into_tensor()) - let raw_tensor = result.swap_remove(0).into_tensor(); - // 在引擎内部消化掉 DatumType 强耦合 - match raw_tensor.datum_type() { - DatumType::I64 => { - let array_d = raw_tensor - .into_plain_array::() - .map_err(|_| TensorError::Engine("Tract 无法获取 i64 内存视图".to_string()))?; - // .context("Tract 无法获取 i64 内存视图")?; - // 🌟 提前提取真实维度 - let actual_shape = array_d.shape().to_vec(); - // 转成标准的 Array1 传给 core - let array1 = array_d - .to_owned() - .into_dimensionality::() - .map_err(|_| TensorError::DimensionMismatch { - expected: "1D 字符索引静态矩阵".to_string(), - actual: actual_shape, - })?; - Ok(OcrOutput::Indices(array1)) - } - DatumType::F32 => { - let shape = raw_tensor.shape(); - println!("模型输出shape数据: {:?}", shape); - // raw_tensor.to_plain_array_view() - let view = raw_tensor - .to_plain_array_view::() - .map_err(|_| TensorError::Engine("Tract 无法获取 f32 内存视图".to_string()))?; - // 1. 极其纯粹的、无拷贝的多维 Shape 压扁清洗 - normalize_ocr_logits(view, shape) - } - _ => Err( - // anyhow::anyhow!("不支持的模型输出数据类型: {:?}",raw_tensor.datum_type()) - TensorError::UnknownOutputFormat, - ), - } - } -} -impl Info for OcrRuntime { - fn input_info(&self) -> Result> { - let model = self.session.model(); - let outlets = model.input_outlets().map_err(DdddError::new)?; - self.resolve_tensors(model, outlets) - } - - /// 获取模型输出的节点信息列表 - fn output_info(&self) -> Result> { - let model = self.session.model(); - let outlets = model.output_outlets().map_err(DdddError::new)?; - self.resolve_tensors(model, outlets) - } - - /// 获取模型详细元数据信息(对标 Python ddddocr 的 get_model_info) - /// 完美包容 [1, 1, 64, image_width] 这样的变长图像模型 - /// 获取模型详细元数据信息(代码更紧凑、优雅) - fn model_info(&self) -> Result { - Ok(ModelInfo { - inputs: self.input_info()?, - outputs: self.output_info()?, - providers: None, - }) - } -} diff --git a/ddddocr-tract/src/types.rs b/ddddocr-tract/src/types.rs deleted file mode 100644 index dcf55ef..0000000 --- a/ddddocr-tract/src/types.rs +++ /dev/null @@ -1,4 +0,0 @@ -use std::sync::Arc; -use tract_onnx::prelude::TypedRunnableModel; - -pub type Session = Arc; diff --git a/ddddocr-tract/tests/char_slice.rs b/ddddocr-tract/tests/char_slice.rs deleted file mode 100644 index cec0056..0000000 --- a/ddddocr-tract/tests/char_slice.rs +++ /dev/null @@ -1,600 +0,0 @@ -use std::borrow::Cow; -use std::fs::File; -use std::path::Path; -use anyhow::anyhow; -use ddddocr_core::Charset; -use ddddocr_core::{Normalization, Resize}; - -pub const CHARSET_BETA: &[&str] = &[ - "", "笤", "谴", "膀", "荔", "佰", "电", "臁", "矍", "同", "奇", "芄", "吠", "6", "曛", "荇", - "砥", "蹅", "晃", "厄", "殣", "c", "辱", "钋", "杻", "價", "眙", "鴿", "⒄", "裙", "训", "涛", - "酉", "挞", "忙", "怍", "︰", "镍", "檐", "眯", "茓", "辖", "淩", "啟", "蜀", "芟", "裟", "楝", - "彘", "嶪", "费", "亞", "滁", "榉", "朝", "f", "倻", "裎", "谧", "崂", "卑", "助", "触", "氐", - "锟", "铢", "膪", "脐", "渲", "荫", "佾", "琯", "钣", "珰", "翦", "膻", "娥", "浥", "淄", "猸", - "内", "消", "粞", "反", "苪", "冽", "酵", "玩", "父", "存", "屯", "殷", "俐", "篱", "俛", "塮", - "苕", "耲", "输", "壖", "溶", "琤", "氏", "真", "黩", "瑄", "阶", "茔", "眩", "浙", "痄", "噔", - "烤", "楯", "²", "铆", "裈", "偬", "盏", "祐", "伯", "庙", "獯", "榀", "裒", "综", "蒸", "架", - "蜱", "鹖", "涴", "肌", "廖", "祾", "蔗", "破", "!", "鑫", "瓷", "H", "宛", "倪", "贝", "酝", - "倞", "榼", "菊", "帕", "胍", "淌", "抨", "倕", "味", "独", "à", "庐", "蹲", "肸", "洹", "騳", - "绖", "觉", "蝙", "铜", "選", "郚", "奄", "手", "篦", "忮", "潺", "歁", "湖", "貔", "缚", "癫", - "捣", "翎", "勇", "徒", "杪", "捃", "纴", "郞", "蛱", "浓", "講", "薇", "汊", "彻", "琖", "觇", - "驩", "野", "闺", "彩", "膊", "簸", "瑭", "龏", "栓", "攸", "堕", "鹿", "檠", "锽", "晟", "煊", - "衖", "p", "L", "侞", "吹", "岵", "捡", "邃", "曩", "泼", "娌", "磙", "鞮", "號", "苤", "骁", - "感", "氙", "榜", "菟", "蠲", "∶", "焌", "漯", "胪", "以", "剜", "=", "衰", "剔", "疏", "韩", - "邋", "探", "搌", "握", "舵", "腰", "咐", "郎", "鈺", "赴", "斩", "铥", "棂", "褫", "秾", "城", - "葬", "缺", "甓", "沙", "鴨", "恧", "吩", "膈", "俗", "引", "濑", "坛", "蛘", "谍", "飘", "鎚", - "貋", "袅", "圃", "肽", "祖", "瑢", "鄣", "卡", "恸", "饷", "撖", "阖", "碌", "墉", "⇋", "抗", - "僇", "撩", "狷", "静", "荽", "憯", "虻", "滹", "簧", "Y", "汾", "嫁", "蚴", "岈", "榔", "邶", - "挛", "火", "w", "旌", "線", "3", "跏", "F", "楸", "瞬", "證", "現", "符", "鲀", "窸", "朗", - "m", "劉", "襄", "鸻", "敖", "憩", "濛", "胶", "雏", "禽", "缜", "鐀", "澄", "泉", "懈", "鹟", - "牙", "叟", "镖", "膨", "硷", "钏", "嵌", "冲", "橪", "厨", "溘", "妻", "贺", "耀", "潲", "瞳", - "惺", "涑", "鄄", "舡", "战", "钹", "盍", "窀", "凳", "锋", "(", "绤", "翻", "》", "嶷", "戛", - "照", "设", "两", "霹", "風", "格", "栖", "椹", "№", "蔌", "达", "悠", "旒", "函", "抔", "逆", - "疙", "玫", "箢", "恩", "樘", "远", "考", "荭", "殒", "靡", "蝾", "舅", "䀲", "偾", "灿", "埴", - "瀍", "特", "诸", "搦", "恒", "妊", "课", "劂", "殊", "艋", "柚", "硕", "捅", "钍", "芘", "脖", - "襁", "募", "卅", "疆", "嫖", "黹", "臀", "豇", "瘗", "憎", "嗯", "Θ", "跺", "喧", "捺", "爪", - "鲠", "縠", "屋", "撑", "者", "娶", "喝", "墼", "丶", "茚", "髅", "瓢", "农", "橼", "攰", "折", - "诋", "镒", "赂", "捲", "耑", "沐", "窜", "亰", "煌", "阕", "羯", "纤", "滇", "值", "琥", "渴", - "祗", "鳌", "蛞", "庄", "鹇", "訄", "犷", "弋", "琐", "佗", "氛", "揄", "旺", "聱", "榨", "湿", - "蟥", "湎", "敕", "轷", "耿", "三", "運", "瑶", "困", "勁", "蚱", "泸", "螫", "斜", "蟠", "轨", - "镞", "霆", "嶙", "烷", "瘩", "敦", "塾", "僚", "澙", "關", "酩", "殴", "—", "例", "筷", "乘", - "颗", "核", "孬", "舣", "糇", "劾", "黧", "镌", "罅", "X", "仅", "哐", "蟊", "呻", "呕", "粟", - "配", "伊", "槊", "昌", "宰", "盘", "肫", "鳥", "圾", "恬", "辘", "绿", "時", "丐", "扃", "敓", - "摄", "陕", "滿", "鹆", "嗬", "龅", "渣", "釣", "萦", "督", "孑", "∧", "疥", "噱", "蝎", "君", - "笮", "泌", "镔", "称", "柘", "鬣", "罨", "潍", "垣", "顔", "褶", "礓", "△", "骐", "湍", "獾", - "羖", "戾", "预", "祭", "鹨", "凤", "茕", "珏", "蛊", "毛", "枰", "鄭", "娲", "丕", "蜜", "纟", - "蛹", "粮", "嚰", "嚓", "螨", "裰", "G", "集", "删", "郜", "舻", "嵛", "鵰", "腊", "峄", "脸", - "鲺", "坢", "寞", "撰", "顸", "枋", "荠", "夡", "豆", "馆", "赭", "傎", "淼", "镪", "許", "礌", - "带", "訂", "饧", "锜", "及", "漾", "編", "究", "仍", "糜", "喳", "嗝", "醦", "堅", "企", "烔", - "图", "垲", "枥", "畿", "踱", "槟", "◆", "酽", "溢", "酥", "谚", "缨", "死", "镑", "干", "用", - "紊", "坑", "副", "枭", "琮", "鸨", "獻", "弈", "伺", "醍", "氓", "宁", "臻", "贾", "啐", "玉", - "咀", "孀", "烆", "嘱", "频", "蜥", "楡", "瞩", "委", "锺", "赀", "睬", "旅", "刿", "韪", "抹", - "鞘", "x", "钝", "倌", "奖", "蟭", "灌", "肼", "曰", "啊", "属", "唐", "彦", "煦", "鄘", "坦", - "鬻", "告", "单", "菽", "匏", "浚", "仺", "怜", "拦", "鸡", "拄", "乍", "燠", "暧", "竭", "⒂", - "济", "Ⓡ", "趑", "舴", "体", "拒", "罂", "说", "猎", "闫", "鄗", "妲", "鑙", "葶", "匍", "等", - "略", "盲", "唔", "钰", "渠", "镦", "葫", "蹒", "姘", "婵", "夯", "实", "何", "株", "锌", "礁", - "桺", "捉", "鮕", "莓", "轶", "辉", "溋", "视", "嗒", "猞", "猁", "杓", "怡", "咴", "巷", "仂", - "婉", "睛", "?", "淡", "/", "郛", "绨", "较", "毁", "沓", "瞎", "馏", "蕙", "戏", "i", "董", - "臣", "鹫", "栳", "锹", "裕", "蜷", "唣", "9", "缂", "螬", "笥", "惶", "蚰", "徨", "忭", "传", - "绛", "离", "锑", "候", "拓", "德", "损", "附", "紡", "徕", "錾", "蕻", "⑧", "構", "镊", "脘", - "靸", "涒", "镡", "光", "廒", "尴", "荥", "佳", "弼", "暮", "榆", "鼑", "辅", "钆", "湝", "佤", - "瘌", "炽", "筰", "嗈", "電", "飙", "坶", "椿", "俾", "灊", "泵", "像", "咅", "樓", "苒", "烨", - "溺", "棽", "戒", "箅", "愔", "缢", "楞", "庤", "塑", "湮", "沽", "蝌", "赌", "薨", "锾", "圜", - "骥", "秉", "瞌", "惇", "诊", "圣", "睢", "我", "廰", "苠", "襻", "鲚", "酮", "厮", "评", "沈", - "愀", "垞", "习", "敷", "比", "欢", "尚", "钪", "卣", "她", ",", "伴", "赃", "蚬", "喇", "醇", - "嚅", "T", "姝", "鍊", "悯", "N", "抚", "颡", "獐", "趟", "洑", "缝", "喁", "帷", "憷", "获", - "阉", "镫", "臨", "炮", "奴", "揩", "叩", "恺", "粱", "胁", "憬", "痿", "´", "沘", "彀", "饩", - "滋", "竑", "嗑", "鸟", "T", "璠", "快", "銀", "舶", "羞", "桞", "飛", "茹", "師", "偌", "節", - "冁", "叡", "臑", "踔", "酔", "養", "溦", "岐", "豉", "杌", "胩", "仳", "沾", "窑", "曳", "闷", - "垢", "垆", "磨", "髹", "態", "丽", "見", "洃", "遣", "场", "铭", "溉", "衬", "橦", "详", "馊", - "濂", "瑾", "鲫", "贞", "搴", "胺", " ", "景", "执", "袴", "炖", "箭", "楂", "婚", "镧", "厩", - "宣", "缣", "跃", "痘", "亓", "宦", "豪", "侣", "郧", "與", "痳", "挚", "殻", "嘢", "洽", "蹉", - "孽", "森", "俚", "八", "砹", "凹", "訇", "屹", "啰", "宴", "廨", "沇", "麇", "泅", "绡", "辛", - "鹲", "鋆", "旮", "婀", "幔", "赞", ":", "永", "活", "萸", "霉", "←", "媲", "阚", "鲮", "佝", - "獒", "圹", "隋", "征", "蚶", "龊", "搀", "嫫", "鬏", "幞", "學", "然", "沧", "萑", "襜", "撻", - "苯", "狳", "鞠", "咋", "壹", "栅", "款", "镘", "阳", "蚜", "荬", "糊", "疳", "糕", "镵", "寐", - "褴", "v", "醋", "诀", "汰", "啸", "备", "娘", "氚", "镓", "室", "簟", "硝", "嘌", "釐", "争", - "男", "疬", "鹄", "艳", "倒", "忸", "庶", "葒", "岖", "涨", "羝", "诼", "纨", "纰", "扉", "酎", - "藉", "疮", "枞", "黜", "戮", "芽", "鳑", "末", "蒿", "茈", "透", "渊", "秷", "〈", "试", "络", - "羼", "滪", "奋", "虏", "脁", "沫", "蓰", "襆", "披", "鲌", "艚", "逹", "炳", "泔", "叹", "轳", - "锵", "嫜", "佥", "严", "迅", "筠", "逵", "铿", "钇", "拇", "诏", "绯", "吊", "纠", "蟾", "c", - "涝", "汩", "盐", "跋", "拤", "邹", "镨", "羚", "龆", "脊", "攉", "傕", "短", "團", "蹬", "嘤", - "奎", "熨", "芪", "鸢", "濉", "''", "莴", "義", "赜", "踺", "皂", "努", "偏", "狡", "遭", "吞", - "嘿", "婊", "媸", "增", "殿", "刮", "燘", "劫", "娜", "瞄", "寡", "优", "捋", "佴", "菰", "蓠", - "笙", "镃", "樇", "瘫", "B", "橇", "逯", "堍", "О", "磐", "腼", "て", "送", "狭", "皓", "亡", - "嗉", "菠", "顺", "連", "嶶", "瑪", "辟", "婷", "牛", "笫", "窅", "萁", "戟", "覃", "馍", "建", - "謇", "旘", "镣", "燏", "葉", "轺", "倏", "堪", "见", "葛", "钕", "键", "押", "僊", "槐", "戎", - "窨", "洙", "鲢", "鞒", "慒", "雁", "圭", "D", "陌", "肱", "蜿", "洧", "惑", "祛", "樟", "矧", - "呵", "峻", "凝", "蕨", "拯", "珮", "塥", "展", "贻", "囐", "弱", "庳", "嫔", "緣", "呈", "策", - "漉", "瑗", "鲂", "鹂", "吾", "灶", "并", "挲", "重", "奭", "皙", "侪", "埗", "烬", "纾", "椒", - "技", "ɔ", "擀", "恍", "遨", "订", "雨", "卵", "锏", "猗", "癸", ")", "谡", "稷", "枨", "蹽", - "荑", "沅", "稽", "間", "冉", "颇", "酺", "份", "瞾", "毯", "藥", "蕞", "狲", "吡", "慷", "卯", - "摽", "肿", "嗛", "悒", "丨", "横", "鳡", "仫", "狎", "砗", "聿", "腥", "酡", "飱", "柳", "遽", - "汇", "湔", "麋", "垃", "粽", "坷", "鳗", "迫", "丢", "\"", "⒀", "嗲", "肐", "結", "署", "飨", - "蠡", "涩", "挈", "浿", "鐾", "姞", "隧", "铘", "呜", "蜕", "鷄", "逼", "哌", "病", "係", "偿", - "Ⅲ", "埋", "妤", "赘", "悉", "陷", "沸", "呲", "誓", "舆", "髀", "挫", "羑", "据", "顿", "淝", - "抟", "珧", "郑", "仗", "怛", "掠", "稳", "尥", "祙", "找", "郐", "锔", "轹", "钓", "黙", "饸", - "谌", "斐", "龙", "噫", "駆", "浼", "峒", "育", "纣", "溠", "铊", "亨", "杮", "呓", "钌", "业", - "繻", "溪", "戌", "蓿", "椱", "悱", "仉", "阮", "芈", "濋", "搔", "纽", "琛", "趄", "双", "镯", - "☆", "敉", "啬", "讦", "娱", "爾", "遶", "漱", "郗", "锪", "颃", "靰", "醊", "驊", "呢", "術", - "妙", "蚣", "溽", "酇", "巾", "舐", "却", "废", "邾", "砣", "乙", "鲜", "蒤", "囍", "璈", "稔", - "蘘", "匐", "業", "碟", "渺", "贤", "绋", "畑", "颞", "侥", "盟", "鼍", "阊", "蔽", "标", "吮", - "淬", "鏾", "圗", "夜", "乕", "娇", "瞿", "循", "讲", "懒", "熘", "禚", "观", "钷", "万", "n", - "未", "藝", "愿", "圈", "浩", "伦", "扛", "暄", "饶", "梧", "欣", "咿", "檔", "吼", "妮", "覆", - "辰", "誤", "允", "危", "硗", "惫", "瘪", "李", "焱", "沣", "坯", "穄", "归", "画", "营", ":", - "色", "哔", "矢", "巯", "祆", "傍", "享", "悻", "取", "凫", "铒", "唅", "眈", "疹", "败", "晴", - "顼", "绶", "剃", "斗", "禾", "4", "誜", "俨", "2", "患", "结", "可", "帇", "抍", "筝", "衢", - "鹛", "跸", "颢", "钾", "渡", "棒", "丛", "皱", "梓", "将", "压", "#", "岛", "?", "砺", "过", - "党", "挣", "瞋", "谶", "妯", "羡", "化", "淫", "歪", "鼗", "阄", "蔓", "烩", "餘", "猊", ".", - "畯", "祧", "狒", "碁", "咛", "鲈", "叨", "哞", "5", "娈", "半", "免", "拿", "畎", "媾", "棚", - "丈", "周", "匋", "酯", "奚", "爇", "摇", "搭", "蓇", "陽", "岢", "禤", "藠", "雅", "哲", "弹", - "按", "↑", "蹀", "察", "螾", "渎", "褂", "觳", "耍", "皲", "骗", "箫", "蕺", "亚", "保", "棵", - "放", "踪", "了", "熣", "亦", "痛", "币", "馐", "夢", "诱", "梱", "鲰", "郕", "璜", "祯", "颦", - "走", "踣", "嫚", "旯", "雲", "湟", "墨", "笃", "肇", "撝", "腦", "账", "舞", "⑨", "噻", "幂", - "僵", "崦", "’", "牢", "号", "嫡", "囱", "肥", "代", "锶", "掏", "随", "棓", "殉", "嘅", "掰", - "功", "垛", "踶", "娠", "霜", "碣", "鲼", "伉", "凄", "骋", "鹞", "洺", "乌", "赧", "瑛", "黎", - "曚", "鲴", "髫", "瘴", "藏", "雍", "畐", "蔻", "爼", "蹴", "巨", "贱", "汜", "胡", "虬", "椎", - "逸", "魇", "亶", "Φ", "忆", "赉", "塞", "潢", "垌", "简", "鼹", "發", "枢", "麝", "虹", "惭", - "唛", "春", "瑟", "郰", "桡", "捩", "堙", "嗨", "驳", "F", "荪", "忑", "贪", "躅", "步", "揜", - "闪", "垟", "晶", "分", "韭", "戴", "泪", "啧", "機", "峙", "和", "鸱", "绎", "屠", "阋", "黍", - "淸", "萩", "汉", "吐", "匙", "铗", "蠔", "簠", "鲵", "须", "蛣", "躏", "完", "咻", "釜", "馼", - "崤", "欻", "珐", "于", "郅", "焓", "轴", "递", "堰", "嗷", "儇", "壕", "嘟", "酸", "庾", "龂", - "妍", "锅", "雳", "桦", "抬", "谄", "气", "六", "诎", "绀", "张", "復", "客", "荞", "鳚", "衔", - "亁", "昂", "漤", "鞚", "筘", "绫", "彝", "枪", "苊", "榟", "饺", "苦", "顶", "衷", "聚", "寮", - "揆", "轪", "栋", "臂", "葖", "颋", "镐", "愕", "贸", "Q", "琼", "糥", "世", "莪", "龁", "禁", - "绲", "陶", "弑", "黢", "铵", "睐", "沄", "紬", "防", "癣", "曾", "钉", "纶", "膘", "句", "莸", - "踝", "躐", "酤", "腑", "雄", "堤", "喀", "姣", "孢", "阡", "褐", "胂", "髙", ";", "骖", "膺", - "糙", "辢", "⒃", "险", "砻", "缫", "骎", "低", "蚵", "箐", "苞", "劭", "峪", "工", "盈", "腹", - "袄", "祉", "癔", "笨", "R", "乚", "畏", "虍", "臾", "泛", "噙", "杷", "麗", "蹋", "逍", "迓", - "摅", "页", "戥", "胞", "艄", "壅", "啶", "趼", "牟", "翙", "蓝", "府", "轿", "砼", "荜", "杆", - "惊", "起", "瘅", "墈", "氖", "匀", "麃", "阘", "虮", "蘇", "蚤", "汗", "鳞", "籁", "缲", "畈", - "亟", "劬", "課", "蓄", "缅", "楮", "湜", "珩", "斋", "塬", "殁", "魃", "脞", "H", "澼", "钚", - "饕", "缕", "Ⅱ", "攮", "卿", "莅", "镆", "熹", "藩", "汁", "順", "趿", "拆", "蟹", "砒", "惴", - "㎡", "忖", "寝", "戕", "螭", "酿", "™", "柬", "枧", "凶", "蚁", "島", "殄", "鲊", "忠", "肉", - "辕", "叫", "徙", "漆", "缞", "夀", "楦", "佪", "兴", "粉", "裳", "蘧", "國", "旬", "看", "Ⅰ", - "剑", "痭", "襟", "恐", "遹", "◎", "窃", "穰", "澎", "敬", "旱", "燚", "坩", "彤", "尜", "猃", - "夏", "穈", "媒", "柑", "駡", "孛", "脉", "车", "零", "菩", "痊", "卉", "桔", "距", "吧", "漦", - "启", "仁", "滬", "馋", "帅", "鳈", "鄌", "超", "芡", "窘", "刽", "掌", "氤", "梽", "拎", "踏", - "勋", "甍", "玑", "稱", "鞍", "浍", "翅", "饟", "鼎", "罩", "加", "虚", "蕰", "簉", "堇", "巢", - "疲", "蟑", "狝", "瓮", "潋", "行", "饥", "散", "糌", "牵", "貢", "偉", "咄", "痕", "沃", "苓", - "锂", "狻", "褿", "畸", "姿", "煎", "胜", "觅", "烊", "質", "疵", "擢", "椤", "米", "累", "诳", - "斡", "K", "恻", "匦", "烫", "湾", "鹎", "吟", "摘", "涞", "恿", "嫉", "炎", "婧", "朽", "铑", - "ㆍ", "讧", "曜", "挑", "〇", "搅", "鹐", "丁", "彼", "棠", "饪", "箬", "祎", "魄", "囿", "犬", - "市", "髃", "勚", "桶", "辎", "瓞", "财", "缄", "園", "睒", "护", "尿", "融", "围", "水", "糍", - "虢", "呦", "越", "棺", "砮", "邓", "鹦", "稣", "呃", "柙", "鎌", "转", "袋", "湉", "亘", "俩", - "腆", "谣", "飔", "撂", "鄳", "爲", "盦", "谳", "卸", "W", "嚆", "婕", "卫", "拚", "呀", "汽", - "洣", "冻", "鳝", "录", "毋", "閥", "熬", "谜", "齐", "匳", "慧", "猴", "撬", "妳", "諾", "蠼", - "瘟", "伐", "颤", "奶", "陧", "麾", "岌", "浇", "邸", "「", "不", "哼", "热", "旳", "慙", "&", - "苔", "郿", "钗", "氡", "纹", "侬", "霓", "靈", "扁", "聢", "疼", "岣", "甥", "恭", "喷", "芫", - "骂", "肪", "熥", "揠", "鲷", "遁", "霎", "娆", "圩", "爬", "傲", "贽", "紫", "觑", "琇", "蟆", - "怙", "玙", "庼", "筮", "慗", "层", "娓", "蚨", "糟", "璩", "隼", "锧", "疱", "铎", "祠", "绁", - "速", "湛", "蝮", "立", "媵", "禇", "撸", "禳", ">", "恋", "⑥", "鹡", "蓑", "樱", "奸", "蝣", - "埭", "聪", "慭", "睑", "肢", "焗", "骃", "毵", "潼", "塘", "烧", "劓", "栾", "牯", "〉", "毓", - "釉", "庞", "宕", "磚", "夺", "畜", "俏", "筼", "虱", "釆", "计", "陀", "诧", "臱", "牌", "固", - "鹉", "凰", "擞", "■", "㛃", "词", "店", "當", "许", "妣", "耋", "硼", "根", "焅", "砸", "霈", - "锃", "巳", "誉", "咕", "锊", "P", "云", "乞", "为", "姆", "桕", "丞", "鳤", "楷", "醒", "趔", - "怔", "砉", "潏", "肝", "拷", "也", "璐", "厘", "致", "昇", "绥", "抃", "佩", "斥", "⑶", "断", - "纵", "翁", "耄", "沭", "洄", "别", "吻", "渍", "r", "愦", "替", "骓", "攻", "旦", "来", "案", - "坫", "辞", "班", "锝", "拜", "掎", "穸", "笛", "痂", "笈", "鲶", "僻", "依", "碎", "蕤", "炕", - "寥", "拔", "髑", "慨", "眺", "⑿", "珞", "歧", "湲", "錦", "拮", "哭", "爰", "验", "寸", "%", - "口", "阔", "积", "篝", "狴", "殂", "痧", "绽", "搪", "祸", "缘", "遯", "祜", "种", "缓", "冒", - "庵", "窥", "颂", "哕", "谘", "蜗", "掖", "驮", "郎", "跂", "蝓", "贲", "馔", "琰", "大", "芊", - "粝", "啻", "蒉", "谒", "羔", "蘑", "菑", "布", "徂", "l", "炬", "蘩", "弭", "嵎", "補", "岑", - "佯", "棍", "没", "志", "裣", "咸", "权", "豺", "韦", "優", "紧", "嚚", "牴", "酚", "沤", "睥", - "葆", "乓", "划", "犒", "惚", "埕", "锴", "就", "滓", "汕", "冏", "缵", "囟", "旸", "麂", "接", - "餮", "瓤", "偕", "灏", "溻", "揶", "钯", "荸", "宪", "泠", "槠", "抺", "威", "燴", "井", "骣", - "耜", "磔", "懜", "淇", "瘘", "蹼", "觏", "圬", "纔", "恤", "铝", "薏", "鞫", "衉", "E", "球", - "姽", "毹", "嵘", "睦", "蛉", "伽", "橥", "痤", "卞", "警", "则", "芬", "磉", "悢", "逾", "吆", - "朿", "锒", "卧", "E", "焉", "纥", "髦", "鞯", "牞", "蹿", "琪", "洌", "幛", "淳", "菲", "涔", - "噗", "勺", "势", "哓", "毪", "刖", "雜", "浪", "懵", "棁", "秋", "◇", "玡", "埯", "谥", "芑", - "拌", "Z", "埂", "寻", "虼", "豫", "蛄", "蜞", "椟", "〔", "哩", "絷", "咱", "郈", "湫", "抡", - "矮", "庖", "锰", "鎖", "葸", "棣", "砑", "题", "棋", "晕", "兠", "蓣", "貂", "裤", "昊", "扳", - "讴", "弩", "蚀", "尓", "暗", "莘", "黏", "寖", "蛔", "И", "痪", "饳", "妈", "Z", "秏", "矽", - "蘭", "艴", "菖", "寿", "撅", "秤", "颓", "廪", "醪", "耢", "螣", "椰", "麈", "听", "敞", "铠", - "润", "穑", "涟", "澹", "茨", "昨", "嚯", "钟", "護", "榇", "曦", "蜎", "呷", "邦", "瘵", "鲬", - "谖", "概", "九", "飞", "潇", "高", "锫", "钐", "徘", "诟", "缧", "剞", "【", "簋", "噍", "痋", - "关", "糁", "鹊", "潤", "邬", "赔", "序", "盤", "拙", "盾", "鸫", "迟", "氇", "塄", "庀", "噩", - "臃", "绔", "岔", "珠", "癀", "骡", "隶", "堋", "笆", "影", "昶", "飗", "α", "薄", "碜", "瞅", - "奠", "鲽", "牂", "裆", "刀", "遑", "隙", "沔", "訾", "旇", "s", "诮", "炱", "榚", "些", "縯", - "提", "甚", "埏", "峣", "意", "出", "郡", "摊", "哦", "轼", "嚒", "杈", "痢", "裥", "袖", "陔", - "溷", "裀", "迄", "枇", "筑", "貊", "鲃", "鸪", "V", "鞭", "粳", "菥", "盒", "毙", "风", "壽", - "胝", "章", "泄", "浜", "菇", "釘", "揖", "蝰", "榧", "掊", "瘿", "亍", "欤", "髻", "歃", "朱", - "撇", "铁", "兜", "喋", "趵", "瘼", "芤", "邳", "除", "滌", "么", "践", "矜", "曆", "炒", "咔", - "促", "姐", "酦", "货", "箔", "锡", "吝", "医", "汀", "精", "馘", "骶", "碉", "啷", "缉", "褪", - "阙", "滕", "蓐", "搏", "俅", "癌", "股", "圪", "孕", "鳕", "话", "鳳", "妩", "馬", "鞣", "璁", - "测", "螠", "圆", "颥", "卒", "钲", "䨱", "骢", "批", "陨", "婶", "熵", "鸣", "梁", "怅", "滑", - "驵", "帑", "鑽", "痈", "鲑", "犍", "茑", "糧", "谫", "咒", "绘", "塆", "耖", "铮", "殳", "角", - "齮", "挻", "捎", "2", "З", "廋", "泻", "犊", "儋", "椋", "聍", "鼬", "鳏", "收", "跞", "盥", - "信", "嘴", "眉", "黠", "纡", "Ω", "愆", "桹", "昽", "讠", "蚧", "龀", "鳓", "麓", "括", "蘊", - "鈇", "写", "焕", "哒", "忌", "咳", "蜮", "衄", "氰", "邘", "缇", "缮", "表", "续", "篇", "旄", - "闻", "門", "偃", "茳", "晗", "鋪", "讶", "衙", "闭", "管", "傒", "藔", "鳯", "萼", "泥", "汔", - "浆", "姚", "几", "含", "沆", "繇", "灾", "嗦", "饬", "系", "熠", "漶", "潭", "牲", "湘", "稁", - "宄", "亳", "杏", "豳", "監", "印", "旁", "辙", "播", "让", "乳", "镚", "腒", "衅", "铅", "殛", - "形", "颚", "茸", "绚", "铲", "贬", "溆", "寘", "傫", "解", "事", "旻", "差", "竣", "篃", "渥", - "嵩", "@", "鹀", "哈", "痍", "绪", "囔", "渗", "帐", "叙", "⑦", "跖", "貝", "盅", "碶", "哗", - "裼", "窝", "滙", "郸", "延", "炼", "芹", "簃", "谭", "莱", "佞", "猝", "褥", "陆", "王", "碴", - "粑", "怃", "倭", "貉", "硈", "裴", "溍", "坂", "勐", "踬", "敌", "改", "膠", "罘", "罚", "繁", - "幢", "煸", "扩", "黑", "氮", "孓", "饔", "姹", "蠖", "倬", "慝", "沩", "嚏", "雌", "琏", "莹", - "觊", "颟", "坤", "筅", "桉", "肈", "幻", "”", "烽", "蓅", "噌", "桎", "矻", "指", "瀚", "羊", - "邒", "筒", "匣", "旨", "葑", "团", "偻", "镛", "忉", "帱", "往", "刎", "害", "母", "串", "酢", - "舟", "栝", "娣", "⒉", "装", "笊", "篑", "垄", "镳", "牝", "煲", "氵", "遂", "骜", "钜", "屡", - "宇", "z", "惨", "潆", "鹃", "豌", "浞", "幄", "麺", "暽", "弁", "菤", "酲", "虑", "样", "访", - "睁", "黼", "悞", "禧", "涠", "舂", "駕", "屈", "噀", "邽", "炅", "欸", "隆", "描", "绦", "派", - "溲", "颙", "忐", "鹺", "只", "诈", "腭", "亵", "这", "炀", "趣", "喙", "跨", "場", "全", "搢", - "舨", "踢", "巿", "糸", "乐", "澈", "羰", "匯", "D", "濒", "莛", "癯", "娴", "姒", "祥", "渖", - "庭", "渑", "挹", "狉", "萍", "鹚", "焻", "自", "舸", "岫", "飑", "戍", "淙", "愠", "导", "賣", - "进", "赳", "鱿", "硂", "僤", "O", "拟", "钨", "笳", "汴", "挤", "稞", "柏", "阐", "弥", "艽", - "爻", "魭", "俶", "聂", "鲎", "齌", "菀", "僜", "煅", "满", "兀", "辔", "舊", "胥", "卢", "额", - "膝", "嵬", "昼", "唏", "璨", "苷", "舫", "倨", "耵", "碳", "鄺", "橘", "裔", "裸", "宋", "窋", - "悚", "昱", "错", "咣", "檄", "硁", "莆", "肃", "曼", "垍", "绵", "役", "內", "館", "规", "犋", - "毅", "锨", "瓘", "丘", "疝", "杀", "袗", "屏", "阎", "衹", "嚣", "冼", "铪", "熏", "t", "储", - "傧", "髁", "邙", "窴", "泾", "止", "晾", "涵", "庸", "庠", "靿", "睚", "减", "衲", "思", "簖", - "耘", "之", "斑", "扬", "袼", "缗", "菏", "滍", "研", "垚", "艘", "黇", "蜘", "汨", "侦", "疃", - "再", "沂", "榛", "励", "嚼", "拴", "钴", "珑", "撕", "鸯", "共", "醐", "揿", "醴", "凭", "菹", - "鹬", "捷", "掼", "芝", "缪", "咏", "挺", "蒗", "疖", "伸", "索", "黉", "髋", "習", "姜", "蔺", - "扶", "忽", "锉", "戚", "珲", "摸", "黛", "跌", "螈", "冚", "洱", "鼯", "庡", "痒", "哆", "品", - "歆", "登", "呔", "追", "鉫", "碾", "祚", "总", "帚", "薹", "趴", "容", "滘", "❋", "迷", "拾", - "炯", "析", "佼", "嗾", "-", "针", "滩", "禅", "讯", "織", "饱", "哟", "蹓", "侧", "蹯", "踽", - "趙", "漫", "卷", "朴", "卺", "狈", "绉", "浉", "玳", "榕", "畛", "蛾", "帔", "欠", "劙", "矾", - "進", "蚺", "骨", "捂", "疾", "璱", "圠", "坚", "弯", "秩", "逧", "烟", "佛", "嫱", "鳢", "裹", - "耥", "潮", "巽", "嶝", "廷", "鳆", "五", "西", "壤", "慌", "鴈", "爡", "‧", "儆", "萘", "愁", - "昔", "咩", "侃", "炫", "迳", "构", "缶", "皴", "捱", "菜", "秀", "粢", "畵", "辊", "伟", "榄", - "嗪", "已", "聖", "枕", "恢", "厍", "涅", "鄢", "饨", "鲨", "谪", "礤", "搁", "疔", "雎", "羿", - "犁", "硐", "盹", "若", "操", "昀", "亩", "凑", "睃", "贰", "穷", "荆", "葹", "嘃", "廓", "憔", - "制", "胧", "染", "麿", "镴", "砀", "组", "茎", "畫", "哑", "坨", "罱", "刳", "嘲", "瞰", "缏", - "侩", "谝", "谮", "还", "惋", "佈", "谏", "酗", "怩", "i", "秽", "抻", "蟪", "狠", "辑", "羟", - "娉", "肯", "毕", "枸", "啮", "鳙", "要", "娑", "蜈", "忍", "侗", "Р", "凛", "巉", "拽", "该", - "俎", "惠", "薅", "猬", "忲", "●", "哏", "柔", "沉", "磁", "脾", "龃", "鲩", "钞", "厂", "鱽", - "濞", "群", "唱", "攝", "刃", "蹻", "剕", "朊", "啜", "语", "蜻", "遠", "呖", "都", "嫄", "戢", - "丫", "酞", "修", "户", "膏", "侈", "浣", "捍", "馒", "谱", "點", "滏", "跟", "鹁", "书", "愉", - "扭", "票", "耒", "燁", "魚", "拨", "鞑", "匆", "最", "憨", "晨", "癍", "邻", "醅", "骘", "骇", - "蔫", "。", "珪", "安", "歉", "邑", "淦", "胱", "漏", "咂", "叮", "瘛", "钺", "聘", "玎", "荻", - "涰", "淏", "烈", "囚", "㙟", "矫", "嗵", "澶", "磛", "肖", "蹑", "支", "哪", "久", "嗅", "稍", - "抠", "具", "裨", "韨", "虿", "漪", "外", "埸", "ä", "葡", "鲇", "廛", "蝥", "广", "兒", "涧", - "阌", "谊", "嵴", "拂", "悸", "哳", "4", "佘", "篁", "基", "赪", "掬", "演", "谋", "酣", "植", - "波", "恅", "杼", "胀", "纯", "缩", "盆", "芷", "绺", "施", "礞", "莳", "稻", "狐", "馌", "椑", - "恃", "镩", "骼", "孱", "硭", "曈", "焼", "秕", "觥", "茛", "射", "肣", "蟞", "′", "彰", "罔", - "麻", "逋", "谓", "革", "藤", "堆", "忿", "茂", "屦", "炟", "碹", "啤", "垤", "文", "佐", "叼", - "蹭", "踉", "眍", "龟", "黾", "崋", "氘", "尼", "瞢", "悦", "罢", "瑀", "睇", "贴", "涿", "拍", - "庥", "粪", "陳", "闌", "蓍", "元", "磊", "忻", "葴", "买", "诺", "㐂", "沦", "苏", "岂", "浊", - "脍", "誠", "嚬", "蔬", "黄", "銘", "钩", "劃", "嫘", "嵖", "笄", "鸰", "熳", "堑", "河", "遮", - "尝", "灭", "愬", "娅", "鸽", "锢", "狂", "弓", "侨", "滚", "释", "晏", "徵", "苡", "佚", "切", - "惰", "降", "槎", "脑", "磺", "谟", "裉", "弘", "醺", "眇", "顒", "兰", "忧", "础", "-", "茫", - "袒", "喤", "慶", "話", "跽", "堵", "能", "武", "壳", "汤", "橐", "圧", "嗡", "簌", "斧", "林", - "楊", "净", "嫌", "猛", "炸", "冠", "弦", "洵", "°", "創", "葜", "苁", "顏", "薛", "平", "舜", - "崧", "撼", "哮", "窣", "殖", "象", "飒", "瞥", "玥", "斝", "胭", "葱", "擎", "踰", "盛", "稇", - "斫", "滴", "硫", "胬", "唁", "拐", "殍", "冱", "陪", "鋈", "烦", "辋", "妇", "轸", "潴", "荤", - "碡", "徭", "膜", "秧", "淀", "缤", "琶", "^", "肋", "违", "轭", "$", "箕", "墩", "罗", "摆", - "槛", "笠", "塃", "畚", "嘛", "秸", "≥", "剪", "羅", "帜", "庇", "骙", "酾", "康", "陬", "蝶", - "闇", "圏", "琴", "鬈", "苶", "黡", "瓠", "酋", "琎", "奏", "科", "搒", "億", "翡", "熊", "性", - "痞", "篾", "邴", "篥", "饵", "揸", "狙", "鳂", "否", "煺", "畦", "凖", "鹧", "宵", "庛", "鬯", - "袂", "昴", "徽", "奧", "鸥", "锸", "庚", "彪", "槿", "趱", "铡", "讹", "莎", "約", "璞", "┌", - "铫", "鸈", "瞀", "鼙", "廙", "估", "屺", "锘", "渝", "汶", "囵", "跻", "酏", "扎", "孜", "腔", - "吗", "块", "潽", "“", "焚", "倘", "靥", "默", "笺", "遍", "剅", "桠", "极", "夷", "眸", "泳", - "谢", "懦", ")", "泜", "物", "开", "淮", "邵", "卟", "徜", "轧", "苍", "酶", "捌", "耨", "膄", - "琦", "痦", "涪", "舰", "迥", "涘", "季", "悫", "初", "贩", "碍", "沼", "腮", "勻", "恣", "他", - "院", "7", "蜒", "叉", "昉", "瞽", "疢", "蓼", "相", "臜", "ü", "秘", "蚌", "摉", "莞", "番", - "盼", "冀", "缠", "学", "馗", "搞", "苛", "羹", "潟", "嬴", "杶", "妖", "↓", "銭", "斄", "猢", - "搂", "芦", "埶", "癜", "铴", "從", "留", "硎", "簇", "臬", "侮", "鳎", "頉", "所", "邝", "哂", - "弛", "垂", "暑", "仿", "療", "轾", "熜", "悃", "勘", "鋫", "泞", "閃", "+", "士", "虐", "盡", - "溯", "劣", "1", "锇", "蜇", "碛", "婴", "8", "捶", "藻", "嫰", "跹", "芋", "淠", "疯", "Й", - "诨", "醢", "痨", "栌", "摧", "噤", "灸", "馉", "蒇", "洲", "孪", "孵", "亿", "枝", "涕", "孟", - "缎", "攒", "湧", "褛", "铺", "廣", "诃", "蕈", "维", "珣", "逖", "瓯", "苘", "榫", "寰", "供", - "铽", "暲", "义", "兖", "喆", "祇", "蝽", "膛", "髭", "尹", "乒", "柈", "抓", "镋", "脏", "乩", - "挎", "酬", "靳", "躔", "霞", "離", "桌", "o", " ", "滨", "懷", "萭", "望", "仆", "怂", "麸", - "槁", "洨", "俬", "孚", "匕", "栩", "t", "被", "邗", "纺", "狄", "国", "苋", "眢", "秣", "畤", - "∵", "创", "嵫", "胖", "垮", "镁", "壑", "A", "趾", "荟", "汝", "嗥", "驰", "向", "磴", "讪", - "溅", "箍", "驾", "讙", "蛐", "眨", "醯", "筣", "鼫", "叠", "沥", "恕", "埽", "甩", "煜", "端", - "蜃", "帏", "丙", "荏", "圻", "夥", "暖", "抛", "岸", "头", "恝", "船", "鞲", "の", "七", "怪", - "诅", "茧", "北", "搓", "皖", "綉", "坪", "簪", "贵", "阍", "刑", "偶", "雷", "體", "髡", "岚", - "剂", "妾", "茬", "鹣", "鲳", "蜊", "假", "认", "嗍", "傈", "焘", "驷", "賀", "氆", "炝", "聋", - "嘡", "悺", "﹐", "僭", "证", "侉", "屐", "吃", "十", "〕", "瀦", "骤", "俳", "舁", "驸", "竿", - "坍", "|", "普", "軒", "瘃", "现", "醾", "铈", "榭", "蓁", "唷", "睫", "绰", "叶", "頤", "锤", - "浸", "杂", "汹", "璟", "蓖", "迦", "截", "錎", "年", "達", "劁", "码", "乃", "捯", "髪", "埚", - "呯", "頭", "镈", "汆", "β", "舷", "菂", "纸", "造", "晁", "卦", "蛎", "枉", "脯", "诛", "生", - "令", "桄", "恶", "鬟", "怯", "囡", "充", "省", "控", "螂", "笕", "邺", "扅", "斲", "骏", "鹋", - "队", "套", "镢", "牖", "I", "援", "封", "泚", "艿", "沮", "铙", "揳", "抄", "帨", "近", "唾", - "珥", "销", "非", "啱", "驼", "瓅", "遢", "筱", "奥", "善", "氩", "盉", "帖", "杜", "鈉", "蕉", - "鳄", "江", "鄂", "矩", "排", "诠", "准", "菼", "刻", "足", "峦", "灰", "僳", "蝢", "孫", "據", - "璆", "孳", "徹", "妆", "坭", "渌", "喏", "钦", "朔", "机", "徼", "掾", "其", "愧", "刹", "迹", - "惹", "闿", "鹘", "窗", "贳", "箓", "奡", "鸮", "翟", "滠", "辄", "夸", "袱", "】", "阿", "摁", - "觽", "垠", "棼", "杉", "甏", "旖", "阜", "猩", "埤", "醛", "馥", "哫", "囝", "晖", "骸", "椭", - "军", "哺", "束", "犄", "遛", "涡", "罄", "赇", "幌", "曙", "契", "饹", "圳", "仝", "爝", "示", - "敝", "漓", "马", "铐", "掳", "鲱", "蟀", "阵", "栒", "b", "轮", "俯", "嬉", "漩", "佟", "捆", - "迩", "液", "炊", "抒", "迭", "换", "菘", "请", "柩", "腓", "妥", "怖", "穆", "骝", "胛", "幺", - "燥", "棹", "孖", "洁", "边", "彥", "睨", "桁", "淆", "醤", "奘", "伙", "刘", "o", "過", "鏖", - "怄", "镗", "蘖", "卩", "龈", "枣", "联", "圊", "贫", "郭", "梗", "赡", "輸", "拼", "冰", "Ë", - "姓", "办", "拉", "富", "对", "肩", "缬", "逻", "瞠", "な", "荚", "宝", "緃", "峋", "鞁", "坉", - "译", "银", "猹", "榞", "借", "楠", "殽", "片", "谸", "雩", "琨", "颏", "晷", ";", "莠", "楽", - "嬗", "啉", "爍", "視", "岽", "荙", "冗", "『", "鯭", "觌", "喹", "药", "腈", "蹰", "–", "泷", - "榷", "卮", "缥", "各", "瘙", "凡", "悍", "劢", "6", "镰", "四", "摈", "驹", "陵", "沟", "麟", - "骊", "椀", "★", "滦", "菌", "彊", "疽", "辫", "璎", "郁", "资", "粼", "萄", "鳁", "鸤", "漁", - "痃", "绌", "蒴", "尊", "哙", "守", "坠", "胯", "泽", "持", "隅", "耧", "逛", "鄯", "瑜", "召", - "眷", "逄", "垦", "窄", "板", "赵", "源", "绹", "總", "适", "轰", "钛", "停", "唝", "燎", "栽", - "燃", "搬", "夬", "掐", "簦", "旃", "更", "蹊", "熙", "埃", "偲", "蒙", "舍", "杭", "朋", "霍", - "谙", "蓥", "赫", "鲏", "純", "缃", "蓓", "è", "萧", "锆", "诉", "恚", "u", "旷", "⑵", "褲", - "鲟", "互", "峂", "绝", "陒", "议", "脽", "态", "岙", "僮", "突", "濯", "犹", "阆", "溧", "宜", - "霣", "呆", "鄉", "觖", "濠", "耐", "橱", "敛", "踮", "怦", "鸠", "授", "滫", "叭", "镤", "仵", - "圖", "救", "变", "寕", "洋", "泃", "晥", "檎", "缦", "鏠", "悬", "彧", "韓", "籽", "磷", "歙", - "÷", "杨", "闯", "罴", "鼠", "陋", "瀣", "揾", "匪", "晚", "丧", "彷", "梏", "诽", "尻", "蹢", - "拊", "氕", "芳", "凸", "懊", "型", "媄", "憝", "骆", "纭", "刺", "悼", "藍", "欧", "葳", "艺", - "±", "紗", "钡", "钭", "首", "栈", "闩", "勃", "喑", "栉", "栟", "焊", "哀", "竖", "肘", "悲", - "鳜", "迨", "怿", "裘", "綮", "蕹", "冕", "无", "鼢", "戽", "鲣", "蜍", "插", "扯", "俣", "袪", - "级", "理", "茵", "矣", "障", "禊", "惯", "䄂", "宏", "韫", "栗", "编", "座", "跫", "、", "捞", - "谠", "車", "袆", "舖", "暝", "9", "混", "蓊", "韂", "拳", "j", "伶", "啦", "0", "诰", "缑", - "郴", "蕲", "谛", "皋", "兢", "件", "隈", "溊", "窈", "檀", "洪", "揭", "油", "颐", "剎", "侠", - "或", "腻", "迪", "舔", "牺", "倦", "夭", "蠋", "鹑", "倜", "喱", "豨", "谨", "翥", "馄", "蔚", - "类", "鳍", "泯", "岷", "張", "紅", "情", "婪", "睡", "诒", "旋", "舱", "列", "求", "姥", "翯", - "锲", "適", "蒡", "㭗", "韵", "撄", "律", "湊", "鲪", "碓", "馓", "汛", "尤", "℃", "泫", "竹", - "溃", "诵", "乡", "楹", "肷", "戋", "獭", "撴", "晤", "嘎", "裢", "轱", "歘", "鼱", "舀", "潵", - "腩", "挽", "至", "骞", "佻", "蕊", "轫", "岘", "斌", "《", "雇", "枘", "贶", "履", "亭", "绍", - "空", "泡", "擒", "蠓", "桼", "舢", "踵", "柢", "躺", "罥", "蔁", "幪", "蒯", "≤", "齉", "況", - "锕", "徇", "儿", "帽", "谕", "抽", "獍", "揪", "膳", "酴", "姊", "作", "弍", "郦", "翮", "髌", - "勝", "孔", "颁", "泩", "衾", "翊", "噉", "∩", "先", "的", "財", "绢", "崇", "饲", "賓", "绾", - "陡", "砾", "纷", "酱", "窎", "浕", "琫", "补", "嗽", "呛", "蚓", "伪", "艨", "搡", "粗", "阱", - "商", "郫", "喵", "缯", "炻", "州", "珽", "芒", "脶", "蕖", "拘", "\\", "蕃", "伏", "蛏", "璘", - "缡", "伞", "吸", "煞", "嗫", "餪", "━", "8", "漠", "衮", "峭", "筌", "阀", "乇", "杞", "镕", - "鹈", "觚", "疋", "猥", "肚", "阃", "地", "鸾", "玚", "镀", "诬", "凇", "惬", "劝", "堠", "睪", - "瞪", "涓", "專", "琢", "蠹", "裂", "芎", "轲", "谯", "畋", "长", "攘", "缁", "吵", "汈", "稂", - "咤", "甸", "瀑", "讣", "翠", "綦", "笑", "掺", "宫", "唆", "旗", "帘", "遵", "唪", "连", "必", - "姬", "枵", "渫", "神", "凱", "虞", "闵", "爭", "迢", "飓", "桴", "冑", "招", "鬶", "赊", "朦", - "薜", "逗", "铩", "焖", "狱", "昕", "犀", "捏", "侓", "爆", "箧", "怠", "缐", "苄", "踯", "暹", - "絮", "裁", "嘶", "诙", "攥", "¥", "痫", "摹", "朕", "薰", "闼", "樨", "需", "蕾", "扔", "服", - "蚩", "漳", "瞻", "陟", "诐", "爽", "耩", "坏", "寶", "瞧", "蘅", "爺", "仇", "瞈", "揉", "隰", - "阏", "皤", "鉏", "郇", "啵", "僧", "渐", "骠", "厾", "谦", "榱", "蓮", "乂", "伷", "觐", "遫", - "畀", "污", "眭", "蝗", "亢", "腾", "遇", "欺", "狸", "籼", "锯", "赚", "槔", "域", "老", "掩", - "锎", "邪", "沬", "袯", "映", "肤", "舒", "箦", "涎", "缔", "孃", "萎", "推", "峧", "嫒", "嵐", - "怒", "闾", "阅", "扢", "絡", "剩", "腢", "晌", "铟", "铚", "燔", "鄜", "墠", "擤", "芸", "鼩", - "食", "朰", "啥", "贿", "券", "垩", "典", "逭", "成", "帧", "侯", "妒", "顷", "晩", "浦", "汳", - "㾄", "坊", "②", "蝼", "倩", "挦", "騠", "蓂", "兹", "渤", "茴", "矶", "煤", "伛", "逃", "堞", - "漭", "闽", "埠", "妗", "烙", "傀", "滢", "堂", "骅", "崮", "兿", "螟", "榴", "蒈", "蟛", "员", - "嗟", "毗", "鹭", "毖", "籍", "傣", "偈", "澴", "耆", "黔", "薷", "俘", "箸", "蒺", "记", "铣", - "拥", "瑰", "抉", "史", "急", "什", "川", "曪", "剖", "罪", "扥", "鱼", "羌", "复", "昵", "朓", - "氪", "矅", "ò", "摒", "催", "{", "懂", "莉", "屃", "症", "遒", "璋", "鄒", "玄", "氦", "舳", - "納", "锷", "鲥", "羸", "怵", "嬖", "飚", "倔", "辨", "篌", "娄", "洎", "弟", "悝", "婥", "待", - "梃", "棕", "撞", "肊", "婺", "桥", "慕", "5", "尖", "监", "囊", "腎", "瘁", "⑴", "伢", "邈", - "炷", "籴", "月", "终", "龠", "蹇", "柯", "噜", "多", "玮", "踹", "泣", "圮", "辈", "鄙", "赆", - "蠃", "珈", "鬃", "识", "甑", "藓", "宥", "韧", "隗", "跚", "峁", "晒", "戳", "環", "葓", "筐", - "瑚", "稆", "巩", "葵", "网", "铨", "仡", "呶", "休", "村", "傩", "浡", "祝", "幅", "晳", "岿", - "[", "尃", "响", "咽", "讵", "淹", "糠", "驴", "烹", "甪", "焯", "整", "瘆", "茀", "瑞", "嘁", - "赅", "芼", "震", "怼", "膑", "蒟", "钊", "缷", "獨", "俄", "噪", "亏", "芍", "鲲", "黟", "酃", - "铻", "→", "鲡", "仑", "有", "扌", "治", "聆", "腙", "冬", "剥", "诓", "祃", "棘", "孥", "濆", - "鞋", "赣", "卜", "谆", "投", "琊", "塍", "洗", "津", "肴", "奕", "掴", "螗", "胸", "惦", "赠", - "耶", "蛸", "曷", "名", "栏", "崖", "始", "孤", "篆", "椴", "模", "儙", "袁", "颌", "卤", "寂", - "呸", "蓺", "噶", "钔", "粹", "潸", "郾", "娡", "啖", "芜", "䧳", "缟", "鞅", "哇", "嚄", "熛", - "私", "住", "鉄", "U", "失", "蜾", "㺃", "莨", "擂", "沕", "铄", "耰", "炔", "藐", "锈", "苇", - "芯", "檇", "龍", "珀", "筻", "褚", "缀", "棬", "仲", "杧", "铛", "挖", "缸", "嵇", "剟", "觋", - "鬼", "天", "鹪", "豭", "腴", "驿", "粵", "馈", "迸", "夕", "蜚", "禺", "迎", "狞", "嶽", "躯", - "暅", "蹾", "甾", "柆", "e", "欃", "無", "羽", "蛛", "僖", "碲", "遴", "厝", "滂", "眦", "鹅", - "咖", "潜", "媽", "啴", "寨", "琬", "判", "塌", "与", "剧", "掮", "读", "庆", "愚", "氲", "梾", - "稗", "很", "饯", "淘", "灞", "A", "!", "飾", "醚", "壁", "芮", "蔼", "知", "郯", "瞒", "术", - "法", "匠", "┅", "尕", "脂", "琅", "孝", "埙", "濟", "袷", "方", "芾", "驽", "线", "咡", "睿", - "滥", "鞨", "駹", "馎", "蛲", "申", "涣", "牗", "跄", "鲐", "泐", "铍", "肓", "é", "司", "辣", - "慑", "崞", "魏", "髯", "涯", "滃", "薪", "~", "鐵", "町", "芥", "匿", "癞", "嘚", "□", "啪", - "俇", "橛", "巅", "鄞", "痱", "回", "着", "魂", "瘀", "埒", "措", "蚪", "锁", "巴", "芏", "另", - "忏", "洇", "⑾", "箱", "劳", "榈", "B", "毒", "泰", "巍", "寇", "斛", "赖", "酒", "密", "左", - "莜", "茯", "脆", "饴", "洳", "舉", "酪", "鼒", "職", "桫", "螋", "砌", "戬", "前", "豁", "膲", - "鲯", "憋", "珺", "蹂", "亥", "冷", "蜔", "俦", "碇", "慰", "扒", "亮", "弒", "胫", "肠", "弇", - "拣", "丸", "涫", "勉", "帝", "玠", "应", "砜", "鬓", "泮", "鳖", "峇", "辗", "吴", "僡", "玊", - "钘", "惘", "奁", "翰", "爨", "罽", "莶", "纻", "菪", "興", "钧", "鄹", "缌", "嘉", "玲", "蛋", - "倚", "镬", "彳", "氯", "谐", "疗", "魉", "扈", "鏡", "涤", "佑", "勾", "饽", "R", "局", "醉", - "燫", "驱", "崽", "榮", "锄", "脎", "枓", "敲", "俑", "镶", "当", "逦", "寅", "捽", "宗", "茼", - "稿", "躇", "晋", "东", "渭", "闶", "潦", "慊", "蔟", "疑", "蜡", "嬛", "荒", "扪", "拈", "受", - "沱", "螽", "嗣", "瘰", "颖", "百", "楱", "崛", "窿", "蓬", "禨", "螵", "捕", "鳀", "霰", "瘸", - "圄", "陂", "敢", "矗", "炉", "篪", "注", "凉", "摔", "衿", "g", "遘", "鳟", "腚", "泱", "荣", - "池", "杰", "阻", "里", "峥", "葺", "翔", "柁", "飐", "载", "刨", "瘊", "溏", "嚭", "穝", "站", - "笞", "厌", "门", "汞", "雠", "靖", "怨", "葙", "厅", "凉", "荨", "底", "坼", "海", "轩", "秃", - "醭", "莒", "坎", "驺", "瀛", "嵝", "溥", "嚋", "寤", "k", "築", "耔", "跎", "小", "弊", "疭", - "√", "洞", "利", "次", "迕", "鸿", "刁", "媳", "酹", "磋", "勒", "伎", "浔", "斤", "珊", "鸳", - "颊", "塗", "刈", "龛", "縻", "楚", "脓", "南", "伧", "桨", "尸", "退", "亊", "侔", "蓟", "削", - "诲", "瑯", "挝", "绩", "嶂", "耷", "太", "著", "讥", "烂", "哥", "菔", "唳", "筫", "嚷", "斯", - "蔡", "碧", "慵", "搐", "琵", "逶", "菡", "篙", "驭", "莲", "毫", "犯", "坌", "啕", "疴", "傻", - "牧", "肺", "既", "悟", "讳", "练", "钠", "胨", "G", "迁", "帙", "嫦", "哿", "柝", "迤", "庑", - "踟", "粤", "乜", "悭", "霁", "在", "虔", "蓦", "暾", "鲅", "様", "徐", "诫", "料", "蒂", "揎", - "溜", "崎", "玦", "隐", "绳", "幼", "钼", "腧", "槌", "镅", "锿", "蹁", "猱", "狁", "蹈", "S", - "傢", "}", "珉", "浴", "龚", "吇", "肆", "⑩", "臌", "鏢", "―", "定", "哧", "螳", "爹", "摞", - "榍", "苩", "丑", "犴", "璀", "偎", "燹", "洯", "啁", "鱾", "計", "镂", "字", "琉", "壴", "霖", - "蟜", "做", "松", "扣", "徊", "叱", "桑", "≠", "寓", "崔", "茌", "`", "殓", "猖", "慎", "坻", - "皮", "喔", "耕", "拧", "织", "桂", "垝", "约", "飯", "皿", "移", "微", "桅", "钬", "赑", "宓", - "颉", "掂", "希", "沁", "翳", "澝", "崭", "聃", "蔸", "磕", "崚", "奉", "槍", "颠", "任", "飕", - "蛴", "歼", "蛭", "¥", "鉵", "刷", "泓", "頫", "诤", "阈", "诖", "漂", "冯", "柠", "本", "狼", - "芗", "丹", "柒", "饫", "衫", "摩", "桃", "啼", "譄", "醌", "帡", "少", "螃", "祷", "幸", "喘", - "噼", "甲", "刭", "泊", "那", "舄", "畲", "遊", "記", "绠", "蝈", "忒", "耙", "鹌", "搽", "绕", - "镠", "凼", "扫", "鸵", "匡", "缈", "铼", "挢", "踊", "噭", "苴", "貌", "啾", "蒜", "茱", "⒅", - "邛", "棉", "怀", "筵", "笾", "邢", "濱", "蒲", "嫠", "儡", "益", "萊", "歩", "日", "婢", "楔", - "嚎", "髂", "禄", "巫", "懿", "砍", "惆", "袭", "~", "欲", "鳅", "書", "撷", "库", "绻", "⒁", - "蒹", "辜", "屉", "奂", "龇", "诡", "醑", "儀", "讷", "聒", "盖", "浅", "長", "蛑", "念", "辒", - "蚊", "勖", "揣", "岬", "糅", "刊", "蛆", "硌", "柜", "惗", "激", "颈", "閣", "唬", "捧", "蒽", - "爸", "侏", "氧", "蛤", "牡", "瘦", "铉", "撒", "屿", "谔", "钀", "瓦", "恂", "钻", "声", "馨", - "贷", "藁", "闰", "人", "瀹", "间", "炜", "煨", "畴", "鞡", "悔", "量", "原", "屁", "杯", "趋", - "愎", "瓶", "烘", "韬", "姮", "勰", "眛", "饮", "瘐", "决", "版", "際", "俸", "此", "辽", "愫", - "爷", "隘", "螯", "腕", "闟", "厣", "齁", "矿", "女", "扇", "郄", "诚", "焜", "<", "檵", "赙", - "郢", "酌", "恳", "侵", "劍", "徳", "脔", "岍", "倍", "隹", "镲", "僬", "○", "啭", "坳", "谰", - "璪", "昆", "⒆", "惧", "虺", "篡", "锐", "邮", "嵊", "恹", "茄", "黯", "對", "魑", "禀", "添", - "汎", "廉", "戈", "∈", "陈", "肟", "螅", "缰", "啃", "瘾", "辁", "茜", "曝", "C", "餍", "蜴", - "咦", "臺", "扺", "隽", "崴", "遐", "胃", "铕", "楗", "墀", "魈", "淑", "邰", "飧", "勤", "糨", - "你", "铂", "蛰", "锻", "塈", "予", "怏", "鷪", "暂", "诞", "會", "鼐", "辏", "矬", "筜", "蟒", - "柫", "靴", "垒", "樵", "狨", "魋", "查", "掸", "'", "每", "浮", "绞", "疍", "於", "饦", "辐", - "墟", "窳", "养", "墦", "鲔", "黝", "迈", "砟", "伥", "藜", "墅", "喬", "卬", "赶", "眼", "龌", - "主", "嗞", "転", "襕", ",", "杲", "儒", "政", "蹩", "付", "Я", "厢", "点", "如", "茗", "奍", - "嗌", "蕴", "问", "膚", "硒", "佃", "居", "赍", "鯨", "槜", "衡", "廐", "鲾", "慈", "莫", "篮", - "铱", "园", "范", "靠", "叻", "绸", "众", "抑", "浃", "極", "辀", "千", "蔯", "r", "碱", "應", - "夼", "祺", "绣", "澉", "愛", "譬", "刚", "扼", "檫", "时", "荼", "部", "耽", "稀", "琳", "鎮", - "鳃", "疌", "挠", "京", "筴", "胳", "橡", "裱", "栊", "蛩", "流", "猄", "葭", "邯", "伤", "秦", - "孺", "郓", "筏", "茉", "谈", "黥", "鳇", "魅", "秫", "敫", "肄", "俪", "尺", "度", "廊", "昏", - "怎", "钎", "愤", "腿", "Λ", "碘", "囤", "婆", "煋", "桀", "阪", "焒", "砘", "澡", "阒", "臼", - "茭", "纛", "唻", "胗", "歌", "吱", "铸", "種", "礳", "舾", "砰", "即", "慥", "缆", "躞", "卖", - "眆", "搎", "鲁", "稠", "惝", "毶", "耎", "挡", "异", "咨", "歔", "垫", "素", "鳊", "打", "镏", - "耗", "锭", "剀", "讓", "鍋", "歇", "拗", "齿", "聊", "惕", "塔", "况", "汐", "采", "灣", "菁", - "峰", "呋", "阴", "衽", "鹏", "挂", "鲞", "第", "浑", "秭", "铯", "胎", "滔", "雕", "渔", "骍", - "鴻", "眚", "易", "枫", "麥", "罹", "劈", "苣", "蹄", "是", "锛", "饼", "铳", "器", "秒", "開", - "舛", "纳", "庒", "饰", "发", "虎", "乏", "届", "浯", "目", "霪", "氢", "华", "澧", "陴", "誊", - "欷", "瀌", "梵", "嗖", "惩", "妞", "螓", "溇", "嬃", "笼", "嬢", "獠", "辩", "骛", "挪", "礅", - "銎", "趺", "狍", "阑", "擦", "咙", "+", "鼻", "戆", "宿", "霏", "牁", "耦", "枳", "鲸", "阽", - "峯", "瘭", "祁", "镜", "绮", "道", "摭", "﹒", "耠", "限", "轻", "莽", "帛", "唯", "墒", "W", - "荦", "矸", "崃", "洫", "杳", "舌", "涌", "朵", "苑", "瓻", "辂", "凬", "畺", "莩", "奔", "荐", - "撵", "嶲", "憧", "沖", "邱", "瞑", "瘢", "腺", "嵯", "诗", "經", "胚", "谎", "央", "稼", "3", - "冈", "痣", "故", "皎", "珅", "踅", "硇", "通", "鹱", "草", "粕", "而", "梨", "萜", "搛", "鸺", - "托", "倡", "匾", "骷", "桐", "阇", "璃", "抖", "显", "镝", "I", "锣", "辆", "茝", "虫", "谀", - "萤", "帼", "滈", "鮼", "乔", "会", "产", "縢", "纱", "跆", "铤", "圯", "旚", "墓", "棰", "苜", - "聩", "蚍", "筢", "殇", "槚", "阂", "豊", "翚", "犰", "疚", "浠", "礴", "界", "蛙", "吁", "忪", - "讫", "辇", "汧", "澥", "纮", "糺", "拭", "镉", "鄠", "讼", "鎏", "逐", "烝", "扊", "筹", "仪", - "段", "杵", "卲", "钤", "曹", "潘", "浏", "陑", "答", "期", "橋", "位", "梅", "榻", "芨", "汭", - "贇", "杅", "伋", "馁", "皈", "躁", "鲦", "良", "幤", "曺", "榖", "便", "氍", "窍", "槃", "設", - "襦", "菓", "猡", "槲", "觱", "邠", "岩", "骈", "鬲", "睽", "残", "碗", "凯", "览", "伾", "吣", - "峡", "箨", "忡", "岁", "醵", "霸", "焐", "谁", "疟", "樾", "竺", "果", "阝", "花", "•", "耱", - "嗜", "骰", "萋", "甄", "侍", "厦", "辌", "给", "健", "垧", "娩", "校", "又", "临", "揽", "犟", - "蠢", "包", "檬", "穹", "燮", "札", "翏", "领", "深", "诶", "窒", "鸷", "统", "肾", "澍", "畹", - "职", "蝟", "眬", "旎", "朘", "眠", "篚", "贼", "貴", "#", "茆", "磬", "①", "祀", "坞", "盯", - "苹", "痼", "耪", "狺", "妓", "湨", "動", "渚", "售", "鸶", "霄", "某", "×", "铀", "桓", "脲", - "心", "节", "[", "蜩", "剐", "猜", "盂", "穿", "洮", "坜", "掷", "坐", "烜", "冶", "袍", "穴", - "偷", "槽", "面", "媛", "撙", "孩", "询", "苈", "橙", "恙", "吉", "燈", "暇", "杋", "後", "璇", - "喟", "妪", "湄", "贡", "兮", "楫", "锗", "肮", "圉", "参", "烃", "葩", "骀", "锖", "犿", "恼", - "麯", "牮", "溱", "俵", "祢", "割", "羲", "中", "博", "膦", "7", "钙", "耸", "蚋", "嘬", "逝", - "瓿", "且", "苗", "屑", "華", "糯", "吓", "陇", ".", "魆", "d", "拶", "箜", "澳", "蘼", "垸", - "钅", "樯", "侑", "娼", "赛", "恪", "击", "濮", "隔", "似", "惜", "滤", "培", "谩", "坝", "煙", - "馕", "茡", "颼", "啡", "强", "巡", "糗", "芙", "骒", "常", "鳔", "楣", "嫩", "师", "攀", "旭", - "茠", "吏", "剌", "露", "把", "携", "忘", "软", "荩", "弧", "锩", "僦", "掘", "仓", "嵚", "沲", - "傅", "蝴", "爵", "纪", "薮", "參", "荀", "珙", "逞", "蹙", "徉", "佶", "庹", "弢", "锞", "想", - "窕", "躬", "蚡", "闸", "难", "妃", "唶", "V", "蚂", "酐", "]", "羁", "土", "敏", "蝻", "赎", - "闹", "铷", "脬", "攫", "椐", "橹", "(", "暨", "剁", "灵", "咫", "苻", "赈", "萝", "鹮", "颛", - "勿", "臆", "福", "蝠", "烺", "跤", "垓", "庋", "鏊", "彭", "碚", "膂", "鐘", "鸹", "择", "疫", - "暌", "胙", "翘", "仞", "實", "猫", "嘹", "坟", "泺", "靽", "仟", "鲋", "畅", "箪", "箩", "星", - "辍", "餐", "伍", "狃", "蹐", "芴", "龋", "仨", "狩", "诌", "媚", "琚", "❤", "鉰", "仔", "忝", - "垅", "嗤", "氅", "填", "詹", "诿", "皑", "椅", "鲭", "繪", "碑", "选", "廠", "嶓", "迮", "唠", - "赏", "│", "泍", "姑", "晦", "直", "艾", "邂", "裝", "郊", "疡", "」", "鸲", "兕", "县", "邡", - "麤", "旧", "壶", "礼", "梭", "铔", "玕", "硬", "后", "馅", "窠", "俊", "犾", "槭", "姨", "妨", - "幡", "沿", "帮", "爿", "褊", "淅", "册", "诔", "使", "唢", "族", "逮", "蟋", "掣", "红", "颔", - "闲", "咧", "衍", "矛", "蹜", "抱", "雀", "箴", "雙", "茁", "聲", "芰", "瘤", "落", "峨", "秆", - "献", "霭", "胰", "墁", "柽", "跛", "阼", "菝", "谗", "蠊", "懋", "蔷", "拃", "岱", "戡", "逡", - "背", "克", "棱", "栲", "乖", "橄", "炭", "萱", "胲", "摺", "殆", "魍", "宾", "拢", "姁", "祲", - "·", "歹", "胆", "爱", "旰", "抢", "匜", "硚", "愈", "跳", "▲", "跪", "網", "糈", "維", "痹", - "娃", "疸", "痔", "褙", "芭", "鹜", "猷", "檩", "吨", "淖", "竟", "呱", "瘠", "奢", "呐", "扞", - "灼", "家", "饿", "玻", "倾", "锚", "遗", "赝", "去", "跣", "纬", "玢", "梆", "陉", "屎", "上", - "酆", "搤", "併", "腌", "避", "禹", "绅", "帆", "英", "区", "交", "▪", "巧", "豹", "游", "清", - "荧", "娀", "訓", "尾", "觫", "梢", "均", "忤", "继", "變", "喽", "尉", "骚", "趸", "馃", "石", - "置", "毡", "竴", "龄", "掭", "骟", "堡", "确", "街", "沌", "恨", "壮", "弄", "鞴", "剿", "貅", - "路", "杠", "豚", "澜", "靼", "擐", "租", "媪", "彖", "逢", "撺", "盗", "呑", "锥", "栎", "唧", - "翩", "倥", "虽", "郏", "钒", "雉", "捒", "官", "酷", "樽", "房", "屣", "堌", "蒍", "悌", "④", - "蛳", "俱", "慢", "筇", "框", "椽", "债", "吭", "柱", "夤", "嘈", "骺", "趹", "刓", "豕", "噢", - "J", "论", "俞", "仙", "碰", "经", "铋", "⑤", "顽", "曲", "得", "汪", "浒", "际", "嘏", "扮", - "祊", "嵋", "‘", "牒", "禮", "粒", "籀", "闱", "刍", "邕", "美", "苫", "靺", "铹", "莰", "蔑", - "敵", "逑", "锬", "宸", "鞥", "匝", "褀", "菅", "逊", "脱", "晔", "罾", "郝", "恰", "丟", "芩", - "枷", "鹩", "a", "夙", "述", "钢", "瀵", "铧", "翱", "尧", "醮", "&", "鳐", "懲", "濩", "树", - "劵", "虾", "砚", "腄", "罟", "硖", "崩", "埘", "╱", "血", "觯", "巂", "栀", "萏", "雪", "眵", - "白", "新", "靶", "猪", "亻", "窬", "Ⅳ", "麽", "遄", "沏", "茅", "笋", "甬", "潔", "悛", "幕", - "鹤", "悴", "耻", "觜", "滞", "己", "鏂", "肛", "婤", "嘞", "蘸", "胴", "柿", "穗", "咯", "嵕", - "蜣", "僰", "玃", "细", "▏", "戗", "尘", "仄", "子", "历", "翌", "烀", "晞", "桷", "藕", "啄", - "腐", "瘥", "诣", "彗", "捭", "懑", "陛", "傥", "沚", "贯", "﹑", "雒", "航", "跬", "晓", "赢", - "鸭", "臊", "闳", "稲", "阁", "鼋", "‰", "个", "農", "匮", "辚", "滗", "桢", "詈", "绗", "馇", - "蜓", "专", "余", "鳉", "稚", "午", "珍", "癃", "钵", "档", "颍", "厕", "岭", "祓", "诂", "襙", - "炙", "枯", "锦", "袤", "桊", "嗓", "䘵", "嫂", "丰", "苎", "梦", "早", "菱", "钱", "灯", "钮", - "锓", "豐", "蝤", "协", "h", "鼓", "燕", "覺", "涮", "呗", "専", "篓", "玷", "褓", "从", "鲍", - "羧", "俭", "萌", "樣", "颜", "谷", "夹", "囫", "』", "缙", "鹰", "条", "状", "沨", "因", "莺", - "楼", "扰", "禢", "砧", "埔", "纩", "臭", "茶", "妹", "莼", "境", "山", "诘", "蒌", "唤", "仃", - "眄", "田", "畼", "缱", "祘", "痴", "揍", "猾", "甙", "躲", "返", "砝", "叽", "苟", "肭", "悖", - "嫣", "凋", "踞", "勢", "弃", "般", "赤", "佣", "嘘", "智", "寒", "旆", "咎", "戊", "温", "昙", - "蝄", "掉", "冤", "凍", "一", "鋼", "茏", "兼", "昃", "峤", "挟", "0", "顾", "颅", "*", "遆", - "硅", "烯", "眊", "鳘", "下", "雾", "癖", "贮", "缴", "升", "劲", "婞", "掇", "梯", "壬", "撮", - "绑", "氣", "薤", "兔", "赟", "漕", "签", "顇", "砭", "鸼", "明", "佧", "鹗", "哉", "席", "趁", - "砖", "澌", "撤", "萨", "熔", "蚝", "狮", "夔", "介", "青", "喈", "郂", "埝", "狗", "哚", "咪", - "材", "跑", "炗", "龉", "髓", "衣", "觀", "淋", "寄", "羮", "抵", "恁", "藿", "蜢", "甜", "兽", - "洒", "眶", "薯", "绷", "颀", "骑", "鲻", "|", "q", "繄", "丝", "焙", "瑕", "童", "豸", "讨", - "钿", "艮", "踧", "幽", "焰", "宽", "址", "鸩", "堉", "音", "擅", "铞", "埌", "宙", "_", "钥", - "承", "率", "噬", "凌", "程", "蚕", "嘣", "饭", "橉", "径", "1", "鄏", "袜", "孙", "樊", "窦", - "牦", "歡", "罕", "蓉", "诩", "㧎", "责", "豢", "逅", "甘", "礶", "镥", "穂", "到", "檑", "皇", - "泖", "腱", "郤", "竞", "竽", "溴", "木", "蛀", "蛟", "燧", "鹳", "谵", "钳", "魔", "链", "咆", - "荡", "婳", "冢", "鲧", "昝", "※", "倫", "才", "簿", "醫", "吕", "姗", "L", "俺", "隳", "鮮", - "衩", "鲆", "崟", "鲹", "岗", "镇", "嗄", "硪", "盎", "氟", "笪", "今", "公", "尽", "佬", "骧", - "驻", "翼", "咚", "盱", "镎", "浈", "谅", "洟", "嘭", "跶", "蔹", "咭", "妁", "殚", "砷", "购", - "犸", "哄", "笸", "喂", "赋", "倓", "项", "臧", "梳", "笏", "鹝", "昭", "罿", "镄", "П", "湯", - "U", "绐", "绂", "鸬", "毐", "台", "鈴", "憾", "痰", "缭", "绒", "赁", "效", "哝", "─", "偆", - "泗", "谇", "貘", "搜", "阗", "個", "艟", "嗔", "正", "筛", "鼷", "摛", "馀", "坡", "卓", "厥", - "睾", "雯", "篷", "狰", "掀", "夫", "靛", "伻", "茇", "顧", "猕", "占", "俟", "兄", "垡", "兆", - "铃", "屙", "轵", "銮", "磲", "桤", "跷", "缳", "粘", "袢", "尬", "獘", "社", "彬", "哨", "煳", - "莊", "教", "鸸", "窖", "晰", "捻", "环", "廿", "驶", "椠", "熟", "赓", "挥", "兵", "洚", "桧", - "埼", "嘀", "哎", "柞", "悄", "调", "洼", "蛇", "铬", "蝇", "倆", "谂", "姻", "怕", "瑙", "算", - "惮", "遥", "惟", "甫", "玺", "袈", "税", "玟", "械", "擗", "淤", "溟", "揞", "纲", "谤", "條", - "翕", "荛", "忾", "馿", "糖", "檗", "垱", "┐", "躜", "缒", "您", "蹶", "合", "数", "斟", "粲", - "玖", "淞", "孰", "觎", "M", "嫪", "毽", "桩", "蹦", "亹", "胾", "亲", "痉", "莙", "捐", "烁", - "瓣", "邀", "但", "误", "饻", "妄", "镱", "民", "嗳", "竦", "柰", "脒", "斓", "瞟", "拱", "霾", - "粜", "腽", "咬", "唿", "礻", "y", "褒", "郪", "熰", "梻", "甭", "处", "拖", "蜉", "鄱", "絲", - "宠", "瞵", "荷", "靓", "喻", "阢", "伫", "担", "朐", "墙", "儣", "胄", "簏", "皆", "踌", "萃", - "命", "滟", "睹", "叁", "蟮", "東", "﹖", "式", "營", "疠", "醳", "尔", "購", "吒", "柴", "途", - "力", "疰", "寳", "萬", "挨", "碥", "牍", "嘻", "柃", "剡", "徝", "杖", "螺", "祈", "産", "煽", - "讽", "瞭", "由", "牀", "涉", "暴", "枚", "仰", "它", "胤", "驯", "港", "寵", "熄", "蛮", "务", - "殃", "亸", "涢", "妫", "粥", "扦", "寺", "抿", "湃", "C", "脚", "涸", "动", "務", "镭", "检", - "釂", "耳", "榦", "怆", "氨", "瘳", "钽", "牚", "负", "纂", "獬", "息", "婄", "襞", "囹", "酰", - "扑", "臛", "价", "褡", "篼", "媢", "酊", "腋", "愣", "垯", "喃", "牾", "犨", "蜂", "诹", "迂", - "槑", "好", "褰", "咝", "③", "劐", "骄", "腉", "仕", "叵", "磅", "金", "皁", "勍", "煮", "鍪", - "筚", "吲", "艰", "床", "叛", "﹔", "喜", "齑", "昧", "乎", "谲", "匈", "麒", "身", "唑", "鲤", - "栂", "垭", "殪", "沪", "苌", "濡", "蒎", "遏", "®", "质", "纫", "罐", "瞍", "柄", "呼", "锱", - "盔", "搋", "烛", "喉", "奈", "赦", "轘", "鉴", "瓒", "铰", "恽", "腠", "韶", "胼", "侄", "珂", - "鹕", "䝉", "呤", "椁", "岳", "汲", "疤", "绊", "涂", "乾", "噎", "兑", "絜", "嘧", "蚯", "们", - "蝉", "玛", "魁", "黻", "振", "冥", "报", "窟", "笱", "喊", "瓴", "喾", "説", "雹", "恫", "a", - "颧", "給", "宅", "鞧", "嬷", "鼾", "笔", "鲉", "匹", "蠕", "愍", "氽", "赐", "畔", "絪", "洴", - "审", "窂", "褔", "狯", "谑", "毳", "右", "疣", "鲙", "堃", "瓜", "…", "崆", "钫", "樭", "鲛", - "砂", "筋", "犏", "乱", "入", "浐", "膙", "厚", "獗", "覌", "焦", "罃", "宬", "隍", "荃", "醜", - "厉", "艇", "娟", "樂", "筲", "洛", "唼", "诜", "馑", "香", "缛", "运", "祟", "踩", "陲", "叔", - "潞", "二", "搠", "祼", "瀘", "蒋", "樗", "麦", "鸦", "棻", "古", "鹠", "怊", "裾", "够", "璧", - "晡", "擘", "毂", "御", "葚", "忱", "觞", "瑁", "唇", "罡", "剽", "殡", "沛", "帻", "举", "瞓", - "谬", "溝", "言", "哽", "婿", "猿", "跗", "獴", "俜", "呙", "弗", "凿", "窭", "铌", "友", "唉", - "怫", "荘", -]; - -pub const CHARSET_OLD: &[&str] = &["", "笤", "谴", "膀", "荔"]; - - - - -// pub fn from_builtin_old() -> Self { -// Self::from_static_slice( -// CHARSET_OLD, -// false, -// Resize::DynamicWidth(64), -// 1, -// Normalization::ZeroToOne, -// ) -// } -// -// /// 从预设的 Beta 版字符集创建 -// pub fn from_builtin_beta() -> Self { -// Self::from_static_slice( -// CHARSET_BETA, -// false, -// Resize::DynamicWidth(64), -// 1, -// Normalization::MinusOneToOne, -// ) -// } - - -// /// 从外部外部 JSON 文件动态加载字符集(在后续优化中移除) -// pub fn from_json_file>(path: P) -> anyhow::Result { -// let path = path.as_ref(); -// if !path.exists() { -// return Err(anyhow!("模型元数据配置文件不存在: {:?}", path)); -// } -// -// let mut file = File::open(path)?; -// let mut content = String::new(); -// file.read_to_string(&mut content)?; -// -// let dto: ModelMetadataDto = serde_json::from_str(&content) -// .map_err(|e| anyhow!("JSON 反序列化失败,请检查字段是否完整: {}", e))?; -// -// // 1. 将 DTO 的字符串数组转化为强类型的 Charset -// let tokens: Vec> = -// dto.charset.into_iter().map(|s| Cow::Owned(s)).collect(); -// let charset = Charset::new(tokens); -// -// // 2. 解析 resize 策略(重现 Python 的复杂条件判断) -// if dto.resize.len() != 2 { -// return Err(anyhow!( -// "'resize (or image)' 字段必须是包含两个元素的数组,例如 [-1, 64]" -// )); -// } -// let r0 = dto.resize[0]; -// let r1 = dto.resize[1]; -// -// let resize = if r0 == -1 { -// if dto.word { -// // 如果 word 为 true,且包含 -1,Python 里是 resize 为 (r1, r1) 的正方形 -// Resize::Square(r1 as u32) -// } else { -// // 如果 word 为 false,且包含 -1,Python 里是高度固定为 r1,宽度按原图比例缩放 -// Resize::DynamicWidth(r1 as u32) -// } -// } else { -// // 正常的固定宽高 -// Resize::Fixed(r0 as u32, r1 as u32) -// }; -// -// Ok(Self { -// charset, -// word: dto.word, -// resize, -// channel: dto.channel, -// normalization: dto.normalization, -// }) -// } \ No newline at end of file diff --git a/ddddocr-tract/tests/ocr_test.rs b/ddddocr-tract/tests/ocr_test.rs deleted file mode 100644 index be5c7cc..0000000 --- a/ddddocr-tract/tests/ocr_test.rs +++ /dev/null @@ -1,251 +0,0 @@ -use anyhow::Context; -use ddddocr_core::traits::Loader; -use ddddocr_tract::{DetectionResult, Ocr}; -use ddddocr_tract::{Detector, ModelMetadata, Normalization, Slider}; -// 假设你的包名是这个 -use ddddocr_tract::{DetRuntime, OcrRuntime}; -use image::{DynamicImage, ImageBuffer, Luma, Rgb}; -use std::fs; -use std::path::Path; - -mod char_slice; -use char_slice::CHARSET_BETA; -use ddddocr_core::Resize; - -use ddddocr_tract::loader::ModelLoader as TractModelLoader; - -fn load_image>(path: P) -> anyhow::Result { - // 1. 先将泛型转为具体的 &Path 引用 - let path_ref = path.as_ref(); - - // 2. 调用 open 时传入引用(utils::open 支持 AsRef) - image::open(path_ref).map_err(|e| { - // 3. 此时 path_ref 依然有效,可以安全地在闭包中使用 - anyhow::anyhow!("无法加载图片 {:?}: {}", path_ref, e) - }) -} -/// 将检测结果绘制在图像上并保存 -fn save_debug_image( - dynamic_img: &DynamicImage, // 【优化点 1】直接传入解码好的引用,拒绝重复解码 - bboxes: &[DetectionResult], // 【修改点 1】类型改为自定义结构体切片 - output_path: &str, -) -> anyhow::Result<()> { - // 删除了原本的 let dynamic_img = image::load_from_memory(image_bytes)?; - let mut img = dynamic_img.to_rgb8(); - let (width, height) = img.dimensions(); - let red = Rgb([255u8, 0, 0]); - - for bbox in bboxes { - // 【修改点 2】将原来的索引 bbox[0].. 改为结构体字段访问 .x1, .y1 .. - let x1 = bbox.x1.max(0).min(width as i32 - 1) as u32; - let y1 = bbox.y1.max(0).min(height as i32 - 1) as u32; - let x2 = bbox.x2.max(0).min(width as i32 - 1) as u32; - let y2 = bbox.y2.max(0).min(height as i32 - 1) as u32; - - // 绘制横向线条 - for x in x1..=x2 { - img.put_pixel(x, y1, red); - img.put_pixel(x, y2, red); - if y1 + 1 < height { - img.put_pixel(x, y1 + 1, red); - } - if y2.saturating_sub(1) > 0 { - img.put_pixel(x, y2 - 1, red); - } - } - // 绘制纵向线条 - for y in y1..=y2 { - img.put_pixel(x1, y, red); - img.put_pixel(x2, y, red); - if x1 + 1 < width { - img.put_pixel(x1 + 1, y, red); - } - if x2.saturating_sub(1) > 0 { - img.put_pixel(x2 - 1, y, red); - } - } - } - - img.save(output_path)?; - Ok(()) -} -#[allow(dead_code)] -fn save_rust_result(result: &ImageBuffer, Vec>, filename: &str) { - let (width, height) = result.dimensions(); - - // 1. 寻找最值进行归一化 - let mut max_val = f32::MIN; - let mut min_val = f32::MAX; - for p in result.pixels() { - if p.0[0] > max_val { - max_val = p.0[0]; - } - if p.0[0] < min_val { - min_val = p.0[0]; - } - } - - // 2. 创建 8 位灰度图 - let mut out_buf = ImageBuffer::new(width, height); - for y in 0..height { - for x in 0..width { - let val = result.get_pixel(x, y).0[0]; - let normalized = if max_val > min_val { - ((val - min_val) / (max_val - min_val) * 255.0) as u8 - } else { - 0u8 - }; - out_buf.put_pixel(x, y, Luma([normalized])); - } - } - - // 3. 保存 - DynamicImage::ImageLuma8(out_buf).save(filename).unwrap(); - println!("Rust 结果热力图已保存至: {}", filename); -} -#[test] -fn test_full_classification() { - let session = TractModelLoader::default() - .build_for_path("D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_sml2h3_f32.onnx") - .expect("模型加载失败"); - - let metadata = ModelMetadata::from_static_slice( - CHARSET_BETA, - false, - Resize::DynamicWidth(64), - 1, - Normalization::MinusOneToOne, - ); - // 1. 初始化模型 - let ocr_runtime = OcrRuntime::new(session, metadata); - // 2. 加载测试图片 - let img = - image::open("D:/CNWei/CNW/Rust/ddddocr-rs/samples/code2.png").expect("测试图片不存在"); - - // 3. 执行识别 - // let result = Ocr::new(&ocr_runtime) - // .predict(&img) - // .expect("识别过程出错") - // .into_text(); - let result = Ocr::builder() - .build_with(&ocr_runtime) - .predict(&img) - .expect("识别过程出错") - .into_text(); - - println!("识别结果: {}", result); - assert!(!result.is_empty()); -} -#[test] -fn test_det_load() -> anyhow::Result<()> { - let det_model = TractModelLoader::default() - .build_for_path("D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_det.onnx") - .expect("模型加载失败"); - let det = DetRuntime::new(det_model); - let image_path = "D:/CNWei/CNW/Rust/ddddocr-rs/samples/det1.png"; - let image_bytes = - fs::read(image_path).map_err(|e| anyhow::anyhow!("无法读取图片 {}: {}", image_path, e))?; - - println!("图片读取成功,字节大小: {}", image_bytes.len()); - - // 【修改点 1】将字节流解码为统一的 DynamicImage - let img = image::load_from_memory(&image_bytes) - .map_err(|e| anyhow::anyhow!("图片解码失败: {}", e))?; - - // 【修改点 2】传入统一的 &DynamicImage 引用 - let bboxes = Detector::new(&det).predict(&img)?; - // println!("{:?}", det); - println!("检测到的目标数量: {}", bboxes.len()); - - if bboxes.is_empty() { - println!("未检测到任何目标。"); - } else { - // 如果 save_debug_image 报错,记得去把它的入参类型和内部访问也改为 DetectionResult - save_debug_image( - &img, - &bboxes, - "D:/CNWei/CNW/Rust/ddddocr-rs/samples/result.jpg", - )?; - - for (i, bbox) in bboxes.iter().enumerate() { - // 【修改点 3】将原来的 bbox[0].. 索引访问改为结构体字段访问 - println!("目标 [{}]: {}", i, bbox); - } - } - Ok(()) -} - -#[test] -fn test_real_slide_match() { - let engine = Slider::new(); - - // 1. 加载你准备好的测试图 - // 假设图片放在项目根目录下的 assets 文件夹 - let target_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/hua.png") - .expect("请确保 samples/hua.png 存在"); - let bg_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/huatu.png") - .expect("请确保 samples/huatu.png 存在"); - - // 2. 执行匹配 - // 如果是那种带有明显阴影边缘的复杂滑块,建议 simple_target 传 false - let start = std::time::Instant::now(); - let result = engine - .slide_match(&target_img, &bg_img, false) - .expect("Slide match 执行失败"); - let duration = start.elapsed(); - - // 3. 打印结果 - println!("-------------------------------------------"); - println!("{}", result); - println!("耗时: {:?}", duration); - println!("-------------------------------------------"); - - // 验证基本逻辑:坐标不应为 0 (除非匹配失败) - assert_eq!(result.target_x, 237); - assert_eq!(result.target_y, 77); - assert!(result.confidence > 0.0); -} - -#[test] -fn test_real_slide_comparison() { - let engine = Slider::new(); - - // 1. 加载你准备好的测试图 - // 假设图片放在项目根目录下的 assets 文件夹 - let target_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/ken.jpg") - .expect("请确保 samples/ken.jpg 存在"); - let bg_img = load_image("D:/CNWei/CNW/Rust/ddddocr-rs/samples/kenyuan.jpg") - .expect("请确保 samples/kenyuan.jpg 存在"); - - // 2. 执行匹配 - // 如果是那种带有明显阴影边缘的复杂滑块,建议 simple_target 传 false - let start = std::time::Instant::now(); - let result = engine - .slide_comparison(&target_img, &bg_img) - .expect("Slide match 执行失败"); - let duration = start.elapsed(); - - // 3. 打印结果 - println!("-------------------------------------------"); - println!("滑块匹配测试结果:"); - println!("检测坐标: [x: {}, y: {}]", result.target_x, result.target_y); - println!("置信度: {:.4}", result.confidence); - println!("耗时: {:?}", duration); - println!("-------------------------------------------"); - - // 验证基本逻辑:坐标不应为 0 (除非匹配失败) - assert_eq!(result.target_x, 171); - assert_eq!(result.target_y, 90); - assert!(result.confidence > 0.0); -} -#[test] -fn test_resolve_shape_logic_direct() { - // 创建一个哑 ModelLoader 实例(session 用不上,因为我们直接测私有方法) - let loader = TractModelLoader::default() - .build_for_path( - // "D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_sml2h3_f32.onnx", - "D:\\CNWei\\CNW\\Rust\\ddddocr-rs\\models\\common_huashi666_i64.onnx", - ) - .expect("建立测试模型图失败"); - println!("{:?}", loader.model().inputs); -} diff --git a/ddddocr-tract2/Cargo.toml b/ddddocr-tract2/Cargo.toml new file mode 100644 index 0000000..a5eb41d --- /dev/null +++ b/ddddocr-tract2/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "ddddocr-tract2" +version = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +description = "ddddocr-rs 的 Tract 推理引擎实现" +keywords = ["ocr", "captcha", "ddddocr", "onnxruntime", "tract"] +categories = ["multimedia::images", "computer-vision"] +# repository = "https://github.com/<用户名>/<仓库名>" # 发布前请补充 +readme = "../README.md" + +[dependencies] +ddddocr-core = { path = "../ddddocr-core", version = "0.2.4" } +tract-onnx = { workspace = true } +tract-linalg = { workspace = true } +ndarray = { workspace = true } +image = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } diff --git a/ddddocr-tract/src/ocr.rs b/ddddocr-tract2/src/det.rs similarity index 100% rename from ddddocr-tract/src/ocr.rs rename to ddddocr-tract2/src/det.rs diff --git a/ddddocr-tract2/src/det/session.rs b/ddddocr-tract2/src/det/session.rs new file mode 100644 index 0000000..322f903 --- /dev/null +++ b/ddddocr-tract2/src/det/session.rs @@ -0,0 +1,44 @@ +use crate::runtime::{extract_plain_array, run_session}; +use crate::types::Session; +use ddddocr_core::DetOutput; +use ddddocr_core::error::{Result, TensorError}; +use ddddocr_core::traits::{DetEngine, InferenceEngine}; +use ndarray::Ix3; +use tracing::debug; +use tract_onnx::prelude::*; + +#[derive(Debug)] +/// 目标检测推理运行时:持有 Tract 会话,输出 [`DetOutput`]。 +pub struct DetRuntime { + /// Tract 会话句柄。 + pub session: Session, +} + +impl DetRuntime { + /// 基于已构建的会话创建检测运行时。 + pub fn new(session: Session) -> Self { + Self { session } + } +} + +impl InferenceEngine for DetRuntime { + type Output = DetOutput; + fn inference(&self, input_array: ndarray::Array4) -> Result { + let mut result = run_session(&self.session, input_array)?; + debug!("模型输出原始数据: {:?}", result); + let raw_tensor = result.swap_remove(0).into_tensor(); + let array_d = extract_plain_array::(raw_tensor)?; + let actual_shape = array_d.shape().to_vec(); + + let array3 = + array_d + .into_dimensionality::() + .map_err(|_| TensorError::DimensionMismatch { + expected: "3D 检测矩阵 [Batch, Box_Count, Box_Attributes]".to_string(), + actual: actual_shape, + })?; + Ok(DetOutput::Detection(array3)) + } +} + +impl DetEngine for DetRuntime {} diff --git a/ddddocr-tract2/src/lib.rs b/ddddocr-tract2/src/lib.rs new file mode 100644 index 0000000..6d89dd4 --- /dev/null +++ b/ddddocr-tract2/src/lib.rs @@ -0,0 +1,22 @@ +//! # ddddocr-tract2 +//! +//! 基于 Tract(纯 Rust ONNX 推理框架)的推理引擎实现:通过 [`loader::ModelLoader`] 构建会话, +//! 再由 [`OcrRuntime`] / [`DetRuntime`] 实现 core 的 +//! [`ddddocr_core::traits::InferenceEngine`] 接口。 +//! 同时重导出 core 的 [`OcrBuilder`]、[`Slider`]、[`SlideResult`] 等便捷 API。 + +#![warn(missing_docs)] + +mod det; +/// 模型加载器:从路径或字节流构建 Tract 会话。 +pub mod loader; +mod ocr; +mod runtime; +mod types; + +pub use ddddocr_core::{ + DetectionResult, Detector, ModelMetadata, Normalization, Ocr, OcrBuilder, SlideResult, Slider, +}; +pub use det::session::DetRuntime; +pub use ocr::session::OcrRuntime; +pub use types::Session; diff --git a/ddddocr-tract/src/loader.rs b/ddddocr-tract2/src/loader.rs similarity index 63% rename from ddddocr-tract/src/loader.rs rename to ddddocr-tract2/src/loader.rs index dcd4dd7..094c247 100644 --- a/ddddocr-tract/src/loader.rs +++ b/ddddocr-tract2/src/loader.rs @@ -3,5 +3,5 @@ mod metadata; mod model; pub use error::{Error, ParseError, Result}; -pub use metadata::{ModelMetadataDto, NormalizationDto, Metadata}; +pub use metadata::{Metadata, ModelMetadataDto, NormalizationDto}; pub use model::ModelLoader; diff --git a/ddddocr-tract/src/loader/error.rs b/ddddocr-tract2/src/loader/error.rs similarity index 64% rename from ddddocr-tract/src/loader/error.rs rename to ddddocr-tract2/src/loader/error.rs index fd39b5d..9c08d8f 100644 --- a/ddddocr-tract/src/loader/error.rs +++ b/ddddocr-tract2/src/loader/error.rs @@ -1,6 +1,8 @@ use tract_onnx::prelude::TractError; +/// 模型加载与解析的通用结果类型。 pub type Result = std::result::Result; #[derive(thiserror::Error, Debug)] +/// 模型加载、解析与 Session 构建阶段的错误。 pub enum Error { /// 解析 ONNX 模型/路径失败(如文件损坏、算子不支持、路径非法) #[error("解析 ONNX 模型结构失败: {0}")] @@ -22,6 +24,7 @@ pub enum Error { #[error("Metadata 字节流不是合法的 UTF-8 编码: {0}")] InvalidUtf8(#[from] std::str::Utf8Error), + /// 模型元数据内容解析失败。 #[error("模型元数据解析失败: {0}")] MetadataParse(String), @@ -38,8 +41,9 @@ impl Error { Self::Other(msg.into(), err.into()) } } -#[derive(thiserror::Error,Debug)] -pub enum ParseError{ +#[derive(thiserror::Error, Debug)] +/// 从路径或字节流解析 ONNX 模型失败的错误。 +pub enum ParseError { /// 策略 A:从文件路径加载失败(附带路径上下文信息,方便排查是找不到文件还是格式不对) #[error("从路径 '{0}' 加载 ONNX 模型失败: {1}")] Path(String, #[source] TractError), @@ -47,4 +51,32 @@ pub enum ParseError{ /// 策略 B:从内存字节流加载失败(如 include_bytes! 传入的字节流损坏) #[error("从内存字节流解析 ONNX 模型失败: {0}")] Bytes(#[source] TractError), -} \ No newline at end of file +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn wraps_external_error_via_new() { + let io_err = std::io::Error::other("boom"); + let err = Error::new("自定义错误", io_err); + assert!(matches!(err, Error::Other(_, _))); + assert!(err.to_string().contains("自定义错误")); + } + + #[test] + fn serde_json_error_converts_to_error() { + let json_err = serde_json::from_str::("{").unwrap_err(); + let err: Error = json_err.into(); + assert!(matches!(err, Error::JsonParse(_))); + } + + #[test] + fn invalid_utf8_converts_to_error() { + let bytes = vec![0xffu8]; + let utf8_err = std::str::from_utf8(&bytes).unwrap_err(); + let err: Error = utf8_err.into(); + assert!(matches!(err, Error::InvalidUtf8(_))); + } +} diff --git a/ddddocr-tract/src/loader/metadata.rs b/ddddocr-tract2/src/loader/metadata.rs similarity index 50% rename from ddddocr-tract/src/loader/metadata.rs rename to ddddocr-tract2/src/loader/metadata.rs index 3f2dd1e..8679544 100644 --- a/ddddocr-tract/src/loader/metadata.rs +++ b/ddddocr-tract2/src/loader/metadata.rs @@ -8,6 +8,7 @@ use std::borrow::Cow; #[derive(Deserialize)] #[serde(rename_all = "snake_case")] // 支持 json 中写 "zero_to_one" 或 "minus_one_to_one" +/// 归一化策略的 JSON 反序列化中间表示。 pub enum NormalizationDto { /// 映射到 [0.0, 1.0] -> pixel / 255.0 ZeroToOne, @@ -41,8 +42,9 @@ fn default_normalization() -> NormalizationDto { NormalizationDto::ZeroToOne } -/// Tract 专属扩展trait 或 工具函数 +/// 从 JSON 字符串或字节流解析模型元数据的扩展接口。 pub trait Metadata: Sized { + /// 从 JSON 字符串解析模型元数据。 fn from_json_str(json_str: &str) -> Result; /// 机制 2:从内存字节流加载(极大地方便 include_bytes! 或网络下载) fn from_json_bytes(bytes: &[u8]) -> Result { @@ -56,8 +58,7 @@ impl Metadata for ModelMetadata { let dto: ModelMetadataDto = serde_json::from_str(json_str)?; // 1. 将 DTO 的字符串数组转化为强类型的 Charset - let tokens: Vec> = - dto.charset.into_iter().map(|s| Cow::Owned(s)).collect(); + let tokens: Vec> = dto.charset.into_iter().map(Cow::Owned).collect(); let charset = Charset::new(tokens); // 2. 解析 resize 策略(重现 Python 的复杂条件判断) @@ -91,3 +92,104 @@ impl Metadata for ModelMetadata { )) } } + +#[cfg(test)] +mod tests { + use super::*; + + const MINIMAL_JSON: &str = r#"{ + "charset": ["a", "b", "c"], + "word": false, + "resize": [-1, 64], + "channel": 1 + }"#; + + #[test] + fn parses_minimal_json_with_default_normalization() { + let meta = ModelMetadata::from_json_str(MINIMAL_JSON).unwrap(); + assert_eq!(meta.charset.size(), 3); + assert!(!meta.word); + assert_eq!(meta.channel, 1); + assert!(matches!(meta.resize, Resize::DynamicWidth(64))); + assert!(matches!(meta.normalization, Normalization::ZeroToOne)); + } + + #[test] + fn parses_minus_one_to_one_normalization() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [-1, 64], + "channel": 1, + "normalization": "minus_one_to_one" + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.normalization, Normalization::MinusOneToOne)); + } + + #[test] + fn parses_word_model_as_square_resize() { + let json = r#"{ + "charset": ["a"], + "word": true, + "resize": [-1, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Square(64))); + } + + #[test] + fn parses_fixed_resize() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [100, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Fixed(100, 64))); + } + + #[test] + fn parses_image_alias() { + let json = r#"{ + "charset": ["a"], + "word": false, + "image": [200, 64], + "channel": 1 + }"#; + let meta = ModelMetadata::from_json_str(json).unwrap(); + assert!(matches!(meta.resize, Resize::Fixed(200, 64))); + } + + #[test] + fn rejects_resize_with_wrong_length() { + let json = r#"{ + "charset": ["a"], + "word": false, + "resize": [1, 2, 3], + "channel": 1 + }"#; + assert!(matches!( + ModelMetadata::from_json_str(json), + Err(Error::MetadataParse(_)) + )); + } + + #[test] + fn rejects_invalid_json() { + assert!(matches!( + ModelMetadata::from_json_str("not json"), + Err(Error::JsonParse(_)) + )); + } + + #[test] + fn rejects_invalid_utf8_bytes() { + assert!(matches!( + ModelMetadata::from_json_bytes(&[0xff, 0xfe]), + Err(Error::InvalidUtf8(_)) + )); + } +} diff --git a/ddddocr-tract/src/loader/model.rs b/ddddocr-tract2/src/loader/model.rs similarity index 52% rename from ddddocr-tract/src/loader/model.rs rename to ddddocr-tract2/src/loader/model.rs index 1d5688b..9239c38 100644 --- a/ddddocr-tract/src/loader/model.rs +++ b/ddddocr-tract2/src/loader/model.rs @@ -46,13 +46,10 @@ impl Loader for ModelLoader { let session = onnx() .model_for_path(path_ref) .map_err(|e| ParseError::Path(path_ref.display().to_string(), e))? - // .with_context(|| "加载 ONNX 模型失败,请检查路径是否正确")? .into_optimized() .map_err(Error::OptimizationFailed)? - // .with_context(|| "优化 Tract 模型图失败")? .into_runnable() .map_err(Error::RunnableBuildFailed)?; - // .with_context(|| "构建可运行 Tract 实例失败")?; Ok(session) } /// 策略 B:从内存字节流加载模型(配合 include_bytes! 使用) @@ -64,13 +61,10 @@ impl Loader for ModelLoader { let session = onnx() .model_for_read(&mut cursor) .map_err(ParseError::Bytes)? - // .with_context(|| "从内存字节流解析 ONNX 模型失败")? .into_optimized() .map_err(Error::OptimizationFailed)? - // .with_context(|| "优化 Tract 模型图失败")? .into_runnable() .map_err(Error::RunnableBuildFailed)?; - // .with_context(|| "构建可运行 Tract 实例失败")?; Ok(session) } @@ -80,48 +74,22 @@ impl Loader for ModelLoader { mod tests { use super::*; - /// 辅助函数:动态构建一个简单的 ONNX/Tract 内存模型图用于测试 - fn create_test_model() -> std::result::Result { - let mut rect = TypedModel::default(); - - // 0.21.10 最稳妥的静态 Fact 构建 - let input_fact = TypedFact::dt_shape(DatumType::F32, &[1, 3, 224, 224]); - - let input_node = rect - .add_source("input", input_fact) - .map_err(|e| anyhow::anyhow!("{:?}", e))?; - - rect.set_input_outlets(&[input_node.into()]) - .map_err(|e| anyhow::anyhow!("{:?}", e))?; - - let typed = rect - .into_optimized() - .map_err(|e| anyhow::anyhow!("{:?}", e))?; - let runnable = typed - .into_runnable() - .map_err(|e| anyhow::anyhow!("{:?}", e))?; - Ok(runnable) + #[test] + fn default_config() { + let loader = ModelLoader::default(); + assert!(loader.num_threads.is_none()); } - // #[test] - // fn test_input_output_shapes_and_type() { - // let session = create_test_model().expect("建立测试模型图失败"); - // - // println!("{:?}", ModelLoader::model_info(&session).unwrap()); - // // 1. 测试输入维度解析 - // } - // - // #[test] - // fn test_resolve_shape_logic_direct() { - // // 创建一个哑 ModelLoader 实例(session 用不上,因为我们直接测私有方法) - // let session = create_test_model().expect("建立测试模型图失败"); - // - // let dims: Vec = vec![TDim::from(1), TDim::from(3), TDim::from(224)]; - // // 方案二的精髓:我们直接利用已导出的 ShapeFact 来纯手工验证边界逻辑! - // // 1. 验证纯静态维度是否被正确还原 - // let static_shape = ShapeFact::from_dims(dims); - // - // let res = ModelLoader - // ::resolve_shape(&static_shape); - // } + #[test] + fn builder_configures_threads() { + let loader = ModelLoader::default().num_threads(4); + assert_eq!(loader.num_threads, Some(4)); + } + + #[test] + fn builder_is_chainable_and_immutable() { + let base = ModelLoader::default(); + let _configured = base.clone().num_threads(8); + assert!(base.num_threads.is_none()); + } } diff --git a/ddddocr-tract2/src/ocr.rs b/ddddocr-tract2/src/ocr.rs new file mode 100644 index 0000000..f52f1c4 --- /dev/null +++ b/ddddocr-tract2/src/ocr.rs @@ -0,0 +1 @@ +pub mod session; diff --git a/ddddocr-tract2/src/ocr/session.rs b/ddddocr-tract2/src/ocr/session.rs new file mode 100644 index 0000000..3a2e9d5 --- /dev/null +++ b/ddddocr-tract2/src/ocr/session.rs @@ -0,0 +1,174 @@ +use crate::runtime::{extract_plain_array, run_session}; +use crate::types::Session; +use ddddocr_core::ModelMetadata; +use ddddocr_core::OcrOutput; +use ddddocr_core::error::{DdddError, Result, TensorError}; +use ddddocr_core::traits::{InferenceEngine, Info, OcrEngine}; +use ddddocr_core::types::{AxisDim, ModelInfo, TensorInfo, TensorType}; +use ddddocr_core::utils::normalize_ocr_logits; +use tracing::debug; +use tract_onnx::prelude::{DatumType, IntoTensor, OutletId, ShapeFact, TypedModel}; + +/// OCR 推理运行时:持有 Tract 会话与模型元数据,输出 [`OcrOutput`]。 +pub struct OcrRuntime { + /// Tract 会话句柄。 + pub session: Session, + /// 模型元数据(字符集、归一化策略等)。 + pub metadata: ModelMetadata, +} +impl OcrRuntime { + /// 基于已构建的会话与元数据创建 OCR 运行时。 + pub fn new(session: Session, metadata: ModelMetadata) -> Self { + Self { session, metadata } + } + + /// 提取出来的公共转换逻辑:将一组 OutletId 解析为 TensorInfo 列表 + fn resolve_tensors(&self, model: &TypedModel, outlets: &[OutletId]) -> Result> { + outlets + .iter() + .map(|&outlet_id| { + let fact = model.outlet_fact(outlet_id).map_err(DdddError::new)?; + let shape = resolve_shape(&fact.shape); + let node_name = model.node(outlet_id.node).name.clone(); + let tensor_type = tensor_type_from_datum(fact.datum_type); + + Ok(TensorInfo { + name: node_name, + shape, + tensor_type, + }) + }) + .collect() // 函数式声明:自动传播第一处发生的错误 + } +} + +/// 将 Tract 的 DatumType 映射为 core 的 [`TensorType`]。 +fn tensor_type_from_datum(datum: DatumType) -> TensorType { + match datum { + DatumType::F32 => TensorType::F32, + DatumType::I64 => TensorType::I64, + _ => TensorType::Other, + } +} + +/// 安全还原 Tract 维度至 [`AxisDim`] 列表。 +fn resolve_shape(shape_fact: &ShapeFact) -> Vec { + shape_fact + .to_tvec() + .iter() + .map(|dim| { + // 防御性编程:必须同时满足能够转换为 i64 且 大于等于 0 + if let Ok(size) = dim.to_i64() { + if size >= 0 { + AxisDim::Static(size as usize) + } else { + // 如果 ONNX 导出时某些动态维度被标记为了 -1,安全地作为动态符号捕获 + AxisDim::Dynamic(dim.to_string()) + } + } else { + AxisDim::Dynamic(dim.to_string()) + } + }) + .collect() +} + +impl OcrEngine for OcrRuntime { + fn metadata(&self) -> &ModelMetadata { + &self.metadata + } +} +impl InferenceEngine for OcrRuntime { + type Output = OcrOutput; + fn inference(&self, input_array: ndarray::Array4) -> Result { + let mut result = run_session(&self.session, input_array)?; + debug!("模型输出原始数据: {:?}", result); + let raw_tensor = result.swap_remove(0).into_tensor(); + match raw_tensor.datum_type() { + DatumType::I64 => { + let array_d = extract_plain_array::(raw_tensor)?; + let actual_shape = array_d.shape().to_vec(); + let array1 = array_d.into_dimensionality::().map_err(|_| { + TensorError::DimensionMismatch { + expected: "1D 字符索引静态矩阵".to_string(), + actual: actual_shape, + } + })?; + Ok(OcrOutput::Indices(array1)) + } + DatumType::F32 => { + let shape = raw_tensor.shape().to_vec(); + debug!("模型输出 shape 数据: {:?}", shape); + let array = extract_plain_array::(raw_tensor)?; + normalize_ocr_logits(array.view(), array.shape()) + } + _ => Err(TensorError::UnknownOutputFormat), + } + } +} +impl Info for OcrRuntime { + fn input_info(&self) -> Result> { + let model = self.session.model(); + let outlets = model.input_outlets().map_err(DdddError::new)?; + self.resolve_tensors(model, outlets) + } + + /// 获取模型输出的节点信息列表 + fn output_info(&self) -> Result> { + let model = self.session.model(); + let outlets = model.output_outlets().map_err(DdddError::new)?; + self.resolve_tensors(model, outlets) + } + + /// 获取模型详细元数据信息(对标 Python ddddocr 的 get_model_info) + /// 完美包容 [1, 1, 64, image_width] 这样的变长图像模型 + /// 获取模型详细元数据信息(代码更紧凑、优雅) + fn model_info(&self) -> Result { + Ok(ModelInfo { + inputs: self.input_info()?, + outputs: self.output_info()?, + providers: None, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use tract_onnx::prelude::*; + + #[test] + fn maps_datum_types() { + assert!(matches!( + tensor_type_from_datum(DatumType::F32), + TensorType::F32 + )); + assert!(matches!( + tensor_type_from_datum(DatumType::I64), + TensorType::I64 + )); + assert!(matches!( + tensor_type_from_datum(DatumType::U8), + TensorType::Other + )); + } + + #[test] + fn resolves_static_shape() { + let fact = ShapeFact::from_dims(vec![TDim::from(1), TDim::from(64)]); + assert_eq!( + resolve_shape(&fact), + vec![AxisDim::Static(1), AxisDim::Static(64)] + ); + } + + #[test] + fn resolves_dynamic_dimension_as_symbol() { + let scope = SymbolScope::default(); + let dims = vec![TDim::from(1), TDim::from(64), scope.sym("width").into()]; + let fact = ShapeFact::from_dims(dims); + let shape = resolve_shape(&fact); + assert_eq!(shape[0], AxisDim::Static(1)); + assert_eq!(shape[1], AxisDim::Static(64)); + assert!(matches!(&shape[2], AxisDim::Dynamic(_))); + } +} diff --git a/ddddocr-tract2/src/runtime.rs b/ddddocr-tract2/src/runtime.rs new file mode 100644 index 0000000..a61e588 --- /dev/null +++ b/ddddocr-tract2/src/runtime.rs @@ -0,0 +1,25 @@ +//! 会话执行相关的共享工具函数。 + +use crate::types::Session; +use ddddocr_core::error::TensorError; +use tract_onnx::prelude::{Datum, TValue, TVec, Tensor, tvec}; + +/// 对输入张量执行一次 Tract 推理,返回原始输出值列表。 +pub(crate) fn run_session( + session: &Session, + input_array: ndarray::Array4, +) -> Result, TensorError> { + let tensor = Tensor::from(input_array); + session + .run(tvec!(tensor.into())) + .map_err(|e| TensorError::Engine(format!("执行模型推理失败: {e}"))) +} + +/// 将 Tensor 转换为 ndarray 的 `ArrayD`。 +pub(crate) fn extract_plain_array( + tensor: Tensor, +) -> Result, TensorError> { + tensor + .into_plain_array::() + .map_err(|_| TensorError::Engine("无法获取张量内存视图".to_string())) +} diff --git a/ddddocr-tract2/src/types.rs b/ddddocr-tract2/src/types.rs new file mode 100644 index 0000000..0f7d56e --- /dev/null +++ b/ddddocr-tract2/src/types.rs @@ -0,0 +1,7 @@ +//! Tract 会话共享类型。 + +use std::sync::Arc; +use tract_onnx::prelude::TypedRunnableModel; + +/// Tract 会话句柄:由 [`crate::loader::ModelLoader`] 构建,可直接并发执行推理。 +pub type Session = Arc; diff --git a/ddddocr-tract2/tests/api_surface.rs b/ddddocr-tract2/tests/api_surface.rs new file mode 100644 index 0000000..568583f --- /dev/null +++ b/ddddocr-tract2/tests/api_surface.rs @@ -0,0 +1,74 @@ +//! 外部视角 API 测试:验证 `ddddocr-tract2` 的公开类型与方法在外部 crate 中可正常使用。 + +use ddddocr_core::Resize; +use ddddocr_core::traits::{Info, Loader}; +use ddddocr_core::types::AxisDim; +use ddddocr_tract2::loader::ModelLoader; +use ddddocr_tract2::{ + DetRuntime, ModelMetadata, Normalization, OcrBuilder, OcrRuntime, Session, SlideResult, Slider, +}; +use std::path::{Path, PathBuf}; + +fn model_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("models") + .join(name) +} + +/// 验证对外导出的类型(含 `Session` 与 core 便捷重导出)均可直接命名。 +#[test] +fn public_types_are_nameable() { + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _slider = Slider::new(); +} + +/// 验证构建器链式 API 可组合使用,且返回的会话类型可显式标注。 +#[test] +fn loader_chain_builds_session() -> anyhow::Result<()> { + let path = model_path("common_sml2h3_f32.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let _session: Session = ModelLoader::default().num_threads(4).build_for_path(path)?; + Ok(()) +} + +/// 验证 `Info` trait 能从真实会话中解析输入/输出信息。 +#[test] +fn info_trait_returns_model_metadata() -> anyhow::Result<()> { + let path = model_path("common_sml2h3_f32.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let session: Session = ModelLoader::default().build_for_path(path)?; + let metadata = ModelMetadata::from_static_slice( + &["a", "b"], + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let inputs = ocr.input_info()?; + let outputs = ocr.output_info()?; + assert!(!inputs.is_empty()); + assert!(!outputs.is_empty()); + assert!(matches!(inputs[0].shape[0], AxisDim::Static(1))); + assert!(matches!(inputs[0].shape[2], AxisDim::Static(64))); + + let model_info = ocr.model_info()?; + assert_eq!(model_info.inputs.len(), inputs.len()); + assert_eq!(model_info.outputs.len(), outputs.len()); + assert!(model_info.providers.is_none()); + Ok(()) +} + +/// 验证检测运行时可以从构建的会话创建。 +#[test] +fn det_runtime_builds_from_session() -> anyhow::Result<()> { + let path = model_path("common_det.onnx"); + assert!(path.exists(), "缺少测试模型: {}", path.display()); + let session: Session = ModelLoader::default().build_for_path(path)?; + let _det = DetRuntime::new(session); + Ok(()) +} diff --git a/ddddocr-tract2/tests/common/mod.rs b/ddddocr-tract2/tests/common/mod.rs new file mode 100644 index 0000000..8c8cb5f --- /dev/null +++ b/ddddocr-tract2/tests/common/mod.rs @@ -0,0 +1,25 @@ +//! 集成测试共享工具。 + +use std::path::{Path, PathBuf}; + +/// 仓库根目录 `models/` 下模型文件的路径。 +pub fn model_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("models") + .join(name) +} + +/// 仓库根目录 `samples/` 下样例图片的路径。 +pub fn sample_path(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("samples") + .join(name) +} + +/// 加载图片,失败时附带路径上下文。 +pub fn load_image>(path: P) -> anyhow::Result { + let path_ref = path.as_ref(); + image::open(path_ref).map_err(|e| anyhow::anyhow!("无法加载图片 {:?}: {}", path_ref, e)) +} diff --git a/ddddocr-tract2/tests/det.rs b/ddddocr-tract2/tests/det.rs new file mode 100644 index 0000000..2478cfc --- /dev/null +++ b/ddddocr-tract2/tests/det.rs @@ -0,0 +1,33 @@ +//! 目标检测集成测试。 + +mod common; + +use common::{model_path, sample_path}; +use ddddocr_core::Detector; +use ddddocr_core::traits::Loader; +use ddddocr_tract2::DetRuntime; +use ddddocr_tract2::loader::ModelLoader; +use image::GenericImageView; + +/// 检测模型应能从样例图片中找到至少一个目标,且坐标在图片范围内。 +#[test] +fn det_model_detects_targets_in_image() -> anyhow::Result<()> { + let session = ModelLoader::default() + .build_for_path(model_path("common_det.onnx")) + .expect("模型加载失败"); + let det = DetRuntime::new(session); + let img = image::open(sample_path("det1.png")).expect("测试图片不存在"); + + let bboxes = Detector::new(&det).predict(&img)?; + assert!(!bboxes.is_empty(), "应检测到至少一个目标"); + + let (width, height) = img.dimensions(); + for bbox in &bboxes { + assert!(bbox.x1 >= 0 && bbox.y1 >= 0, "检测框左上角不应为负"); + assert!( + bbox.x2 <= width as i32 && bbox.y2 <= height as i32, + "检测框右下角不应超出图片范围" + ); + } + Ok(()) +} diff --git a/ddddocr-tract2/tests/ocr.rs b/ddddocr-tract2/tests/ocr.rs new file mode 100644 index 0000000..c8c5714 --- /dev/null +++ b/ddddocr-tract2/tests/ocr.rs @@ -0,0 +1,55 @@ +//! OCR 识别与模型信息集成测试。 + +mod common; + +use common::{model_path, sample_path}; +use ddddocr_core::traits::{Info, Loader}; +use ddddocr_core::{ModelMetadata, Normalization, Ocr, Resize}; +use ddddocr_tract2::OcrRuntime; +use ddddocr_tract2::loader::ModelLoader; + +/// 用官方 sml2h3 f32 模型识别验证码图片,结果不应为空。 +#[test] +fn ocr_classification_recognizes_code_image() { + let session = ModelLoader::default() + .build_for_path(model_path("common_sml2h3_f32.onnx")) + .expect("模型加载失败"); + let metadata = ModelMetadata::from_builtin_beta( + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let img = image::open(sample_path("code2.png")).expect("测试图片不存在"); + let text = Ocr::builder() + .build_with(&ocr) + .predict(&img) + .expect("识别过程出错") + .into_text(); + + println!("识别结果: {text}"); + assert!(!text.is_empty(), "识别结果不应为空"); +} + +/// 真实模型应能通过 `Info` trait 返回输入/输出张量信息。 +#[test] +fn model_info_lists_inputs_and_outputs() -> anyhow::Result<()> { + let session = ModelLoader::default() + .build_for_path(model_path("common_huashi666_i64.onnx")) + .expect("建立测试模型图失败"); + let metadata = ModelMetadata::from_builtin_beta( + false, + Resize::DynamicWidth(64), + 1, + Normalization::MinusOneToOne, + ); + let ocr = OcrRuntime::new(session, metadata); + + let inputs = ocr.input_info()?; + let outputs = ocr.output_info()?; + assert!(!inputs.is_empty(), "模型应有输入张量信息"); + assert!(!outputs.is_empty(), "模型应有输出张量信息"); + Ok(()) +} diff --git a/ddddocr-tract2/tests/slide.rs b/ddddocr-tract2/tests/slide.rs new file mode 100644 index 0000000..37ae13d --- /dev/null +++ b/ddddocr-tract2/tests/slide.rs @@ -0,0 +1,52 @@ +//! 滑块匹配集成测试。 + +mod common; + +use common::{load_image, sample_path}; +use ddddocr_core::Slider; + +/// 边缘模式匹配应定位到预期坐标。 +#[test] +fn slide_match_locates_target_position() { + let engine = Slider::new(); + let target = load_image(sample_path("target1.png")).expect("请确保 samples/target1.png 存在"); + let background = load_image(sample_path("background1.png")).expect("请确保 samples/background1.png 存在"); + + let start = std::time::Instant::now(); + let result = engine + .slide_match(&target, &background, false) + .expect("Slide match 执行失败"); + let elapsed = start.elapsed(); + + println!("边缘模式匹配: {result}"); + println!("耗时: {elapsed:?}"); + + assert_eq!(result.target_x, 237); + assert_eq!(result.target_y, 77); + assert!(result.confidence > 0.0); +} + +/// 灰度对比匹配应定位到预期坐标。 +#[test] +fn slide_comparison_locates_target_position() { + let engine = Slider::new(); + let target = load_image(sample_path("target2.jpg")).expect("请确保 samples/target2.jpg 存在"); + let background = + load_image(sample_path("background2.jpg")).expect("请确保 samples/background2.jpg 存在"); + + let start = std::time::Instant::now(); + let result = engine + .slide_comparison(&target, &background) + .expect("Slide comparison 执行失败"); + let elapsed = start.elapsed(); + + println!( + "灰度对比匹配: 坐标 [x: {}, y: {}], 置信度 {:.4}", + result.target_x, result.target_y, result.confidence + ); + println!("耗时: {elapsed:?}"); + + assert_eq!(result.target_x, 171); + assert_eq!(result.target_y, 90); + assert!(result.confidence > 0.0); +} diff --git a/samples/huatu.png b/samples/background1.png similarity index 100% rename from samples/huatu.png rename to samples/background1.png diff --git a/samples/kenyuan.jpg b/samples/background2.jpg similarity index 100% rename from samples/kenyuan.jpg rename to samples/background2.jpg diff --git a/samples/hua.png b/samples/target1.png similarity index 100% rename from samples/hua.png rename to samples/target1.png diff --git a/samples/ken.jpg b/samples/target2.jpg similarity index 100% rename from samples/ken.jpg rename to samples/target2.jpg