diff --git a/.gitignore b/.gitignore index 955d714..cb6273b 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ cmake_output.txt # Local runtime/test assets /3rd_party/ /images/ +/models/ /tessdata/ /tmp/ diff --git a/README.md b/README.md index d5c63e0..5f721e5 100644 --- a/README.md +++ b/README.md @@ -1,161 +1,196 @@ # op_ocr_engine -`op_ocr_engine` 是一个本地 OCR HTTP 服务。当前推荐使用 `ncnn + PP-OCRv5`,用于窗口截图识别、返回文字 bbox,并给 `op` 主项目做找字和点击坐标。 +`op_ocr_engine` 是给 `op/libop` 用的本地 OCR HTTP 服务。主程序是 C++ 版 `ocr_server.exe`,用 ncnn 跑 PaddleOCR/PP-OCR 模型,负责从窗口截图里识别文字并返回文字框。 -服务接口保持简单: +仓库只放代码、脚本和文档。OCR 模型文件比较大,不再提交到 GitHub,部署或本地调试时单独下载。 -- `GET /health` -- `GET /api/v1/version` -- `POST /api/v1/ocr` +## 服务约定 -## 1. 目录约定 - -推荐本地目录结构: +`libop` 通过 `SetOcrEngine` 选择 OCR 后端。现在保留三个名字: ```text -op_ocr_engine/ - 3rd_party/ - ncnn/ - x64/ - include/ - lib/ - x86/ - include/ - lib/ - arm64/ - include/ - lib/ - models/ - PP_OCRv5_mobile_det.param - PP_OCRv5_mobile_det.bin - PP_OCRv5_mobile_rec.param - PP_OCRv5_mobile_rec.bin - PP_LCNet_x0_25_textline_ori.param - PP_LCNet_x0_25_textline_ori.bin - ppocrv5_dict.txt - build.py - CMakeLists.txt - src/ - tests/ +tesseract -> http://127.0.0.1:8080/api/v1/ocr +paddle -> http://127.0.0.1:8081/api/v1/ocr +paddle_ncnn -> http://127.0.0.1:8082/api/v1/ocr ``` -这些目录不会提交到 Git: +`paddle_ncnn` 是本项目的主服务。这个名字的意思是:模型来自 PaddleOCR/PP-OCR,推理运行时是 ncnn。 -- `3rd_party/`:本机第三方依赖。 -- `build-vs*/`:CMake/Visual Studio 构建产物。 -- `images/`:本地测试图片。 +`libop` 里通常这样配置: -## 2. 第三方依赖 - -### 2.1 ncnn +```text +SetOcrEngine("paddle_ncnn", "", "") +``` -下载地址: +如果想完全绕开后端名,也可以直接传 URL: -- `https://github.com/Tencent/ncnn/releases` +```text +SetOcrEngine("", "", "--url=http://127.0.0.1:8082/api/v1/ocr --timeout=3000") +``` -Windows + VS2026/VS2022 推荐下载 VS2022 包: +端口分工不要混用: ```text -ncnn--windows-vs2022.zip +8080 Tesseract HTTP 服务 +8081 py_paddle_server,Python PaddleOCR 服务 +8082 ocr_server.exe,C++ ncnn 服务 ``` -如果只做本地静态链接,优先使用非 `shared` 包。`shared` 包会依赖额外 DLL,交付时需要一起带上。 +## 本地目录 -解压后把对应架构内容放到: +建议把运行时文件放在仓库内的本地目录里,但不要提交这些目录: ```text -op_ocr_engine/3rd_party/ncnn/x64 -op_ocr_engine/3rd_party/ncnn/x86 -op_ocr_engine/3rd_party/ncnn/arm64 +op_ocr_engine/ + 3rd_party/ # ncnn 预编译包,build.py 可自动准备 + build-vs2026-x64/ # 构建产物 + images/ # 本地测试图片 + models/ # OCR 模型,本机下载,不提交 GitHub + py_paddle_server/ + src/ + tests/ + build.py + CMakeLists.txt ``` -CMake 默认读取: +启动服务时建议显式传模型目录: -```cmake -NCNN_ROOT = /3rd_party/ncnn +```powershell +--model-dir models ``` -然后根据当前编译架构自动查找: +这样不依赖当前工作目录,也不依赖程序里保留的默认路径。 + +## 模型准备 + +模型下载: + +[https://mirrors.sdu.edu.cn/ncnn_modelzoo/liteocr/](https://mirrors.sdu.edu.cn/ncnn_modelzoo/liteocr/) + +也可以加 QQ 群 `743710486` 获取模型文件。 + +下载后放到本地 `models/` 目录。默认模型是 `small`。 + +PP-OCRv6 `tiny` 适合只关心速度的场景,比如快速扫按钮、菜单、标题这类界面文字。它启动和推理都比较轻,但遇到小字号、低对比度或密集文字时,稳定性不如 `small`。 + +`tiny` 必需文件: ```text -3rd_party/ncnn/x64/lib/cmake/ncnn/ncnnConfig.cmake -3rd_party/ncnn/x86/lib/cmake/ncnn/ncnnConfig.cmake -3rd_party/ncnn/arm64/lib/cmake/ncnn/ncnnConfig.cmake +models/ + PP-OCRv6_tiny_det.param + PP-OCRv6_tiny_det.bin + PP-OCRv6_tiny_rec.param + PP-OCRv6_tiny_rec.bin + PP-OCRv6_vocab_tiny.txt ``` -如果放在其他位置,可以构建时指定: +PP-OCRv6 `small` 是默认选择,适合 `libop` 日常找字、点按钮、读窗口文本。它比 `tiny` 稳一些,又不会像 `medium` 那样明显增加耗时,普通使用先选它。 -```powershell -python build.py --ncnn-root E:\path\to\ncnn +`small` 必需文件: + +```text +models/ + PP-OCRv6_small_det.param + PP-OCRv6_small_det.bin + PP-OCRv6_small_rec.param + PP-OCRv6_small_rec.bin + PP-OCRv6_vocab.txt ``` -### 2.2 C++ HTTP/JSON 依赖 +PP-OCRv6 `medium` 适合更看重识别质量的截图,比如小字比较多、背景复杂、文字挤在一起的页面。代价是模型更大,推理会比 `small` 慢一些。 + +`medium` 必需文件: -CMake 使用 `FetchContent` 拉取: +```text +models/ + PP-OCRv6_medium_det.param + PP-OCRv6_medium_det.bin + PP-OCRv6_medium_rec.param + PP-OCRv6_medium_rec.bin + PP-OCRv6_vocab.txt +``` -- `cpp-httplib` -- `nlohmann/json` +方向分类是通用可选项,用来处理倒置文字。常规窗口截图一般可以不放;如果遇到文字方向不稳定,再加这组模型。 -首次配置时需要能访问网络,或者提前准备好 CMake 的 `_deps` 缓存。 +可放: -### 2.3 Tesseract 可选依赖 +```text +models/ + PP-LCNet_x1_0_textline_ori.param + PP-LCNet_x1_0_textline_ori.bin +``` -Tesseract 现在是可选 backend。默认 `build.py` 会关闭 Tesseract,只构建 ncnn OCR 服务。 +表格结构识别不是当前 `ocr_server.exe` 的必需能力。只做文字识别、找字和点击坐标时,不需要下面这些文件。 -如需 Tesseract: +如果以后要把截图里的表格还原成 HTML 结构,才需要表格模型: -```powershell -python build.py --with-tesseract +```text +models/ + PP-StructrureV2_SLANet_plus_cnn.param + PP-StructrureV2_SLANet_plus_cnn.bin + PP-StructrureV2_SLANet_plus_slahead.param + PP-StructrureV2_SLANet_plus_slahead.bin + table_structure_dict_ch.txt ``` -这时需要本机能被 CMake 找到 `Tesseract::libtesseract`。 +如果只是识别表格单元格里的文字,仍然用 `tiny`、`small` 或 `medium`,不需要表格结构模型。 -## 3. OCR 模型 +PP-OCRv5 主要用于和历史模型结果做对比,或者在需要复现 v5 行为时使用。新场景优先用 PP-OCRv6。 -当前 ncnn backend 默认使用 PP-OCRv5 mobile 模型: +PP-OCRv5 不使用 `--quality`,需要显式指定版本和类型: -```text -PP_OCRv5_mobile_det.param -PP_OCRv5_mobile_det.bin -PP_OCRv5_mobile_rec.param -PP_OCRv5_mobile_rec.bin -PP_LCNet_x0_25_textline_ori.param -PP_LCNet_x0_25_textline_ori.bin -ppocrv5_dict.txt +```powershell +ocr_server.exe --model-dir models --model-version v5 --model-type mobile +ocr_server.exe --model-dir models --model-version v5 --model-type server ``` -放置路径: +PP-OCRv5 `mobile` 模型小,适合做兼容性对比或轻量回归: ```text -op_ocr_engine/models/ +models/ + PP-OCRv5_mobile_det.param + PP-OCRv5_mobile_det.bin + PP-OCRv5_mobile_rec.param + PP-OCRv5_mobile_rec.bin + PP-OCRv5_vocab.txt ``` -启动服务时默认按 `--model-dir models` 查找。 - -模型来源可以是: +PP-OCRv5 `server` 模型更大,适合对比 v5 的高精度版本: -- 自己从 PaddleOCR 官方模型转换为 ONNX,再转换为 ncnn。 -- 使用已转换好的 PP-OCRv5 ncnn 模型。 +```text +models/ + PP-OCRv5_server_det.param + PP-OCRv5_server_det.bin + PP-OCRv5_server_rec.param + PP-OCRv5_server_rec.bin + PP-OCRv5_vocab.txt +``` -仓库包含一套默认可用的 mobile 模型,便于拉取后直接构建和启动。替换模型时保持同名文件放在 `models/` 目录即可。 +注意:`build.py` 自动下载的是 ncnn 运行库,不是 OCR 模型。模型需要按上面的地址单独准备。 -## 4. 构建 +## 构建 -推荐使用仓库里的构建脚本: +Windows 下直接用构建脚本: ```powershell python build.py ``` -默认行为: +默认构建 C++ ncnn 服务: + +```text +Generator 自动检测 VS2026 / VS2022 +Arch x64 +Type Release +Target ocr_server +Tesseract OFF +Tests OFF +``` + +`build.py` 会检查 `3rd_party/ncnn`。如果缺少 ncnn,会下载默认的 Windows VS2022 预编译包: ```text -generator: 当前机器可用的 VS2026/VS2022 -arch: x64 -type: Release -target: ocr_server -Tesseract: OFF -Tests: OFF +ncnn-20260526-windows-vs2022.zip ``` 常用命令: @@ -164,79 +199,131 @@ Tests: OFF python build.py -g vs2026 -a x64 -t Release python build.py -g vs2022 -a x64 -t Release python build.py -g vs2026 -a x64 -t Release --clean -python build.py -g vs2026 -a x64 -t Release --target ocr_server +python build.py --no-ncnn-download +python build.py --ncnn-root E:\path\to\ncnn ``` -构建产物: +构建完成后,常用产物路径是: ```text -build-vs2026-x64/Release/ocr_server.exe -build-vs2022-x64/Release/ocr_server.exe +build-vs2026-x64\Release\ocr_server.exe +build-vs2022-x64\Release\ocr_server.exe ``` -也可以直接用 CMake: +Tesseract 是单独的 OCR 后端,默认不参与构建。需要时再打开: ```powershell -cmake -S . -B build-vs2026-x64 -G "Visual Studio 18 2026" -A x64 -DNCNN_ROOT=3rd_party/ncnn -DBUILD_TESSERACT_SERVER=OFF -DBUILD_TESTING=OFF -cmake --build build-vs2026-x64 --config Release --target ocr_server +python build.py --with-tesseract ``` -## 5. 启动服务 +这要求本机 CMake 能找到 `Tesseract::libtesseract`。 + +## 启动 -ncnn mobile: +日常启动默认使用 `small`: ```powershell -build-vs2026-x64\Release\ocr_server.exe --backend ncnn --model-dir models --model-type mobile --host 127.0.0.1 --port 8081 +ocr_server.exe --model-dir models ``` -ncnn server 模型,如果已准备对应模型文件: +也可以显式指定 PP-OCRv6 模型规格: ```powershell -build-vs2026-x64\Release\ocr_server.exe --backend ncnn --model-dir models --model-type server --host 127.0.0.1 --port 8081 +ocr_server.exe --model-dir models --model-type tiny +ocr_server.exe --model-dir models --model-type small +ocr_server.exe --model-dir models --model-type medium ``` -参数说明: +PP-OCRv5 用的是 `mobile` 和 `server` 两个规格,启动时写清楚版本: -- `--backend`:`auto` / `ncnn` / `tesseract`,默认 `auto`。 -- `--model-dir`:ncnn 模型目录,默认 `models`。 -- `--model-type`:`mobile` 或 `server`,默认 `mobile`。 -- `--use-vulkan`:启用 ncnn Vulkan,需 ncnn 包和运行环境支持。 -- `--host`:监听地址,默认 `0.0.0.0`。 -- `--port`:监听端口,默认 `8080`。 +```powershell +ocr_server.exe --model-dir models --model-version v5 --model-type mobile +ocr_server.exe --model-dir models --model-version v5 --model-type server +``` + +GPU 模式: + +```powershell +ocr_server.exe --model-dir models --model-type small --device gpu --gpu-device 0 +``` -Tesseract backend: +CPU 线程数: ```powershell -ocr_server.exe --backend tesseract --datapath tessdata --lang chi_sim --host 127.0.0.1 --port 8081 +ocr_server.exe --model-dir models --model-type small --threads 8 ``` -## 6. HTTP 协议 +快速模式: -### 6.1 健康检查 +```powershell +ocr_server.exe --model-dir models --model-type small --threads 8 --fast-mode +``` + +默认监听: ```text -GET /health +http://127.0.0.1:8082 ``` -响应: +常用参数: -```json -{ "status": "ok" } +```text +--model-dir 模型目录,建议显式传 models +--model-version 模型版本,v6 或 v5,默认 v6 +--model-type v6 用 tiny / small / medium,默认 small;v5 用 mobile / server +--device cpu / gpu,默认 cpu +--threads ncnn CPU 推理线程数,默认 4 +--fast-mode 跳过方向分类和 180 度回退识别,速度更快,但倒置文字鲁棒性会下降 +--host 默认 127.0.0.1 +--port 默认 8082 ``` -### 6.2 版本信息 +`--fast-mode` 和 `--quality fast` 不一样。`--quality fast` 是兼容别名,等价于选择 v6 `tiny` 模型;`--fast-mode` 不换模型,只是在识别流程里跳过方向分类模型和低置信度时的 180 度回退识别。 + +GUI 工具启动服务时也使用这些参数:模型版本传 `--model-version`,模型规格传 `--model-type`,线程档位传 `--threads`,勾选快速模式时额外传 `--fast-mode`。 + +调优和兼容参数: ```text -GET /api/v1/version +--quality 兼容别名:fast / balanced / accurate,对应 v6 tiny / small / medium;不要和 --model-version / --model-type 混用 +--use-vulkan 启用 ncnn Vulkan,等价于 --device gpu +--gpu-device Vulkan GPU 设备编号,GPU 模式默认 0 +--fp16 启用 ncnn FP16 arithmetic / storage / packing +--bf16 启用 ncnn BF16 storage / packing,适合做性能和精度对比 +--backend auto / ncnn / tesseract,默认 auto +--datapath Tesseract tessdata 目录,仅 --backend tesseract 需要 +--lang Tesseract 语言,默认 eng +``` + +开发调试参数可以看: + +```powershell +ocr_server.exe --help-advanced ``` -响应示例: +## HTTP 接口 + +服务提供三个接口: + +```text +GET /health +GET /api/v1/version +POST /api/v1/ocr +``` + +健康检查: + +```text +GET /health +``` + +响应: ```json -{ "version": "ncnn-ocr-service 1.0" } +{ "status": "ok" } ``` -### 6.3 OCR 识别 +OCR 请求使用 JSON,传的是原始像素字节的 Base64,不是 PNG/JPG 文件内容。 ```text POST /api/v1/ocr @@ -245,12 +332,12 @@ Content-Type: application/json 请求字段: -- `image`:原始像素字节的 Base64 字符串。 -- `width`:图像宽度。 -- `height`:图像高度。 -- `bpp`:每像素字节数,支持 `1`、`3`、`4`。 - -注意:接口接收的是原始像素字节,不是 PNG/JPG 文件本身。 +```text +image 原始像素字节的 Base64 字符串 +width 图像宽度 +height 图像高度 +bpp 每像素字节数,支持 1 / 3 / 4 +``` 成功响应示例: @@ -273,20 +360,20 @@ Content-Type: application/json } ``` -`bbox` 是图像坐标中的外接矩形: +`bbox` 是文字外接矩形: ```text [x1, y1, x2, y2] ``` -上层如果需要点击文字,通常使用中心点: +上层要点击文字时,一般取中心点: ```text cx = (x1 + x2) / 2 cy = (y1 + y2) / 2 ``` -## 7. Python 调用示例 +## Python 调用示例 ```python import base64 @@ -303,7 +390,7 @@ payload = { } request = urllib.request.Request( - "http://127.0.0.1:8081/api/v1/ocr", + "http://127.0.0.1:8082/api/v1/ocr", data=json.dumps(payload).encode("utf-8"), headers={"Content-Type": "application/json"}, method="POST", @@ -313,35 +400,45 @@ with urllib.request.urlopen(request, timeout=30) as response: print(response.read().decode("utf-8")) ``` -## 8. 测试和可视化工具 +## 测试工具 -基准测试: +接口压测: ```powershell -python tests\benchmark_ocr_server.py --url http://127.0.0.1:8081/api/v1/ocr --image-dir images --repeat 3 --concurrency 1 +python tests\benchmark_ocr_server.py --url http://127.0.0.1:8082/api/v1/ocr --image-dir images --repeat 3 --concurrency 1 ``` -bbox 可视化: +不同模型档位对比: ```powershell -python tests\visualize_ocr_bboxes.py --url http://127.0.0.1:8081/api/v1/ocr --image-dir images --output-dir build-vs2026-x64\ocr_bbox_visuals --show-text +python tests\benchmark_ncnn_models.py --model-dir models --image-dir images --repeat 3 --csv build-vs2026-x64\ncnn_model_benchmark.csv ``` -测试脚本只依赖 HTTP 接口,不参与 `ocr_server.exe` 编译。 +GPU 对比: -## 9. PaddleOCR Python 服务 +```powershell +python tests\benchmark_ncnn_models.py --model-dir models --use-vulkan --gpu-device 0 --threads 4 +``` -项目还保留了一个基于 FastAPI 的 PaddleOCR HTTP 服务: +bbox 可视化: -```text -py_paddle_server/app.py +```powershell +python tests\visualize_ocr_bboxes.py --url http://127.0.0.1:8082/api/v1/ocr --image-dir images --output-dir build-vs2026-x64\ocr_bbox_visuals --show-text ``` -启动示例: +## Python PaddleOCR 服务 + +`py_paddle_server/` 是保留下来的 Python PaddleOCR 服务,端口固定为 `8081`。它和 C++ 服务使用同一套 HTTP 协议,主要用于精度对比和回退验证。 + +启动: ```powershell pip install -r py_paddle_server\requirements.txt -uvicorn py_paddle_server.app:app --host 0.0.0.0 --port 8082 +uvicorn py_paddle_server.app:app --host 0.0.0.0 --port 8081 ``` -它的 HTTP 协议与 C++ 服务保持兼容,可用于和 ncnn 服务做精度对比。 +`libop` 切到 Python PaddleOCR: + +```text +SetOcrEngine("paddle", "", "") +``` diff --git a/build.py b/build.py index da56585..8a0b61f 100644 --- a/build.py +++ b/build.py @@ -10,12 +10,20 @@ import argparse import os +import re import shutil import subprocess import sys +import tempfile +import urllib.request +import zipfile from pathlib import Path +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(line_buffering=True) + + GENERATORS = { "vs2022": {"cmake": "Visual Studio 17 2022"}, "vs2026": {"cmake": "Visual Studio 18 2026"}, @@ -24,6 +32,12 @@ BUILD_TYPES = ("Debug", "Release", "RelWithDebInfo") ARCHITECTURES = ("x86", "x64") ARCH_TO_VS = {"x86": "Win32", "x64": "x64"} +NCNN_PACKAGE_ARCHITECTURES = ("x86", "x64", "arm64") +DEFAULT_NCNN_VERSION = "20260526" +DEFAULT_NCNN_URL = ( + "https://github.com/Tencent/ncnn/releases/download/20260526/" + "ncnn-20260526-windows-vs2022.zip" +) def find_vswhere() -> Path | None: @@ -134,6 +148,168 @@ def resolve_path(project_dir: Path, value: str) -> Path: return path if path.is_absolute() else (project_dir / path).resolve() +def ncnn_config_path(ncnn_root: Path, arch: str) -> Path: + return ncnn_root / arch / "lib" / "cmake" / "ncnn" / "ncnnConfig.cmake" + + +def ncnn_config_version_path(ncnn_root: Path, arch: str) -> Path: + return ncnn_root / arch / "lib" / "cmake" / "ncnn" / "ncnnConfigVersion.cmake" + + +def parse_cmake_set_values(path: Path) -> dict[str, str]: + values: dict[str, str] = {} + if not path.is_file(): + return values + + pattern = re.compile(r"^\s*set\(\s*([A-Za-z0-9_]+)\s+\"?([^\"\)]+)\"?\s*\)") + for line in path.read_text(encoding="utf-8", errors="ignore").splitlines(): + match = pattern.match(line) + if match: + values[match.group(1)] = match.group(2).strip() + return values + + +def detect_ncnn_info(ncnn_root: Path, arch: str) -> dict[str, str]: + config_values = parse_cmake_set_values(ncnn_config_path(ncnn_root, arch)) + version_values = parse_cmake_set_values(ncnn_config_version_path(ncnn_root, arch)) + shared = config_values.get("NCNN_SHARED_LIB", "unknown") + return { + "version": config_values.get("NCNN_VERSION") + or version_values.get("PACKAGE_VERSION") + or DEFAULT_NCNN_VERSION, + "vulkan": config_values.get("NCNN_VULKAN", "unknown"), + "shared": shared, + "linkage": "shared" if shared == "ON" else "static" if shared == "OFF" else "unknown", + } + + +def package_filename_from_url(url: str) -> str: + filename = url.rstrip("/").rsplit("/", 1)[-1] + return filename or f"ncnn-{DEFAULT_NCNN_VERSION}-windows-vs2022.zip" + + +def download_file(url: str, destination: Path) -> None: + destination.parent.mkdir(parents=True, exist_ok=True) + if destination.is_file(): + print(f"[INFO] Using cached ncnn package: {destination}") + return + + temp_destination = destination.with_suffix(destination.suffix + ".tmp") + if temp_destination.exists(): + temp_destination.unlink() + + print(f"[INFO] Downloading ncnn package: {url}") + progress = {"next_percent": 0} + + def report_progress(block_count: int, block_size: int, total_size: int) -> None: + if total_size <= 0: + return + downloaded = min(block_count * block_size, total_size) + percent = int(downloaded * 100 / total_size) + if percent >= progress["next_percent"]: + print(f"[INFO] ncnn download {percent}%") + progress["next_percent"] += 10 + + try: + urllib.request.urlretrieve(url, temp_destination, reporthook=report_progress) + temp_destination.replace(destination) + except Exception as exc: + if temp_destination.exists(): + temp_destination.unlink() + raise RuntimeError(f"Failed to download ncnn package: {exc}") from exc + + +def safe_extract_zip(archive_path: Path, destination: Path) -> None: + destination.mkdir(parents=True, exist_ok=True) + destination_root = destination.resolve() + + with zipfile.ZipFile(archive_path) as archive: + for member in archive.infolist(): + target = (destination_root / member.filename).resolve() + if target != destination_root and destination_root not in target.parents: + raise RuntimeError(f"Unsafe path in ncnn archive: {member.filename}") + archive.extractall(destination_root) + + +def find_extracted_ncnn_root(extract_dir: Path) -> Path | None: + for config in extract_dir.rglob("ncnnConfig.cmake"): + try: + arch_dir = config.parents[3] + package_root = config.parents[4] + except IndexError: + continue + + if ( + arch_dir.name in NCNN_PACKAGE_ARCHITECTURES + and config.parent.name == "ncnn" + and config.parent.parent.name == "cmake" + and config.parent.parent.parent.name == "lib" + ): + return package_root + return None + + +def install_ncnn_package(package_root: Path, ncnn_root: Path) -> None: + ncnn_root.mkdir(parents=True, exist_ok=True) + installed_arches: list[str] = [] + + for arch in NCNN_PACKAGE_ARCHITECTURES: + source = package_root / arch + if not source.is_dir(): + continue + target = ncnn_root / arch + print(f"[INFO] Installing ncnn {arch}: {target}") + if target.exists(): + shutil.rmtree(target) + shutil.copytree(source, target) + installed_arches.append(arch) + + if not installed_arches: + raise RuntimeError(f"No ncnn architecture directories found in {package_root}") + + +def ensure_ncnn_package(args: argparse.Namespace, ncnn_root: Path) -> None: + config_path = ncnn_config_path(ncnn_root, args.arch) + if config_path.is_file(): + info = detect_ncnn_info(ncnn_root, args.arch) + print( + "[INFO] ncnn found: " + f"version={info['version']} arch={args.arch} " + f"linkage={info['linkage']} vulkan={info['vulkan']}" + ) + print(f"[INFO] ncnn config: {config_path}") + return + + if args.no_ncnn_download: + print(f"[WARN] ncnn config is missing and auto-download is disabled: {config_path}") + return + + print(f"[INFO] ncnn package is missing for arch={args.arch}: {config_path}") + + url = DEFAULT_NCNN_URL + archive_path = ncnn_root / "_downloads" / package_filename_from_url(url) + download_file(url, archive_path) + + with tempfile.TemporaryDirectory(prefix="ncnn-extract-") as temp_dir: + extract_dir = Path(temp_dir) + safe_extract_zip(archive_path, extract_dir) + package_root = find_extracted_ncnn_root(extract_dir) + if package_root is None: + raise RuntimeError(f"Could not locate ncnnConfig.cmake inside {archive_path}") + install_ncnn_package(package_root, ncnn_root) + + if not config_path.is_file(): + raise RuntimeError(f"ncnn package was installed, but config is still missing: {config_path}") + + info = detect_ncnn_info(ncnn_root, args.arch) + print( + "[INFO] ncnn ready: " + f"version={info['version']} arch={args.arch} " + f"linkage={info['linkage']} vulkan={info['vulkan']}" + ) + print(f"[INFO] ncnn config: {config_path}") + + def main() -> int: detected_default_generator = default_generator_key() parser = argparse.ArgumentParser(description="Build op_ocr_engine with Visual Studio CMake generators.") @@ -149,12 +325,23 @@ def main() -> int: default="3rd_party/ncnn", help="Path to the prebuilt ncnn package root.", ) + parser.add_argument( + "--no-ncnn-download", + action="store_true", + help="Do not auto-download the default prebuilt ncnn package when it is missing.", + ) args = parser.parse_args() ensure_cmake_on_path() project_dir = Path(__file__).parent.resolve() ncnn_root = resolve_path(project_dir, args.ncnn_root) + try: + ensure_ncnn_package(args, ncnn_root) + except RuntimeError as exc: + print(f"[ERROR] {exc}") + return 1 + generator = GENERATORS[args.generator]["cmake"] vs_arch = ARCH_TO_VS[args.arch] build_dir = project_dir / f"build-{args.generator}-{args.arch}" diff --git a/models/PP_LCNet_x0_25_textline_ori.bin b/models/PP_LCNet_x0_25_textline_ori.bin deleted file mode 100644 index d7f5d18..0000000 Binary files a/models/PP_LCNet_x0_25_textline_ori.bin and /dev/null differ diff --git a/models/PP_LCNet_x0_25_textline_ori.param b/models/PP_LCNet_x0_25_textline_ori.param deleted file mode 100644 index 1607929..0000000 --- a/models/PP_LCNet_x0_25_textline_ori.param +++ /dev/null @@ -1,79 +0,0 @@ -7767517 -77 79 -Input input 0 1 input -Convolution conv_36 1 1 input 1 0=8 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=216 -HardSwish hswish_5 1 1 1 2 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_60 1 1 2 3 0=8 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=72 7=8 -HardSwish hswish_6 1 1 3 4 0=0.166667 1=0.5 -Convolution conv_37 1 1 4 5 0=8 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=64 -HardSwish hswish_7 1 1 5 6 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_61 1 1 6 7 0=8 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=72 7=8 -HardSwish hswish_8 1 1 7 8 0=0.166667 1=0.5 -Convolution conv_38 1 1 8 9 0=16 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=128 -HardSwish hswish_9 1 1 9 10 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_62 1 1 10 11 0=16 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=144 7=16 -HardSwish hswish_10 1 1 11 12 0=0.166667 1=0.5 -Convolution conv_39 1 1 12 13 0=16 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=256 -HardSwish hswish_11 1 1 13 14 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_63 1 1 14 15 0=16 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=144 7=16 -HardSwish hswish_12 1 1 15 16 0=0.166667 1=0.5 -Convolution conv_40 1 1 16 17 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=512 -HardSwish hswish_13 1 1 17 18 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_64 1 1 18 19 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=288 7=32 -HardSwish hswish_14 1 1 19 20 0=0.166667 1=0.5 -Convolution conv_41 1 1 20 21 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=1024 -HardSwish hswish_15 1 1 21 22 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_65 1 1 22 23 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=288 7=32 -HardSwish hswish_16 1 1 23 24 0=0.166667 1=0.5 -Convolution conv_42 1 1 24 25 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2048 -HardSwish hswish_17 1 1 25 26 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_66 1 1 26 27 0=64 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_18 1 1 27 28 0=0.166667 1=0.5 -Convolution conv_43 1 1 28 29 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_19 1 1 29 30 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_67 1 1 30 31 0=64 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_20 1 1 31 32 0=0.166667 1=0.5 -Convolution conv_44 1 1 32 33 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_21 1 1 33 34 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_68 1 1 34 35 0=64 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_22 1 1 35 36 0=0.166667 1=0.5 -Convolution conv_45 1 1 36 37 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_23 1 1 37 38 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_69 1 1 38 39 0=64 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_24 1 1 39 40 0=0.166667 1=0.5 -Convolution conv_46 1 1 40 41 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_25 1 1 41 42 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_70 1 1 42 43 0=64 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_26 1 1 43 44 0=0.166667 1=0.5 -Convolution conv_47 1 1 44 45 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_27 1 1 45 46 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_71 1 1 46 47 0=64 1=5 11=5 12=1 13=2 14=2 2=1 3=1 4=2 5=1 6=1600 7=64 -HardSwish hswish_28 1 1 47 48 0=0.166667 1=0.5 -Split splitncnn_0 1 2 48 49 50 -Pooling gap_0 1 1 50 51 0=1 4=1 -Convolution convrelu_0 1 1 51 52 0=16 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=1024 9=1 -Convolution conv_49 1 1 52 53 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=1024 -HardSigmoid hsigmoid_3 1 1 53 54 0=0.166667 1=0.5 -Reshape reshape_56 1 1 54 55 0=1 1=1 2=-1 -BinaryOp mul_0 2 1 49 55 56 0=2 -Convolution conv_50 1 1 56 57 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=8192 -HardSwish hswish_29 1 1 57 58 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_72 1 1 58 59 0=128 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=3200 7=128 -HardSwish hswish_30 1 1 59 60 0=0.166667 1=0.5 -Split splitncnn_1 1 2 60 61 62 -Pooling gap_1 1 1 62 63 0=1 4=1 -Convolution convrelu_1 1 1 63 64 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 9=1 -Convolution conv_52 1 1 64 65 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSigmoid hsigmoid_4 1 1 65 66 0=0.166667 1=0.5 -Reshape reshape_57 1 1 66 67 0=1 1=1 2=-1 -BinaryOp mul_1 2 1 61 67 68 0=2 -Convolution conv_53 1 1 68 69 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 -HardSwish hswish_31 1 1 69 70 0=0.166667 1=0.5 -Pooling gap_2 1 1 70 71 0=1 4=1 -Convolution conv_54 1 1 71 72 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=163840 -HardSwish hswish_32 1 1 72 73 0=0.166667 1=0.5 -Reshape reshape_58 1 1 73 74 0=1 1=1 2=-1 -BinaryOp mul_2 1 1 74 75 0=2 1=1 2=0.8 -Reshape reshape_59 1 1 75 76 0=1280 -InnerProduct linear_55 1 1 76 77 0=2 1=1 2=2560 -Softmax softmax_35 1 1 77 output 0=0 1=1 diff --git a/models/PP_LCNet_x1_0_textline_ori.bin b/models/PP_LCNet_x1_0_textline_ori.bin deleted file mode 100644 index 909300e..0000000 Binary files a/models/PP_LCNet_x1_0_textline_ori.bin and /dev/null differ diff --git a/models/PP_LCNet_x1_0_textline_ori.param b/models/PP_LCNet_x1_0_textline_ori.param deleted file mode 100644 index 77a5aa9..0000000 --- a/models/PP_LCNet_x1_0_textline_ori.param +++ /dev/null @@ -1,79 +0,0 @@ -7767517 -77 79 -Input input 0 1 input -Convolution conv_36 1 1 input 1 0=16 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 -HardSwish hswish_5 1 1 1 2 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_60 1 1 2 3 0=16 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=144 7=16 -HardSwish hswish_6 1 1 3 4 0=0.166667 1=0.5 -Convolution conv_37 1 1 4 5 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=512 -HardSwish hswish_7 1 1 5 6 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_61 1 1 6 7 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=288 7=32 -HardSwish hswish_8 1 1 7 8 0=0.166667 1=0.5 -Convolution conv_38 1 1 8 9 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2048 -HardSwish hswish_9 1 1 9 10 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_62 1 1 10 11 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=576 7=64 -HardSwish hswish_10 1 1 11 12 0=0.166667 1=0.5 -Convolution conv_39 1 1 12 13 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -HardSwish hswish_11 1 1 13 14 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_63 1 1 14 15 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=576 7=64 -HardSwish hswish_12 1 1 15 16 0=0.166667 1=0.5 -Convolution conv_40 1 1 16 17 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=8192 -HardSwish hswish_13 1 1 17 18 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_64 1 1 18 19 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=1152 7=128 -HardSwish hswish_14 1 1 19 20 0=0.166667 1=0.5 -Convolution conv_41 1 1 20 21 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 -HardSwish hswish_15 1 1 21 22 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_65 1 1 22 23 0=128 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=1152 7=128 -HardSwish hswish_16 1 1 23 24 0=0.166667 1=0.5 -Convolution conv_42 1 1 24 25 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=32768 -HardSwish hswish_17 1 1 25 26 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_66 1 1 26 27 0=256 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_18 1 1 27 28 0=0.166667 1=0.5 -Convolution conv_43 1 1 28 29 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSwish hswish_19 1 1 29 30 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_67 1 1 30 31 0=256 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_20 1 1 31 32 0=0.166667 1=0.5 -Convolution conv_44 1 1 32 33 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSwish hswish_21 1 1 33 34 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_68 1 1 34 35 0=256 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_22 1 1 35 36 0=0.166667 1=0.5 -Convolution conv_45 1 1 36 37 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSwish hswish_23 1 1 37 38 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_69 1 1 38 39 0=256 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_24 1 1 39 40 0=0.166667 1=0.5 -Convolution conv_46 1 1 40 41 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSwish hswish_25 1 1 41 42 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_70 1 1 42 43 0=256 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_26 1 1 43 44 0=0.166667 1=0.5 -Convolution conv_47 1 1 44 45 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSwish hswish_27 1 1 45 46 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_71 1 1 46 47 0=256 1=5 11=5 12=1 13=2 14=2 2=1 3=1 4=2 5=1 6=6400 7=256 -HardSwish hswish_28 1 1 47 48 0=0.166667 1=0.5 -Split splitncnn_0 1 2 48 49 50 -Pooling gap_0 1 1 50 51 0=1 4=1 -Convolution convrelu_0 1 1 51 52 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 9=1 -Convolution conv_49 1 1 52 53 0=256 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 -HardSigmoid hsigmoid_3 1 1 53 54 0=0.166667 1=0.5 -Reshape reshape_56 1 1 54 55 0=1 1=1 2=-1 -BinaryOp mul_0 2 1 49 55 56 0=2 -Convolution conv_50 1 1 56 57 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=131072 -HardSwish hswish_29 1 1 57 58 0=0.166667 1=0.5 -ConvolutionDepthWise convdw_72 1 1 58 59 0=512 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=12800 7=512 -HardSwish hswish_30 1 1 59 60 0=0.166667 1=0.5 -Split splitncnn_1 1 2 60 61 62 -Pooling gap_1 1 1 62 63 0=1 4=1 -Convolution convrelu_1 1 1 63 64 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 9=1 -Convolution conv_52 1 1 64 65 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=65536 -HardSigmoid hsigmoid_4 1 1 65 66 0=0.166667 1=0.5 -Reshape reshape_57 1 1 66 67 0=1 1=1 2=-1 -BinaryOp mul_1 2 1 61 67 68 0=2 -Convolution conv_53 1 1 68 69 0=512 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=262144 -HardSwish hswish_31 1 1 69 70 0=0.166667 1=0.5 -Pooling gap_2 1 1 70 71 0=1 4=1 -Convolution conv_54 1 1 71 72 0=1280 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=655360 -HardSwish hswish_32 1 1 72 73 0=0.166667 1=0.5 -Reshape reshape_58 1 1 73 74 0=1 1=1 2=-1 -BinaryOp mul_2 1 1 74 75 0=2 1=1 2=0.8 -Reshape reshape_59 1 1 75 76 0=1280 -InnerProduct linear_55 1 1 76 77 0=2 1=1 2=2560 -Softmax softmax_35 1 1 77 output 0=0 1=1 diff --git a/models/PP_OCRv5_mobile_det.bin b/models/PP_OCRv5_mobile_det.bin deleted file mode 100644 index a96b420..0000000 Binary files a/models/PP_OCRv5_mobile_det.bin and /dev/null differ diff --git a/models/PP_OCRv5_mobile_det.param b/models/PP_OCRv5_mobile_det.param deleted file mode 100644 index 8f2b114..0000000 --- a/models/PP_OCRv5_mobile_det.param +++ /dev/null @@ -1,279 +0,0 @@ -7767517 -277 301 -Input input 0 1 input -Convolution conv_63 1 1 input 1 0=16 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 -ConvolutionDepthWise convdw_123 1 1 1 2 0=16 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=144 7=16 -BinaryOp mul_0 1 1 2 3 0=2 1=1 2=1.2126 -BinaryOp add_1 1 1 3 4 0=0 1=1 2=0.46886 -HardSwish hswish_20 1 1 4 5 0=0.166667 1=0.5 -BinaryOp mul_2 1 1 5 6 0=2 1=1 2=0.00523472 -BinaryOp add_3 1 1 6 7 0=0 1=1 2=0.000237282 -Convolution conv_64 1 1 7 8 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=512 -BinaryOp mul_4 1 1 8 9 0=2 1=1 2=1.88755 -BinaryOp add_5 1 1 9 10 0=0 1=1 2=0.718749 -HardSwish hswish_21 1 1 10 11 0=0.166667 1=0.5 -BinaryOp mul_6 1 1 11 12 0=2 1=1 2=0.677513 -BinaryOp add_7 1 1 12 13 0=0 1=1 2=-0.229148 -ConvolutionDepthWise convdw_124 1 1 13 14 0=32 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=288 7=32 -BinaryOp mul_8 1 1 14 15 0=2 1=1 2=0.00517491 -BinaryOp add_9 1 1 15 16 0=0 1=1 2=0.000369573 -Convolution conv_65 1 1 16 17 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=1536 -BinaryOp mul_10 1 1 17 18 0=2 1=1 2=0.882177 -BinaryOp add_11 1 1 18 19 0=0 1=1 2=1.72146 -HardSwish hswish_22 1 1 19 20 0=0.166667 1=0.5 -BinaryOp mul_12 1 1 20 21 0=2 1=1 2=0.367713 -BinaryOp add_13 1 1 21 22 0=0 1=1 2=-0.871138 -ConvolutionDepthWise convdw_125 1 1 22 23 0=48 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=432 7=48 -BinaryOp mul_14 1 1 23 24 0=2 1=1 2=2.4128 -BinaryOp add_15 1 1 24 25 0=0 1=1 2=0.39553 -HardSwish hswish_23 1 1 25 26 0=0.166667 1=0.5 -BinaryOp mul_16 1 1 26 27 0=2 1=1 2=0.00590227 -BinaryOp add_17 1 1 27 28 0=0 1=1 2=-3.078864e-05 -Convolution conv_66 1 1 28 29 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 -BinaryOp mul_18 1 1 29 30 0=2 1=1 2=1.33334 -BinaryOp add_19 1 1 30 31 0=0 1=1 2=0.855694 -HardSwish hswish_24 1 1 31 32 0=0.166667 1=0.5 -BinaryOp mul_20 1 1 32 33 0=2 1=1 2=1.49892 -BinaryOp add_21 1 1 33 34 0=0 1=1 2=-0.555021 -Split splitncnn_0 1 2 34 35 36 -ConvolutionDepthWise convdw_126 1 1 36 37 0=48 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 7=48 -BinaryOp mul_22 1 1 37 38 0=2 1=1 2=0.00354538 -BinaryOp add_23 1 1 38 39 0=0 1=1 2=-0.000263411 -Convolution conv_67 1 1 39 40 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4608 -BinaryOp mul_24 1 1 40 41 0=2 1=1 2=0.611824 -BinaryOp add_25 1 1 41 42 0=0 1=1 2=1.89251 -HardSwish hswish_25 1 1 42 43 0=0.166667 1=0.5 -BinaryOp mul_26 1 1 43 44 0=2 1=1 2=0.558389 -BinaryOp add_27 1 1 44 45 0=0 1=1 2=-0.95102 -ConvolutionDepthWise convdw_127 1 1 45 46 0=96 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=864 7=96 -BinaryOp mul_28 1 1 46 47 0=2 1=1 2=1.17258 -BinaryOp add_29 1 1 47 48 0=0 1=1 2=0.541325 -HardSwish hswish_26 1 1 48 49 0=0.166667 1=0.5 -BinaryOp mul_30 1 1 49 50 0=2 1=1 2=0.0967831 -BinaryOp add_31 1 1 50 51 0=0 1=1 2=2.480455e-05 -Convolution conv_68 1 1 51 52 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 -BinaryOp mul_32 1 1 52 53 0=2 1=1 2=0.908592 -BinaryOp add_33 1 1 53 54 0=0 1=1 2=-0.0670728 -HardSwish hswish_27 1 1 54 55 0=0.166667 1=0.5 -BinaryOp mul_34 1 1 55 56 0=2 1=1 2=1.54173 -BinaryOp add_35 1 1 56 57 0=0 1=1 2=-0.0574839 -Split splitncnn_1 1 2 57 58 59 -ConvolutionDepthWise convdw_128 1 1 59 60 0=96 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=864 7=96 -BinaryOp mul_36 1 1 60 61 0=2 1=1 2=0.00251429 -BinaryOp add_37 1 1 61 62 0=0 1=1 2=0.000520503 -Convolution conv_69 1 1 62 63 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=18432 -BinaryOp mul_38 1 1 63 64 0=2 1=1 2=0.778889 -BinaryOp add_39 1 1 64 65 0=0 1=1 2=1.38154 -HardSwish hswish_28 1 1 65 66 0=0.166667 1=0.5 -BinaryOp mul_40 1 1 66 67 0=2 1=1 2=0.653882 -BinaryOp add_41 1 1 67 68 0=0 1=1 2=-0.815451 -ConvolutionDepthWise convdw_129 1 1 68 69 0=192 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=4800 7=192 -BinaryOp mul_42 1 1 69 70 0=2 1=1 2=1.06083 -BinaryOp add_43 1 1 70 71 0=0 1=1 2=0.365644 -HardSwish hswish_29 1 1 71 72 0=0.166667 1=0.5 -BinaryOp mul_44 1 1 72 73 0=2 1=1 2=0.00462354 -BinaryOp add_45 1 1 73 74 0=0 1=1 2=0.000703441 -Convolution conv_70 1 1 74 75 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 -BinaryOp mul_46 1 1 75 76 0=2 1=1 2=1.12273 -BinaryOp add_47 1 1 76 77 0=0 1=1 2=0.467123 -HardSwish hswish_30 1 1 77 78 0=0.166667 1=0.5 -BinaryOp mul_48 1 1 78 79 0=2 1=1 2=0.790457 -BinaryOp add_49 1 1 79 80 0=0 1=1 2=-0.113252 -ConvolutionDepthWise convdw_130 1 1 80 81 0=192 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=4800 7=192 -BinaryOp mul_50 1 1 81 82 0=2 1=1 2=1.07921 -BinaryOp add_51 1 1 82 83 0=0 1=1 2=0.895926 -HardSwish hswish_31 1 1 83 84 0=0.166667 1=0.5 -BinaryOp mul_52 1 1 84 85 0=2 1=1 2=0.0269234 -BinaryOp add_53 1 1 85 86 0=0 1=1 2=-0.000272939 -Convolution conv_71 1 1 86 87 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 -BinaryOp mul_54 1 1 87 88 0=2 1=1 2=1.02658 -BinaryOp add_55 1 1 88 89 0=0 1=1 2=0.0792048 -HardSwish hswish_32 1 1 89 90 0=0.166667 1=0.5 -BinaryOp mul_56 1 1 90 91 0=2 1=1 2=0.729764 -BinaryOp add_57 1 1 91 92 0=0 1=1 2=0.0485918 -ConvolutionDepthWise convdw_131 1 1 92 93 0=192 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=4800 7=192 -BinaryOp mul_58 1 1 93 94 0=2 1=1 2=0.908857 -BinaryOp add_59 1 1 94 95 0=0 1=1 2=0.894915 -HardSwish hswish_33 1 1 95 96 0=0.166667 1=0.5 -BinaryOp mul_60 1 1 96 97 0=2 1=1 2=0.00505481 -BinaryOp add_61 1 1 97 98 0=0 1=1 2=0.000966824 -Convolution conv_72 1 1 98 99 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 -BinaryOp mul_62 1 1 99 100 0=2 1=1 2=1.16184 -BinaryOp add_63 1 1 100 101 0=0 1=1 2=-0.0963788 -HardSwish hswish_34 1 1 101 102 0=0.166667 1=0.5 -BinaryOp mul_64 1 1 102 103 0=2 1=1 2=0.821648 -BinaryOp add_65 1 1 103 104 0=0 1=1 2=0.177517 -ConvolutionDepthWise convdw_132 1 1 104 105 0=192 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=4800 7=192 -BinaryOp mul_66 1 1 105 106 0=2 1=1 2=0.876167 -BinaryOp add_67 1 1 106 107 0=0 1=1 2=1.14574 -HardSwish hswish_35 1 1 107 108 0=0.166667 1=0.5 -BinaryOp mul_68 1 1 108 109 0=2 1=1 2=0.00791641 -BinaryOp add_69 1 1 109 110 0=0 1=1 2=0.000933445 -Convolution conv_73 1 1 110 111 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 -BinaryOp mul_70 1 1 111 112 0=2 1=1 2=0.891313 -BinaryOp add_71 1 1 112 113 0=0 1=1 2=-0.904133 -HardSwish hswish_36 1 1 113 114 0=0.166667 1=0.5 -BinaryOp mul_72 1 1 114 115 0=2 1=1 2=1.36137 -BinaryOp add_73 1 1 115 116 0=0 1=1 2=0.18225 -Split splitncnn_2 1 2 116 117 118 -ConvolutionDepthWise convdw_133 1 1 118 119 0=192 1=5 11=5 12=1 13=2 14=2 2=1 3=2 4=2 5=1 6=4800 7=192 -BinaryOp mul_74 1 1 119 120 0=2 1=1 2=0.703518 -BinaryOp add_75 1 1 120 121 0=0 1=1 2=-0.0966372 -Split splitncnn_3 1 2 121 122 123 -Pooling gap_0 1 1 123 124 0=1 4=1 -Convolution convrelu_0 1 1 124 125 0=48 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 9=1 -Convolution conv_75 1 1 125 126 0=192 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=9216 -HardSigmoid hsigmoid_10 1 1 126 127 0=0.166667 1=0.5 -Reshape reshape_113 1 1 127 128 0=1 1=1 2=-1 -BinaryOp mul_76 2 1 122 128 129 0=2 -Convolution conv_76 1 1 129 130 0=384 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=73728 -BinaryOp mul_77 1 1 130 131 0=2 1=1 2=1.1775 -BinaryOp add_78 1 1 131 132 0=0 1=1 2=0.0251325 -HardSwish hswish_37 1 1 132 133 0=0.166667 1=0.5 -BinaryOp mul_79 1 1 133 134 0=2 1=1 2=0.967964 -BinaryOp add_80 1 1 134 135 0=0 1=1 2=0.137993 -ConvolutionDepthWise convdw_134 1 1 135 136 0=384 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=9600 7=384 -BinaryOp mul_81 1 1 136 137 0=2 1=1 2=1.55538 -BinaryOp add_82 1 1 137 138 0=0 1=1 2=0.833365 -HardSwish hswish_38 1 1 138 139 0=0.166667 1=0.5 -BinaryOp mul_83 1 1 139 140 0=2 1=1 2=1.25352 -BinaryOp add_84 1 1 140 141 0=0 1=1 2=-1.03515 -Split splitncnn_4 1 2 141 142 143 -Pooling gap_1 1 1 143 144 0=1 4=1 -Convolution convrelu_1 1 1 144 145 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 9=1 -Convolution conv_78 1 1 145 146 0=384 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=36864 -HardSigmoid hsigmoid_11 1 1 146 147 0=0.166667 1=0.5 -Reshape reshape_114 1 1 147 148 0=1 1=1 2=-1 -BinaryOp mul_85 2 1 142 148 149 0=2 -Convolution conv_79 1 1 149 150 0=384 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=147456 -BinaryOp mul_86 1 1 150 151 0=2 1=1 2=0.875972 -BinaryOp add_87 1 1 151 152 0=0 1=1 2=-0.535566 -HardSwish hswish_39 1 1 152 153 0=0.166667 1=0.5 -BinaryOp mul_88 1 1 153 154 0=2 1=1 2=0.919406 -BinaryOp add_89 1 1 154 155 0=0 1=1 2=0.258226 -ConvolutionDepthWise convdw_135 1 1 155 156 0=384 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=9600 7=384 -BinaryOp mul_90 1 1 156 157 0=2 1=1 2=0.946459 -BinaryOp add_91 1 1 157 158 0=0 1=1 2=0.709349 -HardSwish hswish_40 1 1 158 159 0=0.166667 1=0.5 -BinaryOp mul_92 1 1 159 160 0=2 1=1 2=0.146162 -BinaryOp add_93 1 1 160 161 0=0 1=1 2=-0.000106434 -Convolution conv_80 1 1 161 162 0=384 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=147456 -BinaryOp mul_94 1 1 162 163 0=2 1=1 2=0.904013 -BinaryOp add_95 1 1 163 164 0=0 1=1 2=-0.294733 -HardSwish hswish_41 1 1 164 165 0=0.166667 1=0.5 -BinaryOp mul_96 1 1 165 166 0=2 1=1 2=0.935939 -BinaryOp add_97 1 1 166 167 0=0 1=1 2=0.165901 -ConvolutionDepthWise convdw_136 1 1 167 168 0=384 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=9600 7=384 -BinaryOp mul_98 1 1 168 169 0=2 1=1 2=1.01925 -BinaryOp add_99 1 1 169 170 0=0 1=1 2=0.408163 -HardSwish hswish_42 1 1 170 171 0=0.166667 1=0.5 -BinaryOp mul_100 1 1 171 172 0=2 1=1 2=0.169525 -BinaryOp add_101 1 1 172 173 0=0 1=1 2=-6.227764e-05 -Convolution conv_81 1 1 173 174 0=384 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=147456 -BinaryOp mul_102 1 1 174 175 0=2 1=1 2=0.62516 -BinaryOp add_103 1 1 175 176 0=0 1=1 2=-1.13659 -HardSwish hswish_43 1 1 176 177 0=0.166667 1=0.5 -BinaryOp mul_104 1 1 177 178 0=2 1=1 2=4.53756 -BinaryOp add_105 1 1 178 179 0=0 1=1 2=1.28809 -Convolution conv_82 1 1 35 180 0=12 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=576 -Convolution conv_83 1 1 58 181 0=18 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=1728 -Convolution conv_84 1 1 117 182 0=42 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=8064 -Convolution conv_85 1 1 179 183 0=360 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=138240 -Convolution conv_86 1 1 183 184 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=34560 -Split splitncnn_5 1 3 184 185 186 187 -Pooling gap_2 1 1 187 188 0=1 4=1 -Convolution convrelu_2 1 1 188 189 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1 -Convolution conv_88 1 1 189 190 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 -Reshape reshape_115 1 1 190 191 0=1 1=1 2=-1 -BinaryOp mul_106 1 1 191 192 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_12 1 1 192 193 0=0.166667 1=0.5 -BinaryOp mul_107 2 1 185 193 194 0=2 -BinaryOp add_108 2 1 186 194 195 0=0 -Split splitncnn_6 1 2 195 196 197 -Convolution conv_89 1 1 182 198 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=4032 -Split splitncnn_7 1 3 198 199 200 201 -Pooling gap_3 1 1 201 202 0=1 4=1 -Convolution convrelu_3 1 1 202 203 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1 -Convolution conv_91 1 1 203 204 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 -Reshape reshape_116 1 1 204 205 0=1 1=1 2=-1 -BinaryOp mul_109 1 1 205 206 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_13 1 1 206 207 0=0.166667 1=0.5 -Convolution conv_92 1 1 181 208 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=1728 -Split splitncnn_8 1 3 208 209 210 211 -Pooling gap_4 1 1 211 212 0=1 4=1 -Convolution convrelu_4 1 1 212 213 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1 -Convolution conv_94 1 1 213 214 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 -Reshape reshape_117 1 1 214 215 0=1 1=1 2=-1 -BinaryOp mul_110 1 1 215 216 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_14 1 1 216 217 0=0.166667 1=0.5 -Convolution conv_95 1 1 180 218 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=0 6=1152 -Split splitncnn_9 1 3 218 219 220 221 -Pooling gap_5 1 1 221 222 0=1 4=1 -Convolution convrelu_5 1 1 222 223 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 9=1 -Convolution conv_97 1 1 223 224 0=96 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2304 -Reshape reshape_118 1 1 224 225 0=1 1=1 2=-1 -BinaryOp mul_111 1 1 225 226 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_15 1 1 226 227 0=0.166667 1=0.5 -Interp interpolate_44 1 1 196 228 0=1 1=2.0 2=2.0 6=0 -BinaryOp mul_112 2 1 199 207 229 0=2 -BinaryOp add_113 2 1 200 229 230 0=0 -BinaryOp add_114 2 1 230 228 231 0=0 -Split splitncnn_10 1 2 231 232 233 -Interp interpolate_45 1 1 232 234 0=1 1=2.0 2=2.0 6=0 -BinaryOp mul_115 2 1 209 217 235 0=2 -BinaryOp add_116 2 1 210 235 236 0=0 -BinaryOp add_117 2 1 236 234 237 0=0 -Split splitncnn_11 1 2 237 238 239 -Interp interpolate_46 1 1 238 240 0=1 1=2.0 2=2.0 6=0 -BinaryOp mul_118 2 1 219 227 241 0=2 -BinaryOp add_119 2 1 220 241 242 0=0 -BinaryOp add_120 2 1 242 240 243 0=0 -Convolution conv_98 1 1 197 244 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=0 6=20736 -Split splitncnn_12 1 3 244 245 246 247 -Pooling gap_6 1 1 247 248 0=1 4=1 -Convolution convrelu_6 1 1 248 249 0=6 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 9=1 -Convolution conv_100 1 1 249 250 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 -Reshape reshape_119 1 1 250 251 0=1 1=1 2=-1 -BinaryOp mul_121 1 1 251 252 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_16 1 1 252 253 0=0.166667 1=0.5 -BinaryOp mul_122 2 1 245 253 254 0=2 -BinaryOp add_123 2 1 246 254 255 0=0 -Convolution conv_101 1 1 233 256 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=0 6=20736 -Split splitncnn_13 1 3 256 257 258 259 -Pooling gap_7 1 1 259 260 0=1 4=1 -Convolution convrelu_7 1 1 260 261 0=6 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 9=1 -Convolution conv_103 1 1 261 262 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 -Reshape reshape_120 1 1 262 263 0=1 1=1 2=-1 -BinaryOp mul_124 1 1 263 264 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_17 1 1 264 265 0=0.166667 1=0.5 -BinaryOp mul_125 2 1 257 265 266 0=2 -BinaryOp add_126 2 1 258 266 267 0=0 -Convolution conv_104 1 1 239 268 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=0 6=20736 -Split splitncnn_14 1 3 268 269 270 271 -Pooling gap_8 1 1 271 272 0=1 4=1 -Convolution convrelu_8 1 1 272 273 0=6 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 9=1 -Convolution conv_106 1 1 273 274 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 -Reshape reshape_121 1 1 274 275 0=1 1=1 2=-1 -BinaryOp mul_127 1 1 275 276 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_18 1 1 276 277 0=0.166667 1=0.5 -BinaryOp mul_128 2 1 269 277 278 0=2 -BinaryOp add_129 2 1 270 278 279 0=0 -Convolution conv_107 1 1 243 280 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=0 6=20736 -Split splitncnn_15 1 3 280 281 282 283 -Pooling gap_9 1 1 283 284 0=1 4=1 -Convolution convrelu_9 1 1 284 285 0=6 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 9=1 -Convolution conv_109 1 1 285 286 0=24 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=144 -Reshape reshape_122 1 1 286 287 0=1 1=1 2=-1 -BinaryOp mul_130 1 1 287 288 0=2 1=1 2=1.2 -HardSigmoid hsigmoid_19 1 1 288 289 0=0.166667 1=0.5 -BinaryOp mul_131 2 1 281 289 290 0=2 -BinaryOp add_132 2 1 282 290 291 0=0 -Interp interpolate_47 1 1 255 292 0=1 1=8.0 2=8.0 6=0 -Interp interpolate_48 1 1 267 293 0=1 1=4.0 2=4.0 6=0 -Interp interpolate_49 1 1 279 294 0=1 1=2.0 2=2.0 6=0 -Concat cat_0 4 1 292 293 294 291 295 0=0 -Convolution convrelu_10 1 1 295 296 0=24 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=20736 9=1 -Deconvolution deconvrelu_0 1 1 296 297 0=24 1=2 11=2 12=1 13=2 14=0 18=0 19=0 2=1 3=2 4=0 5=1 6=2304 9=1 -Deconvolution deconv_112 1 1 297 298 0=1 1=2 11=2 12=1 13=2 14=0 18=0 19=0 2=1 3=2 4=0 5=0 6=96 -BinaryOp add_133 1 1 298 299 0=0 1=1 2=-0.233349 -Sigmoid sigmoid_62 1 1 299 output diff --git a/models/PP_OCRv5_mobile_rec.bin b/models/PP_OCRv5_mobile_rec.bin deleted file mode 100644 index 2cf896a..0000000 Binary files a/models/PP_OCRv5_mobile_rec.bin and /dev/null differ diff --git a/models/PP_OCRv5_mobile_rec.param b/models/PP_OCRv5_mobile_rec.param deleted file mode 100644 index d25bb1d..0000000 --- a/models/PP_OCRv5_mobile_rec.param +++ /dev/null @@ -1,228 +0,0 @@ -7767517 -226 233 -Input input 0 1 input -Convolution conv_48 1 1 input 1 0=16 1=3 11=3 12=1 13=2 14=1 2=1 3=2 4=1 5=1 6=432 -ConvolutionDepthWise convdw_87 1 1 1 2 0=16 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=144 7=16 -BinaryOp mul_0 1 1 2 3 0=2 1=1 2=0.618031 -BinaryOp add_1 1 1 3 4 0=0 1=1 2=0.187708 -HardSwish hswish_10 1 1 4 5 0=0.166667 1=0.5 -BinaryOp mul_2 1 1 5 6 0=2 1=1 2=0.00957466 -BinaryOp add_3 1 1 6 7 0=0 1=1 2=-0.000411757 -Convolution conv_49 1 1 7 8 0=32 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=512 -BinaryOp mul_4 1 1 8 9 0=2 1=1 2=0.734481 -BinaryOp add_5 1 1 9 10 0=0 1=1 2=0.24252 -HardSwish hswish_11 1 1 10 11 0=0.166667 1=0.5 -BinaryOp mul_6 1 1 11 12 0=2 1=1 2=0.197886 -BinaryOp add_7 1 1 12 13 0=0 1=1 2=-0.191666 -ConvolutionDepthWise convdw_88 1 1 13 14 0=32 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=288 7=32 -BinaryOp mul_8 1 1 14 15 0=2 1=1 2=0.567694 -BinaryOp add_9 1 1 15 16 0=0 1=1 2=0.295256 -HardSwish hswish_12 1 1 16 17 0=0.166667 1=0.5 -BinaryOp mul_10 1 1 17 18 0=2 1=1 2=0.178215 -BinaryOp add_11 1 1 18 19 0=0 1=1 2=1.091638e-05 -Convolution conv_50 1 1 19 20 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=2048 -BinaryOp mul_12 1 1 20 21 0=2 1=1 2=0.786465 -BinaryOp add_13 1 1 21 22 0=0 1=1 2=0.217506 -HardSwish hswish_13 1 1 22 23 0=0.166667 1=0.5 -BinaryOp mul_14 1 1 23 24 0=2 1=1 2=0.168005 -BinaryOp add_15 1 1 24 25 0=0 1=1 2=-0.397175 -ConvolutionDepthWise convdw_89 1 1 25 26 0=64 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=576 7=64 -BinaryOp mul_16 1 1 26 27 0=2 1=1 2=1.43576 -BinaryOp add_17 1 1 27 28 0=0 1=1 2=0.0422556 -HardSwish hswish_14 1 1 28 29 0=0.166667 1=0.5 -BinaryOp mul_18 1 1 29 30 0=2 1=1 2=0.0209962 -BinaryOp add_19 1 1 30 31 0=0 1=1 2=4.977742e-05 -Convolution conv_51 1 1 31 32 0=64 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=4096 -BinaryOp mul_20 1 1 32 33 0=2 1=1 2=0.890911 -BinaryOp add_21 1 1 33 34 0=0 1=1 2=0.160509 -HardSwish hswish_15 1 1 34 35 0=0.166667 1=0.5 -BinaryOp mul_22 1 1 35 36 0=2 1=1 2=0.19684 -BinaryOp add_23 1 1 36 37 0=0 1=1 2=-0.124943 -ConvolutionDepthWise convdw_90 1 1 37 38 0=64 1=3 11=3 12=1 13=2 14=1 2=1 3=1 4=1 5=1 6=576 7=64 -BinaryOp mul_24 1 1 38 39 0=2 1=1 2=0.532039 -BinaryOp add_25 1 1 39 40 0=0 1=1 2=0.300257 -HardSwish hswish_16 1 1 40 41 0=0.166667 1=0.5 -BinaryOp mul_26 1 1 41 42 0=2 1=1 2=0.0433737 -BinaryOp add_27 1 1 42 43 0=0 1=1 2=4.015856e-06 -Convolution conv_52 1 1 43 44 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=8192 -BinaryOp mul_28 1 1 44 45 0=2 1=1 2=0.643983 -BinaryOp add_29 1 1 45 46 0=0 1=1 2=0.376627 -HardSwish hswish_17 1 1 46 47 0=0.166667 1=0.5 -BinaryOp mul_30 1 1 47 48 0=2 1=1 2=0.251939 -BinaryOp add_31 1 1 48 49 0=0 1=1 2=-0.348501 -ConvolutionDepthWise convdw_91 1 1 49 50 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=1 4=1 5=1 6=1152 7=128 -BinaryOp mul_32 1 1 50 51 0=2 1=1 2=1.03336 -BinaryOp add_33 1 1 51 52 0=0 1=1 2=0.105798 -HardSwish hswish_18 1 1 52 53 0=0.166667 1=0.5 -BinaryOp mul_34 1 1 53 54 0=2 1=1 2=0.0406618 -BinaryOp add_35 1 1 54 55 0=0 1=1 2=-4.833737e-06 -Convolution conv_53 1 1 55 56 0=128 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=16384 -BinaryOp mul_36 1 1 56 57 0=2 1=1 2=0.749214 -BinaryOp add_37 1 1 57 58 0=0 1=1 2=0.181502 -HardSwish hswish_19 1 1 58 59 0=0.166667 1=0.5 -BinaryOp mul_38 1 1 59 60 0=2 1=1 2=0.360454 -BinaryOp add_39 1 1 60 61 0=0 1=1 2=-0.06972 -ConvolutionDepthWise convdw_92 1 1 61 62 0=128 1=3 11=3 12=1 13=1 14=1 2=1 3=2 4=1 5=1 6=1152 7=128 -BinaryOp mul_40 1 1 62 63 0=2 1=1 2=0.481373 -BinaryOp add_41 1 1 63 64 0=0 1=1 2=0.20761 -HardSwish hswish_20 1 1 64 65 0=0.166667 1=0.5 -BinaryOp mul_42 1 1 65 66 0=2 1=1 2=0.0510535 -BinaryOp add_43 1 1 66 67 0=0 1=1 2=1.921835e-05 -Convolution conv_54 1 1 67 68 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=30720 -BinaryOp mul_44 1 1 68 69 0=2 1=1 2=0.650919 -BinaryOp add_45 1 1 69 70 0=0 1=1 2=0.339274 -HardSwish hswish_21 1 1 70 71 0=0.166667 1=0.5 -BinaryOp mul_46 1 1 71 72 0=2 1=1 2=0.404994 -BinaryOp add_47 1 1 72 73 0=0 1=1 2=-0.301044 -ConvolutionDepthWise convdw_93 1 1 73 74 0=240 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6000 7=240 -BinaryOp mul_48 1 1 74 75 0=2 1=1 2=0.504058 -BinaryOp add_49 1 1 75 76 0=0 1=1 2=0.0411374 -HardSwish hswish_22 1 1 76 77 0=0.166667 1=0.5 -BinaryOp mul_50 1 1 77 78 0=2 1=1 2=0.0339292 -BinaryOp add_51 1 1 78 79 0=0 1=1 2=-7.692371e-06 -Convolution conv_55 1 1 79 80 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -BinaryOp mul_52 1 1 80 81 0=2 1=1 2=0.639707 -BinaryOp add_53 1 1 81 82 0=0 1=1 2=0.188142 -HardSwish hswish_23 1 1 82 83 0=0.166667 1=0.5 -BinaryOp mul_54 1 1 83 84 0=2 1=1 2=0.424111 -BinaryOp add_55 1 1 84 85 0=0 1=1 2=-0.203311 -ConvolutionDepthWise convdw_94 1 1 85 86 0=240 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6000 7=240 -BinaryOp mul_56 1 1 86 87 0=2 1=1 2=0.383856 -BinaryOp add_57 1 1 87 88 0=0 1=1 2=-0.00941171 -HardSwish hswish_24 1 1 88 89 0=0.166667 1=0.5 -BinaryOp mul_58 1 1 89 90 0=2 1=1 2=0.019946 -BinaryOp add_59 1 1 90 91 0=0 1=1 2=0.000135511 -Convolution conv_56 1 1 91 92 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -BinaryOp mul_60 1 1 92 93 0=2 1=1 2=0.66131 -BinaryOp add_61 1 1 93 94 0=0 1=1 2=-0.0177427 -HardSwish hswish_25 1 1 94 95 0=0.166667 1=0.5 -BinaryOp mul_62 1 1 95 96 0=2 1=1 2=0.587085 -BinaryOp add_63 1 1 96 97 0=0 1=1 2=0.00264927 -ConvolutionDepthWise convdw_95 1 1 97 98 0=240 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6000 7=240 -BinaryOp mul_64 1 1 98 99 0=2 1=1 2=0.318789 -BinaryOp add_65 1 1 99 100 0=0 1=1 2=0.295759 -HardSwish hswish_26 1 1 100 101 0=0.166667 1=0.5 -BinaryOp mul_66 1 1 101 102 0=2 1=1 2=0.0184652 -BinaryOp add_67 1 1 102 103 0=0 1=1 2=7.642443e-05 -Convolution conv_57 1 1 103 104 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -BinaryOp mul_68 1 1 104 105 0=2 1=1 2=0.627805 -BinaryOp add_69 1 1 105 106 0=0 1=1 2=-0.141457 -HardSwish hswish_27 1 1 106 107 0=0.166667 1=0.5 -BinaryOp mul_70 1 1 107 108 0=2 1=1 2=0.633296 -BinaryOp add_71 1 1 108 109 0=0 1=1 2=0.147221 -ConvolutionDepthWise convdw_96 1 1 109 110 0=240 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=6000 7=240 -BinaryOp mul_72 1 1 110 111 0=2 1=1 2=0.316436 -BinaryOp add_73 1 1 111 112 0=0 1=1 2=0.405378 -HardSwish hswish_28 1 1 112 113 0=0.166667 1=0.5 -BinaryOp mul_74 1 1 113 114 0=2 1=1 2=0.019494 -BinaryOp add_75 1 1 114 115 0=0 1=1 2=-8.610530e-05 -Convolution conv_58 1 1 115 116 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -BinaryOp mul_76 1 1 116 117 0=2 1=1 2=0.547101 -BinaryOp add_77 1 1 117 118 0=0 1=1 2=-0.207009 -HardSwish hswish_29 1 1 118 119 0=0.166667 1=0.5 -BinaryOp mul_78 1 1 119 120 0=2 1=1 2=0.531144 -BinaryOp add_79 1 1 120 121 0=0 1=1 2=0.174474 -ConvolutionDepthWise convdw_97 1 1 121 122 0=240 1=5 11=5 12=1 13=2 14=2 2=1 3=1 4=2 5=1 6=6000 7=240 -BinaryOp mul_80 1 1 122 123 0=2 1=1 2=0.801708 -BinaryOp add_81 1 1 123 124 0=0 1=1 2=0.30491 -HardSwish hswish_30 1 1 124 125 0=0.166667 1=0.5 -BinaryOp mul_82 1 1 125 126 0=2 1=1 2=1.07229 -BinaryOp add_83 1 1 126 127 0=0 1=1 2=-0.893251 -Split splitncnn_0 1 2 127 128 129 -Pooling gap_5 1 1 129 130 0=1 4=1 -Convolution convrelu_0 1 1 130 131 0=60 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=14400 9=1 -Convolution conv_60 1 1 131 132 0=240 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=14400 -HardSigmoid hsigmoid_8 1 1 132 133 0=0.166667 1=0.5 -Reshape reshape_82 1 1 133 134 0=1 1=1 2=-1 -BinaryOp mul_84 2 1 128 134 135 0=2 -Convolution conv_61 1 1 135 136 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=115200 -BinaryOp mul_85 1 1 136 137 0=2 1=1 2=0.53807 -BinaryOp add_86 1 1 137 138 0=0 1=1 2=-0.101367 -HardSwish hswish_31 1 1 138 139 0=0.166667 1=0.5 -BinaryOp mul_87 1 1 139 140 0=2 1=1 2=0.666714 -BinaryOp add_88 1 1 140 141 0=0 1=1 2=0.0715439 -ConvolutionDepthWise convdw_98 1 1 141 142 0=480 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=12000 7=480 -BinaryOp mul_89 1 1 142 143 0=2 1=1 2=1.0452 -BinaryOp add_90 1 1 143 144 0=0 1=1 2=0.0480609 -HardSwish hswish_32 1 1 144 145 0=0.166667 1=0.5 -BinaryOp mul_91 1 1 145 146 0=2 1=1 2=1.45315 -BinaryOp add_92 1 1 146 147 0=0 1=1 2=-1.49934 -Split splitncnn_1 1 2 147 148 149 -Pooling gap_6 1 1 149 150 0=1 4=1 -Convolution convrelu_1 1 1 150 151 0=120 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 9=1 -Convolution conv_63 1 1 151 152 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -HardSigmoid hsigmoid_9 1 1 152 153 0=0.166667 1=0.5 -Reshape reshape_83 1 1 153 154 0=1 1=1 2=-1 -BinaryOp mul_93 2 1 148 154 155 0=2 -Convolution conv_64 1 1 155 156 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=230400 -BinaryOp mul_94 1 1 156 157 0=2 1=1 2=0.621537 -BinaryOp add_95 1 1 157 158 0=0 1=1 2=-0.334171 -HardSwish hswish_33 1 1 158 159 0=0.166667 1=0.5 -BinaryOp mul_96 1 1 159 160 0=2 1=1 2=0.59321 -BinaryOp add_97 1 1 160 161 0=0 1=1 2=0.183921 -ConvolutionDepthWise convdw_99 1 1 161 162 0=480 1=5 11=5 12=1 13=2 14=2 2=1 3=1 4=2 5=1 6=12000 7=480 -BinaryOp mul_98 1 1 162 163 0=2 1=1 2=0.283224 -BinaryOp add_99 1 1 163 164 0=0 1=1 2=0.625356 -HardSwish hswish_34 1 1 164 165 0=0.166667 1=0.5 -BinaryOp mul_100 1 1 165 166 0=2 1=1 2=0.00691399 -BinaryOp add_101 1 1 166 167 0=0 1=1 2=0.00055949 -Convolution conv_65 1 1 167 168 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=230400 -BinaryOp mul_102 1 1 168 169 0=2 1=1 2=0.764499 -BinaryOp add_103 1 1 169 170 0=0 1=1 2=-0.291876 -HardSwish hswish_35 1 1 170 171 0=0.166667 1=0.5 -BinaryOp mul_104 1 1 171 172 0=2 1=1 2=0.477352 -BinaryOp add_105 1 1 172 173 0=0 1=1 2=0.164795 -ConvolutionDepthWise convdw_100 1 1 173 174 0=480 1=5 11=5 12=1 13=1 14=2 2=1 3=1 4=2 5=1 6=12000 7=480 -BinaryOp mul_106 1 1 174 175 0=2 1=1 2=0.426318 -BinaryOp add_107 1 1 175 176 0=0 1=1 2=0.2958 -HardSwish hswish_36 1 1 176 177 0=0.166667 1=0.5 -BinaryOp mul_108 1 1 177 178 0=2 1=1 2=0.103937 -BinaryOp add_109 1 1 178 179 0=0 1=1 2=0.000811562 -Convolution conv_66 1 1 179 180 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=230400 -BinaryOp mul_110 1 1 180 181 0=2 1=1 2=2.04554 -BinaryOp add_111 1 1 181 182 0=0 1=1 2=-0.173863 -HardSwish hswish_37 1 1 182 183 0=0.166667 1=0.5 -BinaryOp mul_112 1 1 183 184 0=2 1=1 2=3.23441 -BinaryOp add_113 1 1 184 185 0=0 1=1 2=-0.354521 -Pooling avgpool2d_7 1 1 185 186 0=1 1=2 11=3 12=3 13=0 2=2 3=0 5=1 6=0 -Split splitncnn_2 1 2 186 187 188 -Convolution conv_67 1 1 188 189 0=60 1=3 11=1 12=1 13=1 14=0 2=1 3=1 4=1 5=1 6=86400 -Swish silu_40 1 1 189 190 -Convolution conv_68 1 1 190 191 0=120 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=7200 -Swish silu_41 1 1 191 192 -Reshape reshape_84 1 1 192 193 0=-1 1=120 -Permute permute_79 1 1 193 194 0=1 -Split splitncnn_3 1 2 194 195 196 -LayerNorm ln_72 1 1 196 197 0=120 1=1.000000e-05 2=1 -MultiHeadAttention attention_77 1 1 197 198 0=120 1=8 2=14400 3=120 4=120 -BinaryOp add_114 2 1 195 198 199 0=0 -Split splitncnn_4 1 2 199 200 201 -LayerNorm ln_73 1 1 201 202 0=120 1=1.000000e-05 2=1 -Gemm gemm_0 1 1 202 203 10=4 2=0 3=1 4=0 5=1 6=1 7=0 8=240 9=120 -Swish silu_42 1 1 203 204 -Gemm gemm_1 1 1 204 205 10=4 2=0 3=1 4=0 5=1 6=1 7=0 8=120 9=240 -BinaryOp add_115 2 1 200 205 206 0=0 -Split splitncnn_5 1 2 206 207 208 -LayerNorm ln_74 1 1 208 209 0=120 1=1.000000e-05 2=1 -MultiHeadAttention attention_78 1 1 209 210 0=120 1=8 2=14400 3=120 4=120 -BinaryOp add_116 2 1 207 210 211 0=0 -Split splitncnn_6 1 2 211 212 213 -LayerNorm ln_75 1 1 213 214 0=120 1=1.000000e-05 2=1 -Gemm gemm_2 1 1 214 215 10=4 2=0 3=1 4=0 5=1 6=1 7=0 8=240 9=120 -Swish silu_43 1 1 215 216 -Gemm gemm_3 1 1 216 217 10=4 2=0 3=1 4=0 5=1 6=1 7=0 8=120 9=240 -BinaryOp add_117 2 1 212 217 218 0=0 -LayerNorm ln_76 1 1 218 219 0=120 1=1.000000e-06 2=1 -Reshape reshape_85 1 1 219 220 0=120 1=-1 2=1 -Permute permute_80 1 1 220 221 0=4 -Convolution conv_69 1 1 221 222 0=480 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=57600 -Swish silu_44 1 1 222 223 -Concat cat_0 2 1 187 223 224 0=0 -Convolution conv_70 1 1 224 225 0=60 1=3 11=1 12=1 13=1 14=0 2=1 3=1 4=1 5=1 6=172800 -Swish silu_45 1 1 225 226 -Convolution conv_71 1 1 226 227 0=120 1=1 11=1 12=1 13=1 14=0 2=1 3=1 4=0 5=1 6=7200 -Swish silu_46 1 1 227 228 -Squeeze squeeze_86 1 1 228 229 -23303=1,1 -Permute permute_81 1 1 229 230 0=1 -Gemm gemm_4 1 1 230 231 10=4 2=0 3=1 4=0 5=1 6=1 7=0 8=18385 9=120 -Softmax softmax_47 1 1 231 output 0=1 1=1 diff --git a/models/ppocrv5_dict.txt b/models/ppocrv5_dict.txt deleted file mode 100644 index e26005c..0000000 --- a/models/ppocrv5_dict.txt +++ /dev/null @@ -1,18383 +0,0 @@ -  -一 -乙 -二 -十 -丁 -厂 -七 -卜 -八 -人 -入 -儿 -匕 -几 -九 -刁 -了 -刀 -力 -乃 -又 -三 -干 -于 -亏 -工 -土 -士 -才 -下 -寸 -大 -丈 -与 -万 -上 -小 -口 -山 -巾 -千 -乞 -川 -亿 -个 -夕 -久 -么 -勺 -凡 -丸 -及 -广 -亡 -门 -丫 -义 -之 -尸 -己 -已 -巳 -弓 -子 -卫 -也 -女 -刃 -飞 -习 -叉 -马 -乡 -丰 -王 -开 -井 -天 -夫 -元 -无 -云 -专 -丐 -扎 -艺 -木 -五 -支 -厅 -不 -犬 -太 -区 -历 -歹 -友 -尤 -匹 -车 -巨 -牙 -屯 -戈 -比 -互 -切 -瓦 -止 -少 -曰 -日 -中 -贝 -冈 -内 -水 -见 -午 -牛 -手 -气 -毛 -壬 -升 -夭 -长 -仁 -什 -片 -仆 -化 -仇 -币 -仍 -仅 -斤 -爪 -反 -介 -父 -从 -仑 -今 -凶 -分 -乏 -公 -仓 -月 -氏 -勿 -欠 -风 -丹 -匀 -乌 -勾 -凤 -六 -文 -亢 -方 -火 -为 -斗 -忆 -计 -订 -户 -认 -冗 -讥 -心 -尺 -引 -丑 -巴 -孔 -队 -办 -以 -允 -予 -邓 -劝 -双 -书 -幻 -玉 -刊 -未 -末 -示 -击 -打 -巧 -正 -扑 -卉 -扒 -功 -扔 -去 -甘 -世 -艾 -古 -节 -本 -术 -可 -丙 -左 -厉 -石 -右 -布 -夯 -戊 -龙 -平 -灭 -轧 -东 -卡 -北 -占 -凸 -卢 -业 -旧 -帅 -归 -旦 -目 -且 -叶 -甲 -申 -叮 -电 -号 -田 -由 -只 -叭 -史 -央 -兄 -叽 -叼 -叫 -叩 -叨 -另 -叹 -冉 -皿 -凹 -囚 -四 -生 -矢 -失 -乍 -禾 -丘 -付 -仗 -代 -仙 -们 -仪 -白 -仔 -他 -斥 -瓜 -乎 -丛 -令 -用 -甩 -印 -尔 -乐 -句 -匆 -册 -卯 -犯 -外 -处 -冬 -鸟 -务 -包 -饥 -主 -市 -立 -冯 -玄 -闪 -兰 -半 -汁 -汇 -头 -汉 -宁 -穴 -它 -讨 -写 -让 -礼 -训 -议 -必 -讯 -记 -永 -司 -尼 -民 -弗 -弘 -出 -辽 -奶 -奴 -召 -加 -皮 -边 -孕 -发 -圣 -对 -台 -矛 -纠 -母 -幼 -丝 -邦 -式 -迂 -刑 -戎 -动 -扛 -寺 -吉 -扣 -考 -托 -老 -巩 -圾 -执 -扩 -扫 -地 -场 -扬 -耳 -芋 -共 -芒 -亚 -芝 -朽 -朴 -机 -权 -过 -臣 -吏 -再 -协 -西 -压 -厌 -戌 -在 -百 -有 -存 -而 -页 -匠 -夸 -夺 -灰 -达 -列 -死 -成 -夹 -夷 -轨 -邪 -尧 -划 -迈 -毕 -至 -此 -贞 -师 -尘 -尖 -劣 -光 -当 -早 -吁 -吐 -吓 -虫 -曲 -团 -吕 -同 -吊 -吃 -因 -吸 -吗 -吆 -屿 -屹 -岁 -帆 -回 -岂 -则 -刚 -网 -肉 -年 -朱 -先 -丢 -廷 -舌 -竹 -迁 -乔 -迄 -伟 -传 -乒 -乓 -休 -伍 -伏 -优 -臼 -伐 -延 -仲 -件 -任 -伤 -价 -伦 -份 -华 -仰 -仿 -伙 -伪 -自 -伊 -血 -向 -似 -后 -行 -舟 -全 -会 -杀 -合 -兆 -企 -众 -爷 -伞 -创 -肌 -肋 -朵 -杂 -危 -旬 -旨 -旭 -负 -匈 -名 -各 -多 -争 -色 -壮 -冲 -妆 -冰 -庄 -庆 -亦 -刘 -齐 -交 -衣 -次 -产 -决 -亥 -充 -妄 -闭 -问 -闯 -羊 -并 -关 -米 -灯 -州 -汗 -污 -江 -汛 -池 -汝 -汤 -忙 -兴 -宇 -守 -宅 -字 -安 -讲 -讳 -军 -讶 -许 -讹 -论 -讼 -农 -讽 -设 -访 -诀 -寻 -那 -迅 -尽 -导 -异 -弛 -孙 -阵 -阳 -收 -阶 -阴 -防 -奸 -如 -妇 -妃 -好 -她 -妈 -戏 -羽 -观 -欢 -买 -红 -驮 -纤 -驯 -约 -级 -纪 -驰 -纫 -巡 -寿 -弄 -麦 -玖 -玛 -形 -进 -戒 -吞 -远 -违 -韧 -运 -扶 -抚 -坛 -技 -坏 -抠 -扰 -扼 -拒 -找 -批 -址 -扯 -走 -抄 -贡 -汞 -坝 -攻 -赤 -折 -抓 -扳 -抡 -扮 -抢 -孝 -坎 -均 -抑 -抛 -投 -坟 -坑 -抗 -坊 -抖 -护 -壳 -志 -块 -扭 -声 -把 -报 -拟 -却 -抒 -劫 -芙 -芜 -苇 -芽 -花 -芹 -芥 -芬 -苍 -芳 -严 -芦 -芯 -劳 -克 -芭 -苏 -杆 -杠 -杜 -材 -村 -杖 -杏 -杉 -巫 -极 -李 -杨 -求 -甫 -匣 -更 -束 -吾 -豆 -两 -酉 -丽 -医 -辰 -励 -否 -还 -尬 -歼 -来 -连 -轩 -步 -卤 -坚 -肖 -旱 -盯 -呈 -时 -吴 -助 -县 -里 -呆 -吱 -吠 -呕 -园 -旷 -围 -呀 -吨 -足 -邮 -男 -困 -吵 -串 -员 -呐 -听 -吟 -吩 -呛 -吻 -吹 -呜 -吭 -吧 -邑 -吼 -囤 -别 -吮 -岖 -岗 -帐 -财 -针 -钉 -牡 -告 -我 -乱 -利 -秃 -秀 -私 -每 -兵 -估 -体 -何 -佐 -佑 -但 -伸 -佃 -作 -伯 -伶 -佣 -低 -你 -住 -位 -伴 -身 -皂 -伺 -佛 -囱 -近 -彻 -役 -返 -余 -希 -坐 -谷 -妥 -含 -邻 -岔 -肝 -肛 -肚 -肘 -肠 -龟 -甸 -免 -狂 -犹 -狈 -角 -删 -条 -彤 -卵 -灸 -岛 -刨 -迎 -饭 -饮 -系 -言 -冻 -状 -亩 -况 -床 -库 -庇 -疗 -吝 -应 -这 -冷 -庐 -序 -辛 -弃 -冶 -忘 -闰 -闲 -间 -闷 -判 -兑 -灶 -灿 -灼 -弟 -汪 -沐 -沛 -汰 -沥 -沙 -汽 -沃 -沦 -汹 -泛 -沧 -没 -沟 -沪 -沈 -沉 -沁 -怀 -忧 -忱 -快 -完 -宋 -宏 -牢 -究 -穷 -灾 -良 -证 -启 -评 -补 -初 -社 -祀 -识 -诈 -诉 -罕 -诊 -词 -译 -君 -灵 -即 -层 -屁 -尿 -尾 -迟 -局 -改 -张 -忌 -际 -陆 -阿 -陈 -阻 -附 -坠 -妓 -妙 -妖 -姊 -妨 -妒 -努 -忍 -劲 -矣 -鸡 -纬 -驱 -纯 -纱 -纲 -纳 -驳 -纵 -纷 -纸 -纹 -纺 -驴 -纽 -奉 -玩 -环 -武 -青 -责 -现 -玫 -表 -规 -抹 -卦 -坷 -坯 -拓 -拢 -拔 -坪 -拣 -坦 -担 -坤 -押 -抽 -拐 -拖 -者 -拍 -顶 -拆 -拎 -拥 -抵 -拘 -势 -抱 -拄 -垃 -拉 -拦 -幸 -拌 -拧 -拂 -拙 -招 -坡 -披 -拨 -择 -抬 -拇 -拗 -其 -取 -茉 -苦 -昔 -苛 -若 -茂 -苹 -苗 -英 -苟 -苑 -苞 -范 -直 -茁 -茄 -茎 -苔 -茅 -枉 -林 -枝 -杯 -枢 -柜 -枚 -析 -板 -松 -枪 -枫 -构 -杭 -杰 -述 -枕 -丧 -或 -画 -卧 -事 -刺 -枣 -雨 -卖 -郁 -矾 -矿 -码 -厕 -奈 -奔 -奇 -奋 -态 -欧 -殴 -垄 -妻 -轰 -顷 -转 -斩 -轮 -软 -到 -非 -叔 -歧 -肯 -齿 -些 -卓 -虎 -虏 -肾 -贤 -尚 -旺 -具 -味 -果 -昆 -国 -哎 -咕 -昌 -呵 -畅 -明 -易 -咙 -昂 -迪 -典 -固 -忠 -呻 -咒 -咋 -咐 -呼 -鸣 -咏 -呢 -咄 -咖 -岸 -岩 -帖 -罗 -帜 -帕 -岭 -凯 -败 -账 -贩 -贬 -购 -贮 -图 -钓 -制 -知 -迭 -氛 -垂 -牧 -物 -乖 -刮 -秆 -和 -季 -委 -秉 -佳 -侍 -岳 -供 -使 -例 -侠 -侥 -版 -侄 -侦 -侣 -侧 -凭 -侨 -佩 -货 -侈 -依 -卑 -的 -迫 -质 -欣 -征 -往 -爬 -彼 -径 -所 -舍 -金 -刹 -命 -肴 -斧 -爸 -采 -觅 -受 -乳 -贪 -念 -贫 -忿 -肤 -肺 -肢 -肿 -胀 -朋 -股 -肮 -肪 -肥 -服 -胁 -周 -昏 -鱼 -兔 -狐 -忽 -狗 -狞 -备 -饰 -饱 -饲 -变 -京 -享 -庞 -店 -夜 -庙 -府 -底 -疟 -疙 -疚 -剂 -卒 -郊 -庚 -废 -净 -盲 -放 -刻 -育 -氓 -闸 -闹 -郑 -券 -卷 -单 -炬 -炒 -炊 -炕 -炎 -炉 -沫 -浅 -法 -泄 -沽 -河 -沾 -泪 -沮 -油 -泊 -沿 -泡 -注 -泣 -泞 -泻 -泌 -泳 -泥 -沸 -沼 -波 -泼 -泽 -治 -怔 -怯 -怖 -性 -怕 -怜 -怪 -怡 -学 -宝 -宗 -定 -宠 -宜 -审 -宙 -官 -空 -帘 -宛 -实 -试 -郎 -诗 -肩 -房 -诚 -衬 -衫 -视 -祈 -话 -诞 -诡 -询 -该 -详 -建 -肃 -录 -隶 -帚 -屉 -居 -届 -刷 -屈 -弧 -弥 -弦 -承 -孟 -陋 -陌 -孤 -陕 -降 -函 -限 -妹 -姑 -姐 -姓 -妮 -始 -姆 -迢 -驾 -叁 -参 -艰 -线 -练 -组 -绅 -细 -驶 -织 -驹 -终 -驻 -绊 -驼 -绍 -绎 -经 -贯 -契 -贰 -奏 -春 -帮 -玷 -珍 -玲 -玻 -毒 -型 -拭 -挂 -封 -持 -拷 -拱 -项 -垮 -挎 -城 -挟 -挠 -政 -赴 -赵 -挡 -拽 -哉 -挺 -括 -垢 -拴 -拾 -挑 -垛 -指 -垫 -挣 -挤 -拼 -挖 -按 -挥 -挪 -拯 -某 -甚 -荆 -茸 -革 -茬 -荐 -巷 -带 -草 -茧 -茵 -茶 -荒 -茫 -荡 -荣 -荤 -荧 -故 -胡 -荫 -荔 -南 -药 -标 -栈 -柑 -枯 -柄 -栋 -相 -查 -柏 -栅 -柳 -柱 -柿 -栏 -柠 -树 -勃 -要 -柬 -咸 -威 -歪 -研 -砖 -厘 -厚 -砌 -砂 -泵 -砚 -砍 -面 -耐 -耍 -牵 -鸥 -残 -殃 -轴 -轻 -鸦 -皆 -韭 -背 -战 -点 -虐 -临 -览 -竖 -省 -削 -尝 -昧 -盹 -是 -盼 -眨 -哇 -哄 -哑 -显 -冒 -映 -星 -昨 -咧 -昭 -畏 -趴 -胃 -贵 -界 -虹 -虾 -蚁 -思 -蚂 -虽 -品 -咽 -骂 -勋 -哗 -咱 -响 -哈 -哆 -咬 -咳 -咪 -哪 -哟 -炭 -峡 -罚 -贱 -贴 -贻 -骨 -幽 -钙 -钝 -钞 -钟 -钢 -钠 -钥 -钦 -钧 -钩 -钮 -卸 -缸 -拜 -看 -矩 -毡 -氢 -怎 -牲 -选 -适 -秒 -香 -种 -秋 -科 -重 -复 -竿 -段 -便 -俩 -贷 -顺 -修 -俏 -保 -促 -俄 -俐 -侮 -俭 -俗 -俘 -信 -皇 -泉 -鬼 -侵 -禹 -侯 -追 -俊 -盾 -待 -徊 -衍 -律 -很 -须 -叙 -剑 -逃 -食 -盆 -胚 -胧 -胆 -胜 -胞 -胖 -脉 -胎 -勉 -狭 -狮 -独 -狰 -狡 -狱 -狠 -贸 -怨 -急 -饵 -饶 -蚀 -饺 -饼 -峦 -弯 -将 -奖 -哀 -亭 -亮 -度 -迹 -庭 -疮 -疯 -疫 -疤 -咨 -姿 -亲 -音 -帝 -施 -闺 -闻 -闽 -阀 -阁 -差 -养 -美 -姜 -叛 -送 -类 -迷 -籽 -娄 -前 -首 -逆 -兹 -总 -炼 -炸 -烁 -炮 -炫 -烂 -剃 -洼 -洁 -洪 -洒 -柒 -浇 -浊 -洞 -测 -洗 -活 -派 -洽 -染 -洛 -浏 -济 -洋 -洲 -浑 -浓 -津 -恃 -恒 -恢 -恍 -恬 -恤 -恰 -恼 -恨 -举 -觉 -宣 -宦 -室 -宫 -宪 -突 -穿 -窃 -客 -诫 -冠 -诬 -语 -扁 -袄 -祖 -神 -祝 -祠 -误 -诱 -诲 -说 -诵 -垦 -退 -既 -屋 -昼 -屏 -屎 -费 -陡 -逊 -眉 -孩 -陨 -除 -险 -院 -娃 -姥 -姨 -姻 -娇 -姚 -娜 -怒 -架 -贺 -盈 -勇 -怠 -癸 -蚤 -柔 -垒 -绑 -绒 -结 -绕 -骄 -绘 -给 -绚 -骆 -络 -绝 -绞 -骇 -统 -耕 -耘 -耗 -耙 -艳 -泰 -秦 -珠 -班 -素 -匿 -蚕 -顽 -盏 -匪 -捞 -栽 -捕 -埂 -捂 -振 -载 -赶 -起 -盐 -捎 -捍 -捏 -埋 -捉 -捆 -捐 -损 -袁 -捌 -都 -哲 -逝 -捡 -挫 -换 -挽 -挚 -热 -恐 -捣 -壶 -捅 -埃 -挨 -耻 -耿 -耽 -聂 -恭 -莽 -莱 -莲 -莫 -莉 -荷 -获 -晋 -恶 -莹 -莺 -真 -框 -梆 -桂 -桔 -栖 -档 -桐 -株 -桥 -桦 -栓 -桃 -格 -桩 -校 -核 -样 -根 -索 -哥 -速 -逗 -栗 -贾 -酌 -配 -翅 -辱 -唇 -夏 -砸 -砰 -砾 -础 -破 -原 -套 -逐 -烈 -殊 -殉 -顾 -轿 -较 -顿 -毙 -致 -柴 -桌 -虑 -监 -紧 -党 -逞 -晒 -眠 -晓 -哮 -唠 -鸭 -晃 -哺 -晌 -剔 -晕 -蚌 -畔 -蚣 -蚊 -蚪 -蚓 -哨 -哩 -圃 -哭 -哦 -恩 -鸯 -唤 -唁 -哼 -唧 -啊 -唉 -唆 -罢 -峭 -峨 -峰 -圆 -峻 -贼 -贿 -赂 -赃 -钱 -钳 -钻 -钾 -铁 -铃 -铅 -缺 -氧 -氨 -特 -牺 -造 -乘 -敌 -秤 -租 -积 -秧 -秩 -称 -秘 -透 -笔 -笑 -笋 -债 -借 -值 -倚 -俺 -倾 -倒 -倘 -俱 -倡 -候 -赁 -俯 -倍 -倦 -健 -臭 -射 -躬 -息 -倔 -徒 -徐 -殷 -舰 -舱 -般 -航 -途 -拿 -耸 -爹 -舀 -爱 -豺 -豹 -颁 -颂 -翁 -胰 -脆 -脂 -胸 -胳 -脏 -脐 -胶 -脑 -脓 -逛 -狸 -狼 -卿 -逢 -鸵 -留 -鸳 -皱 -饿 -馁 -凌 -凄 -恋 -桨 -浆 -衰 -衷 -高 -郭 -席 -准 -座 -症 -病 -疾 -斋 -疹 -疼 -疲 -脊 -效 -离 -紊 -唐 -瓷 -资 -凉 -站 -剖 -竞 -部 -旁 -旅 -畜 -阅 -羞 -羔 -瓶 -拳 -粉 -料 -益 -兼 -烤 -烘 -烦 -烧 -烛 -烟 -烙 -递 -涛 -浙 -涝 -浦 -酒 -涉 -消 -涡 -浩 -海 -涂 -浴 -浮 -涣 -涤 -流 -润 -涧 -涕 -浪 -浸 -涨 -烫 -涩 -涌 -悖 -悟 -悄 -悍 -悔 -悯 -悦 -害 -宽 -家 -宵 -宴 -宾 -窍 -窄 -容 -宰 -案 -请 -朗 -诸 -诺 -读 -扇 -诽 -袜 -袖 -袍 -被 -祥 -课 -冥 -谁 -调 -冤 -谅 -谆 -谈 -谊 -剥 -恳 -展 -剧 -屑 -弱 -陵 -祟 -陶 -陷 -陪 -娱 -娟 -恕 -娥 -娘 -通 -能 -难 -预 -桑 -绢 -绣 -验 -继 -骏 -球 -琐 -理 -琉 -琅 -捧 -堵 -措 -描 -域 -捺 -掩 -捷 -排 -焉 -掉 -捶 -赦 -堆 -推 -埠 -掀 -授 -捻 -教 -掏 -掐 -掠 -掂 -培 -接 -掷 -控 -探 -据 -掘 -掺 -职 -基 -聆 -勘 -聊 -娶 -著 -菱 -勒 -黄 -菲 -萌 -萝 -菌 -萎 -菜 -萄 -菊 -菩 -萍 -菠 -萤 -营 -乾 -萧 -萨 -菇 -械 -彬 -梦 -婪 -梗 -梧 -梢 -梅 -检 -梳 -梯 -桶 -梭 -救 -曹 -副 -票 -酝 -酗 -厢 -戚 -硅 -硕 -奢 -盔 -爽 -聋 -袭 -盛 -匾 -雪 -辅 -辆 -颅 -虚 -彪 -雀 -堂 -常 -眶 -匙 -晨 -睁 -眯 -眼 -悬 -野 -啪 -啦 -曼 -晦 -晚 -啄 -啡 -距 -趾 -啃 -跃 -略 -蚯 -蛀 -蛇 -唬 -累 -鄂 -唱 -患 -啰 -唾 -唯 -啤 -啥 -啸 -崖 -崎 -崭 -逻 -崔 -帷 -崩 -崇 -崛 -婴 -圈 -铐 -铛 -铝 -铜 -铭 -铲 -银 -矫 -甜 -秸 -梨 -犁 -秽 -移 -笨 -笼 -笛 -笙 -符 -第 -敏 -做 -袋 -悠 -偿 -偶 -偎 -偷 -您 -售 -停 -偏 -躯 -兜 -假 -衅 -徘 -徙 -得 -衔 -盘 -舶 -船 -舵 -斜 -盒 -鸽 -敛 -悉 -欲 -彩 -领 -脚 -脖 -脯 -豚 -脸 -脱 -象 -够 -逸 -猜 -猪 -猎 -猫 -凰 -猖 -猛 -祭 -馅 -馆 -凑 -减 -毫 -烹 -庶 -麻 -庵 -痊 -痒 -痕 -廊 -康 -庸 -鹿 -盗 -章 -竟 -商 -族 -旋 -望 -率 -阎 -阐 -着 -羚 -盖 -眷 -粘 -粗 -粒 -断 -剪 -兽 -焊 -焕 -清 -添 -鸿 -淋 -涯 -淹 -渠 -渐 -淑 -淌 -混 -淮 -淆 -渊 -淫 -渔 -淘 -淳 -液 -淤 -淡 -淀 -深 -涮 -涵 -婆 -梁 -渗 -情 -惜 -惭 -悼 -惧 -惕 -惟 -惊 -惦 -悴 -惋 -惨 -惯 -寇 -寅 -寄 -寂 -宿 -窒 -窑 -密 -谋 -谍 -谎 -谐 -袱 -祷 -祸 -谓 -谚 -谜 -逮 -敢 -尉 -屠 -弹 -隋 -堕 -随 -蛋 -隅 -隆 -隐 -婚 -婶 -婉 -颇 -颈 -绩 -绪 -续 -骑 -绰 -绳 -维 -绵 -绷 -绸 -综 -绽 -绿 -缀 -巢 -琴 -琳 -琢 -琼 -斑 -替 -揍 -款 -堪 -塔 -搭 -堰 -揩 -越 -趁 -趋 -超 -揽 -堤 -提 -博 -揭 -喜 -彭 -揣 -插 -揪 -搜 -煮 -援 -搀 -裁 -搁 -搓 -搂 -搅 -壹 -握 -搔 -揉 -斯 -期 -欺 -联 -葫 -散 -惹 -葬 -募 -葛 -董 -葡 -敬 -葱 -蒋 -蒂 -落 -韩 -朝 -辜 -葵 -棒 -棱 -棋 -椰 -植 -森 -焚 -椅 -椒 -棵 -棍 -椎 -棉 -棚 -棕 -棺 -榔 -椭 -惠 -惑 -逼 -粟 -棘 -酣 -酥 -厨 -厦 -硬 -硝 -确 -硫 -雁 -殖 -裂 -雄 -颊 -雳 -暂 -雅 -翘 -辈 -悲 -紫 -凿 -辉 -敞 -棠 -赏 -掌 -晴 -睐 -暑 -最 -晰 -量 -鼎 -喷 -喳 -晶 -喇 -遇 -喊 -遏 -晾 -景 -畴 -践 -跋 -跌 -跑 -跛 -遗 -蛙 -蛛 -蜓 -蜒 -蛤 -喝 -鹃 -喂 -喘 -喉 -喻 -啼 -喧 -嵌 -幅 -帽 -赋 -赌 -赎 -赐 -赔 -黑 -铸 -铺 -链 -销 -锁 -锄 -锅 -锈 -锋 -锌 -锐 -甥 -掰 -短 -智 -氮 -毯 -氯 -鹅 -剩 -稍 -程 -稀 -税 -筐 -等 -筑 -策 -筛 -筒 -筏 -答 -筋 -筝 -傲 -傅 -牌 -堡 -集 -焦 -傍 -储 -皓 -皖 -粤 -奥 -街 -惩 -御 -循 -艇 -舒 -逾 -番 -释 -禽 -腊 -脾 -腋 -腔 -腕 -鲁 -猩 -猬 -猾 -猴 -惫 -然 -馈 -馋 -装 -蛮 -就 -敦 -斌 -痘 -痢 -痪 -痛 -童 -竣 -阔 -善 -翔 -羡 -普 -粪 -尊 -奠 -道 -遂 -曾 -焰 -港 -滞 -湖 -湘 -渣 -渤 -渺 -湿 -温 -渴 -溃 -溅 -滑 -湃 -渝 -湾 -渡 -游 -滋 -渲 -溉 -愤 -慌 -惰 -愕 -愣 -惶 -愧 -愉 -慨 -割 -寒 -富 -寓 -窜 -窝 -窖 -窗 -窘 -遍 -雇 -裕 -裤 -裙 -禅 -禄 -谢 -谣 -谤 -谦 -犀 -属 -屡 -强 -粥 -疏 -隔 -隙 -隘 -媒 -絮 -嫂 -媚 -婿 -登 -缅 -缆 -缉 -缎 -缓 -缔 -缕 -骗 -编 -骚 -缘 -瑟 -鹉 -瑞 -瑰 -瑙 -魂 -肆 -摄 -摸 -填 -搏 -塌 -鼓 -摆 -携 -搬 -摇 -搞 -塘 -摊 -聘 -斟 -蒜 -勤 -靴 -靶 -鹊 -蓝 -墓 -幕 -蓬 -蓄 -蒲 -蓉 -蒙 -蒸 -献 -椿 -禁 -楚 -楷 -榄 -想 -槐 -榆 -楼 -概 -赖 -酪 -酬 -感 -碍 -碘 -碑 -碎 -碰 -碗 -碌 -尴 -雷 -零 -雾 -雹 -辐 -辑 -输 -督 -频 -龄 -鉴 -睛 -睹 -睦 -瞄 -睫 -睡 -睬 -嗜 -鄙 -嗦 -愚 -暖 -盟 -歇 -暗 -暇 -照 -畸 -跨 -跷 -跳 -跺 -跪 -路 -跤 -跟 -遣 -蜈 -蜗 -蛾 -蜂 -蜕 -嗅 -嗡 -嗓 -署 -置 -罪 -罩 -蜀 -幌 -错 -锚 -锡 -锣 -锤 -锥 -锦 -键 -锯 -锰 -矮 -辞 -稚 -稠 -颓 -愁 -筹 -签 -简 -筷 -毁 -舅 -鼠 -催 -傻 -像 -躲 -魁 -衙 -微 -愈 -遥 -腻 -腰 -腥 -腮 -腹 -腺 -鹏 -腾 -腿 -鲍 -猿 -颖 -触 -解 -煞 -雏 -馍 -馏 -酱 -禀 -痹 -廓 -痴 -痰 -廉 -靖 -新 -韵 -意 -誊 -粮 -数 -煎 -塑 -慈 -煤 -煌 -满 -漠 -滇 -源 -滤 -滥 -滔 -溪 -溜 -漓 -滚 -溢 -溯 -滨 -溶 -溺 -粱 -滩 -慎 -誉 -塞 -寞 -窥 -窟 -寝 -谨 -褂 -裸 -福 -谬 -群 -殿 -辟 -障 -媳 -嫉 -嫌 -嫁 -叠 -缚 -缝 -缠 -缤 -剿 -静 -碧 -璃 -赘 -熬 -墙 -墟 -嘉 -摧 -赫 -截 -誓 -境 -摘 -摔 -撇 -聚 -慕 -暮 -摹 -蔓 -蔑 -蔡 -蔗 -蔽 -蔼 -熙 -蔚 -兢 -模 -槛 -榴 -榜 -榨 -榕 -歌 -遭 -酵 -酷 -酿 -酸 -碟 -碱 -碳 -磁 -愿 -需 -辖 -辗 -雌 -裳 -颗 -瞅 -墅 -嗽 -踊 -蜻 -蜡 -蝇 -蜘 -蝉 -嘛 -嘀 -赚 -锹 -锻 -镀 -舞 -舔 -稳 -熏 -箕 -算 -箩 -管 -箫 -舆 -僚 -僧 -鼻 -魄 -魅 -貌 -膜 -膊 -膀 -鲜 -疑 -孵 -馒 -裹 -敲 -豪 -膏 -遮 -腐 -瘩 -瘟 -瘦 -辣 -彰 -竭 -端 -旗 -精 -粹 -歉 -弊 -熄 -熔 -煽 -潇 -漆 -漱 -漂 -漫 -滴 -漾 -演 -漏 -慢 -慷 -寨 -赛 -寡 -察 -蜜 -寥 -谭 -肇 -褐 -褪 -谱 -隧 -嫩 -翠 -熊 -凳 -骡 -缩 -慧 -撵 -撕 -撒 -撩 -趣 -趟 -撑 -撮 -撬 -播 -擒 -墩 -撞 -撤 -增 -撰 -聪 -鞋 -鞍 -蕉 -蕊 -蔬 -蕴 -横 -槽 -樱 -橡 -樟 -橄 -敷 -豌 -飘 -醋 -醇 -醉 -磕 -磊 -磅 -碾 -震 -霄 -霉 -瞒 -题 -暴 -瞎 -嘻 -嘶 -嘲 -嘹 -影 -踢 -踏 -踩 -踪 -蝶 -蝴 -蝠 -蝎 -蝌 -蝗 -蝙 -嘿 -嘱 -幢 -墨 -镇 -镐 -镑 -靠 -稽 -稻 -黎 -稿 -稼 -箱 -篓 -箭 -篇 -僵 -躺 -僻 -德 -艘 -膝 -膛 -鲤 -鲫 -熟 -摩 -褒 -瘪 -瘤 -瘫 -凛 -颜 -毅 -糊 -遵 -憋 -潜 -澎 -潮 -潭 -鲨 -澳 -潘 -澈 -澜 -澄 -懂 -憔 -懊 -憎 -额 -翩 -褥 -谴 -鹤 -憨 -慰 -劈 -履 -豫 -缭 -撼 -擂 -操 -擅 -燕 -蕾 -薯 -薛 -薇 -擎 -薪 -薄 -颠 -翰 -噩 -橱 -橙 -橘 -整 -融 -瓢 -醒 -霍 -霎 -辙 -冀 -餐 -嘴 -踱 -蹄 -蹂 -蟆 -螃 -器 -噪 -鹦 -赠 -默 -黔 -镜 -赞 -穆 -篮 -篡 -篷 -篱 -儒 -邀 -衡 -膨 -雕 -鲸 -磨 -瘾 -瘸 -凝 -辨 -辩 -糙 -糖 -糕 -燃 -濒 -澡 -激 -懒 -憾 -懈 -窿 -壁 -避 -缰 -缴 -戴 -擦 -藉 -鞠 -藏 -藐 -檬 -檐 -檀 -礁 -磷 -霜 -霞 -瞭 -瞧 -瞬 -瞳 -瞩 -瞪 -曙 -蹋 -蹈 -螺 -蟋 -蟀 -嚎 -赡 -穗 -魏 -簧 -簇 -繁 -徽 -爵 -朦 -臊 -鳄 -癌 -辫 -赢 -糟 -糠 -燥 -懦 -豁 -臀 -臂 -翼 -骤 -藕 -鞭 -藤 -覆 -瞻 -蹦 -嚣 -镰 -翻 -鳍 -鹰 -瀑 -襟 -璧 -戳 -孽 -警 -蘑 -藻 -攀 -曝 -蹲 -蹭 -蹬 -巅 -簸 -簿 -蟹 -颤 -靡 -癣 -瓣 -羹 -鳖 -爆 -疆 -鬓 -壤 -馨 -耀 -躁 -蠕 -嚼 -嚷 -巍 -籍 -鳞 -魔 -糯 -灌 -譬 -蠢 -霸 -露 -霹 -躏 -黯 -髓 -赣 -囊 -镶 -瓤 -罐 -矗 -乂 -乜 -兀 -弋 -孑 -孓 -幺 -亓 -韦 -廿 -丏 -卅 -仄 -厄 -仃 -仉 -仂 -兮 -刈 -爻 -卞 -闩 -讣 -尹 -夬 -爿 -毋 -邗 -邛 -艽 -艿 -札 -叵 -匝 -丕 -匜 -劢 -卟 -叱 -叻 -仨 -仕 -仟 -仡 -仫 -仞 -卮 -氐 -犰 -刍 -邝 -邙 -汀 -讦 -讧 -讪 -讫 -尻 -阡 -尕 -弁 -驭 -匡 -耒 -玎 -玑 -邢 -圩 -圬 -圭 -扦 -圪 -圳 -圹 -扪 -圮 -圯 -芊 -芍 -芄 -芨 -芑 -芎 -芗 -亘 -厍 -夼 -戍 -尥 -乩 -旯 -曳 -岌 -屺 -凼 -囡 -钇 -缶 -氘 -氖 -牝 -伎 -伛 -伢 -佤 -仵 -伥 -伧 -伉 -伫 -囟 -汆 -刖 -夙 -旮 -刎 -犷 -犸 -舛 -凫 -邬 -饧 -汕 -汔 -汐 -汲 -汜 -汊 -忖 -忏 -讴 -讵 -祁 -讷 -聿 -艮 -厾 -阱 -阮 -阪 -丞 -妁 -牟 -纡 -纣 -纥 -纨 -玕 -玙 -抟 -抔 -圻 -坂 -坍 -坞 -抃 -抉 -㧐 -芫 -邯 -芸 -芾 -苈 -苣 -芷 -芮 -苋 -芼 -苌 -苁 -芩 -芪 -芡 -芟 -苄 -苎 -苡 -杌 -杓 -杞 -杈 -忑 -孛 -邴 -邳 -矶 -奁 -豕 -忒 -欤 -轫 -迓 -邶 -忐 -卣 -邺 -旰 -呋 -呒 -呓 -呔 -呖 -呃 -旸 -吡 -町 -虬 -呗 -吽 -吣 -吲 -帏 -岐 -岈 -岘 -岑 -岚 -兕 -囵 -囫 -钊 -钋 -钌 -迕 -氙 -氚 -牤 -佞 -邱 -攸 -佚 -佝 -佟 -佗 -伽 -彷 -佘 -佥 -孚 -豸 -坌 -肟 -邸 -奂 -劬 -狄 -狁 -鸠 -邹 -饨 -饩 -饪 -饫 -饬 -亨 -庑 -庋 -疔 -疖 -肓 -闱 -闳 -闵 -羌 -炀 -沣 -沅 -沔 -沤 -沌 -沏 -沚 -汩 -汨 -沂 -汾 -沨 -汴 -汶 -沆 -沩 -泐 -怃 -怄 -忡 -忤 -忾 -怅 -忻 -忪 -怆 -忭 -忸 -诂 -诃 -诅 -诋 -诌 -诏 -诒 -孜 -陇 -陀 -陂 -陉 -妍 -妩 -妪 -妣 -妊 -妗 -妫 -妞 -姒 -妤 -邵 -劭 -刭 -甬 -邰 -纭 -纰 -纴 -纶 -纾 -玮 -玡 -玭 -玠 -玢 -玥 -玦 -盂 -忝 -匦 -坩 -抨 -拤 -坫 -拈 -垆 -抻 -劼 -拃 -拊 -坼 -坻 -㧟 -坨 -坭 -抿 -坳 -耶 -苷 -苯 -苤 -茏 -苫 -苜 -苴 -苒 -苘 -茌 -苻 -苓 -茚 -茆 -茑 -茓 -茔 -茕 -茀 -苕 -枥 -枇 -杪 -杳 -枧 -杵 -枨 -枞 -枋 -杻 -杷 -杼 -矸 -砀 -刳 -奄 -瓯 -殁 -郏 -轭 -郅 -鸢 -盱 -昊 -昙 -杲 -昃 -咂 -呸 -昕 -昀 -旻 -昉 -炅 -咔 -畀 -虮 -咀 -呷 -黾 -呱 -呤 -咚 -咆 -咛 -呶 -呣 -呦 -咝 -岢 -岿 -岬 -岫 -帙 -岣 -峁 -刿 -迥 -岷 -剀 -帔 -峄 -沓 -囹 -罔 -钍 -钎 -钏 -钒 -钕 -钗 -邾 -迮 -牦 -竺 -迤 -佶 -佬 -佰 -侑 -侉 -臾 -岱 -侗 -侃 -侏 -侩 -佻 -佾 -侪 -佼 -佯 -侬 -帛 -阜 -侔 -徂 -刽 -郄 -怂 -籴 -瓮 -戗 -肼 -䏝 -肽 -肱 -肫 -剁 -迩 -郇 -狙 -狎 -狍 -狒 -咎 -炙 -枭 -饯 -饴 -冽 -冼 -庖 -疠 -疝 -疡 -兖 -妾 -劾 -炜 -𬉼 -炖 -炘 -炝 -炔 -泔 -沭 -泷 -泸 -泱 -泅 -泗 -泠 -泺 -泖 -泫 -泮 -沱 -泯 -泓 -泾 -怙 -怵 -怦 -怛 -怏 -怍 -㤘 -怩 -怫 -怿 -宕 -穹 -宓 -诓 -诔 -诖 -诘 -戾 -诙 -戽 -郓 -衩 -祆 -祎 -祉 -祇 -诛 -诜 -诟 -诠 -诣 -诤 -诧 -诨 -诩 -戕 -孢 -亟 -陔 -妲 -妯 -姗 -帑 -弩 -孥 -驽 -虱 -迦 -迨 -绀 -绁 -绂 -驷 -驸 -绉 -绌 -驿 -骀 -甾 -珏 -珐 -珂 -珑 -玳 -珀 -顸 -珉 -珈 -拮 -垭 -挝 -垣 -挞 -垤 -赳 -贲 -垱 -垌 -郝 -垧 -垓 -挦 -垠 -茜 -荚 -荑 -贳 -荜 -莒 -茼 -茴 -茱 -莛 -荞 -茯 -荏 -荇 -荃 -荟 -荀 -茗 -荠 -茭 -茨 -垩 -荥 -荦 -荨 -荩 -剋 -荪 -茹 -荬 -荮 -柰 -栉 -柯 -柘 -栊 -柩 -枰 -栌 -柙 -枵 -柚 -枳 -柞 -柝 -栀 -柢 -栎 -枸 -柈 -柁 -枷 -柽 -剌 -酊 -郦 -甭 -砗 -砘 -砒 -斫 -砭 -砜 -奎 -耷 -虺 -殂 -殇 -殄 -殆 -轱 -轲 -轳 -轶 -轸 -虿 -毖 -觇 -尜 -哐 -眄 -眍 -𠳐 -郢 -眇 -眊 -眈 -禺 -哂 -咴 -曷 -昴 -昱 -昵 -咦 -哓 -哔 -畎 -毗 -呲 -胄 -畋 -畈 -虼 -虻 -盅 -咣 -哕 -剐 -郧 -咻 -囿 -咿 -哌 -哙 -哚 -咯 -咩 -咤 -哝 -哏 -哞 -峙 -峣 -罘 -帧 -峒 -峤 -峋 -峥 -贶 -钚 -钛 -钡 -钣 -钤 -钨 -钫 -钯 -氡 -氟 -牯 -郜 -秕 -秭 -竽 -笈 -笃 -俦 -俨 -俅 -俪 -叟 -垡 -牮 -俣 -俚 -皈 -俑 -俟 -逅 -徇 -徉 -舢 -俞 -郗 -俎 -郤 -爰 -郛 -瓴 -胨 -胪 -胛 -胂 -胙 -胍 -胗 -胝 -朐 -胫 -鸨 -匍 -狨 -狯 -飑 -狩 -狲 -訇 -逄 -昝 -饷 -饸 -饹 -胤 -孪 -娈 -弈 -奕 -庥 -疬 -疣 -疥 -疭 -庠 -竑 -彦 -飒 -闼 -闾 -闿 -阂 -羑 -迸 -籼 -酋 -炳 -炻 -炽 -炯 -烀 -炷 -烃 -洱 -洹 -洧 -洌 -浃 -洇 -洄 -洙 -涎 -洎 -洫 -浍 -洮 -洵 -浒 -浔 -浕 -洳 -恸 -恓 -恹 -恫 -恺 -恻 -恂 -恪 -恽 -宥 -扃 -衲 -衽 -衿 -袂 -祛 -祜 -祓 -祚 -诮 -祗 -祢 -诰 -诳 -鸩 -昶 -郡 -咫 -弭 -牁 -胥 -陛 -陟 -娅 -姮 -娆 -姝 -姣 -姘 -姹 -怼 -羿 -炱 -矜 -绔 -骁 -骅 -绗 -绛 -骈 -耖 -挈 -珥 -珙 -顼 -珰 -珩 -珧 -珣 -珞 -琤 -珲 -敖 -恚 -埔 -埕 -埘 -埙 -埚 -挹 -耆 -耄 -埒 -捋 -贽 -垸 -捃 -盍 -荸 -莆 -莳 -莴 -莪 -莠 -莓 -莜 -莅 -荼 -莩 -荽 -莸 -荻 -莘 -莎 -莞 -莨 -渇 -鸪 -莼 -栲 -栳 -郴 -桓 -桡 -桎 -桢 -桤 -梃 -栝 -桕 -桁 -桧 -桅 -栟 -桉 -栩 -逑 -逋 -彧 -鬲 -豇 -酐 -逦 -厝 -孬 -砝 -砹 -砺 -砧 -砷 -砟 -砼 -砥 -砣 -剞 -砻 -轼 -轾 -辂 -鸫 -趸 -龀 -鸬 -虔 -逍 -眬 -唛 -晟 -眩 -眙 -哧 -哽 -唔 -晁 -晏 -鸮 -趵 -趿 -畛 -蚨 -蚜 -蚍 -蚋 -蚬 -蚝 -蚧 -唢 -圄 -唣 -唏 -盎 -唑 -崂 -崃 -罡 -罟 -峪 -觊 -赅 -钰 -钲 -钴 -钵 -钹 -钺 -钽 -钼 -钿 -铀 -铂 -铄 -铆 -铈 -铉 -铊 -铋 -铌 -铍 -䥽 -铎 -氩 -氤 -氦 -毪 -舐 -秣 -秫 -盉 -笄 -笕 -笊 -笏 -笆 -俸 -倩 -俵 -偌 -俳 -俶 -倬 -倏 -恁 -倭 -倪 -俾 -倜 -隼 -隽 -倌 -倥 -臬 -皋 -郫 -倨 -衄 -颀 -徕 -舫 -釜 -奚 -衾 -胯 -胱 -胴 -胭 -脍 -胼 -朕 -脒 -胺 -鸱 -玺 -鸲 -狷 -猁 -狳 -猃 -狺 -逖 -桀 -袅 -饽 -凇 -栾 -挛 -亳 -疳 -疴 -疸 -疽 -痈 -疱 -痂 -痉 -衮 -凋 -颃 -恣 -旆 -旄 -旃 -阃 -阄 -訚 -阆 -恙 -粑 -朔 -郸 -烜 -烨 -烩 -烊 -剡 -郯 -烬 -涑 -浯 -涞 -涟 -娑 -涅 -涠 -浞 -涓 -浥 -涔 -浜 -浠 -浣 -浚 -悚 -悭 -悝 -悒 -悌 -悛 -宸 -窈 -剜 -诹 -冢 -诼 -袒 -袢 -祯 -诿 -谀 -谂 -谄 -谇 -屐 -屙 -陬 -勐 -奘 -牂 -蚩 -陲 -姬 -娠 -娌 -娉 -娲 -娩 -娴 -娣 -娓 -婀 -畚 -逡 -绠 -骊 -绡 -骋 -绥 -绦 -绨 -骎 -邕 -鸶 -彗 -耜 -焘 -舂 -琏 -琇 -麸 -揶 -埴 -埯 -捯 -掳 -掴 -埸 -埵 -赧 -埤 -捭 -逵 -埝 -堋 -堍 -掬 -鸷 -掖 -捽 -掊 -堉 -掸 -捩 -掮 -悫 -埭 -埽 -掇 -掼 -聃 -菁 -萁 -菘 -堇 -萘 -萋 -菽 -菖 -萜 -萸 -萑 -棻 -菔 -菟 -萏 -萃 -菏 -菹 -菪 -菅 -菀 -萦 -菰 -菡 -梵 -梿 -梏 -觋 -桴 -桷 -梓 -棁 -桫 -棂 -啬 -郾 -匮 -敕 -豉 -鄄 -酞 -酚 -戛 -硎 -硭 -硒 -硖 -硗 -硐 -硇 -硌 -鸸 -瓠 -匏 -厩 -龚 -殒 -殓 -殍 -赉 -雩 -辄 -堑 -眭 -眦 -啧 -晡 -晤 -眺 -眵 -眸 -圊 -喏 -喵 -啉 -勖 -晞 -唵 -晗 -冕 -啭 -畦 -趺 -啮 -跄 -蚶 -蛄 -蛎 -蛆 -蚰 -蛊 -圉 -蚱 -蛉 -蛏 -蚴 -啁 -啕 -唿 -啐 -唼 -唷 -啖 -啵 -啶 -啷 -唳 -唰 -啜 -帻 -崚 -崦 -帼 -崮 -崤 -崆 -赇 -赈 -赊 -铑 -铒 -铗 -铙 -铟 -铠 -铡 -铢 -铣 -铤 -铧 -铨 -铩 -铪 -铫 -铬 -铮 -铯 -铰 -铱 -铳 -铵 -铷 -氪 -牾 -鸹 -秾 -逶 -笺 -筇 -笸 -笪 -笮 -笠 -笥 -笤 -笳 -笾 -笞 -偾 -偃 -偕 -偈 -傀 -偬 -偻 -皑 -皎 -鸻 -徜 -舸 -舻 -舴 -舷 -龛 -翎 -脬 -脘 -脲 -匐 -猗 -猡 -猞 -猝 -斛 -猕 -馗 -馃 -馄 -鸾 -孰 -庹 -庾 -痔 -痍 -疵 -翊 -旌 -旎 -袤 -阇 -阈 -阉 -阊 -阋 -阍 -阏 -羟 -粝 -粕 -敝 -焐 -烯 -焓 -烽 -焖 -烷 -焗 -渍 -渚 -淇 -淅 -淞 -渎 -涿 -淖 -挲 -淠 -涸 -渑 -淦 -淝 -淬 -涪 -淙 -涫 -渌 -淄 -惬 -悻 -悱 -惝 -惘 -悸 -惆 -惚 -惇 -惮 -窕 -谌 -谏 -扈 -皲 -谑 -裆 -袷 -裉 -谒 -谔 -谕 -谖 -谗 -谙 -谛 -谝 -逯 -郿 -隈 -粜 -隍 -隗 -婧 -婊 -婕 -娼 -婢 -婵 -胬 -袈 -翌 -恿 -欸 -绫 -骐 -绮 -绯 -绱 -骒 -绲 -骓 -绶 -绺 -绻 -绾 -骖 -缁 -耠 -琫 -琵 -琶 -琪 -瑛 -琦 -琥 -琨 -靓 -琰 -琮 -琯 -琬 -琛 -琚 -辇 -鼋 -揳 -堞 -搽 -揸 -揠 -堙 -趄 -揖 -颉 -塄 -揿 -耋 -揄 -蛩 -蛰 -塆 -摒 -揆 -掾 -聒 -葑 -葚 -靰 -靸 -葳 -葺 -葸 -萼 -葆 -葩 -葶 -蒌 -萱 -戟 -葭 -楮 -棼 -椟 -棹 -椤 -棰 -赍 -椋 -椁 -椪 -棣 -椐 -鹁 -覃 -酤 -酢 -酡 -鹂 -厥 -殚 -殛 -雯 -雱 -辊 -辋 -椠 -辍 -辎 -斐 -睄 -睑 -睇 -睃 -戢 -喋 -嗒 -喃 -喱 -喹 -晷 -喈 -跖 -跗 -跞 -跚 -跎 -跏 -跆 -蛱 -蛲 -蛭 -蛳 -蛐 -蛔 -蛞 -蛴 -蛟 -蛘 -喁 -喟 -啾 -嗖 -喑 -嗟 -喽 -嗞 -喀 -喔 -喙 -嵘 -嵖 -崴 -遄 -詈 -嵎 -崽 -嵬 -嵛 -嵯 -嵝 -嵫 -幄 -嵋 -赕 -铻 -铼 -铿 -锃 -锂 -锆 -锇 -锉 -锏 -锑 -锒 -锔 -锕 -掣 -矬 -氰 -毳 -毽 -犊 -犄 -犋 -鹄 -犍 -嵇 -黍 -稃 -稂 -筚 -筵 -筌 -傣 -傈 -舄 -牍 -傥 -傧 -遑 -傩 -遁 -徨 -媭 -畲 -弑 -颌 -翕 -釉 -鹆 -舜 -貂 -腈 -腌 -腓 -腆 -腴 -腑 -腚 -腱 -鱿 -鲀 -鲂 -颍 -猢 -猹 -猥 -飓 -觞 -觚 -猱 -颎 -飧 -馇 -馊 -亵 -脔 -裒 -痣 -痨 -痦 -痞 -痤 -痫 -痧 -赓 -竦 -瓿 -啻 -颏 -鹇 -阑 -阒 -阕 -粞 -遒 -孳 -焯 -焜 -焙 -焱 -鹈 -湛 -渫 -湮 -湎 -湜 -渭 -湍 -湫 -溲 -湟 -溆 -湲 -湔 -湉 -渥 -湄 -滁 -愠 -惺 -愦 -惴 -愀 -愎 -愔 -喾 -寐 -谟 -扉 -裢 -裎 -裥 -祾 -祺 -谠 -幂 -谡 -谥 -谧 -遐 -孱 -弼 -巽 -骘 -媪 -媛 -婷 -巯 -翚 -皴 -婺 -骛 -缂 -缃 -缄 -彘 -缇 -缈 -缌 -缑 -缒 -缗 -飨 -耢 -瑚 -瑁 -瑜 -瑗 -瑄 -瑕 -遨 -骜 -韫 -髡 -塬 -鄢 -趔 -趑 -摅 -摁 -蜇 -搋 -搪 -搐 -搛 -搠 -摈 -彀 -毂 -搦 -搡 -蓁 -戡 -蓍 -鄞 -靳 -蓐 -蓦 -鹋 -蒽 -蓓 -蓖 -蓊 -蒯 -蓟 -蓑 -蒿 -蒺 -蓠 -蒟 -蒡 -蒹 -蒴 -蒗 -蓥 -颐 -楔 -楠 -楂 -楝 -楫 -楸 -椴 -槌 -楯 -皙 -榈 -槎 -榉 -楦 -楣 -楹 -椽 -裘 -剽 -甄 -酮 -酰 -酯 -酩 -蜃 -碛 -碓 -硼 -碉 -碚 -碇 -碜 -鹌 -辏 -龃 -龅 -訾 -粲 -虞 -睚 -嗪 -韪 -嗷 -嗉 -睨 -睢 -雎 -睥 -嘟 -嗑 -嗫 -嗬 -嗔 -嗝 -戥 -嗄 -煦 -暄 -遢 -暌 -跬 -跶 -跸 -跐 -跣 -跹 -跻 -蛸 -蜊 -蜍 -蜉 -蜣 -畹 -蛹 -嗣 -嗯 -嗥 -嗲 -嗳 -嗌 -嗍 -嗨 -嗐 -嗤 -嗵 -罨 -嵊 -嵩 -嵴 -骰 -锗 -锛 -锜 -锝 -锞 -锟 -锢 -锨 -锩 -锭 -锱 -雉 -氲 -犏 -歃 -稞 -稗 -稔 -筠 -筢 -筮 -筲 -筱 -牒 -煲 -敫 -徭 -愆 -艄 -觎 -毹 -貊 -貅 -貉 -颔 -腠 -腩 -腼 -腭 -腧 -塍 -媵 -詹 -鲅 -鲆 -鲇 -鲈 -稣 -鲋 -鲐 -肄 -鹐 -飕 -觥 -遛 -馐 -鹑 -亶 -瘃 -痱 -痼 -痿 -瘐 -瘁 -瘆 -麂 -裔 -歆 -旒 -雍 -阖 -阗 -阙 -羧 -豢 -粳 -猷 -煳 -煜 -煨 -煅 -煊 -煸 -煺 -滟 -溱 -溘 -漭 -滢 -溥 -溧 -溽 -裟 -溻 -溷 -滗 -滫 -溴 -滏 -滃 -滦 -溏 -滂 -滓 -溟 -滪 -愫 -慑 -慊 -鲎 -骞 -窦 -窠 -窣 -裱 -褚 -裨 -裾 -裰 -禊 -谩 -谪 -媾 -嫫 -媲 -嫒 -嫔 -媸 -缙 -缜 -缛 -辔 -骝 -缟 -缡 -缢 -缣 -骟 -耥 -璈 -瑶 -瑭 -獒 -觏 -慝 -嫠 -韬 -叆 -髦 -摽 -墁 -撂 -摞 -撄 -翥 -踅 -摭 -墉 -墒 -榖 -綦 -蔫 -蔷 -靺 -靼 -鞅 -靿 -甍 -蔸 -蔟 -蔺 -戬 -蕖 -蔻 -蓿 -斡 -鹕 -蓼 -榛 -榧 -榻 -榫 -榭 -槔 -榱 -槁 -槟 -槠 -榷 -僰 -酽 -酶 -酹 -厮 -碡 -碴 -碣 -碲 -磋 -臧 -豨 -殡 -霆 -霁 -辕 -蜚 -裴 -翡 -龇 -龈 -睿 -䁖 -睽 -嘞 -嘈 -嘌 -嘁 -嘎 -暧 -暝 -踌 -踉 -蜞 -蜥 -蜮 -蝈 -蜴 -蜱 -蜩 -蜷 -蜿 -螂 -蜢 -嘘 -嘡 -鹗 -嘣 -嘤 -嘚 -嗾 -嘧 -罴 -罱 -幔 -嶂 -幛 -赙 -罂 -骷 -骶 -鹘 -锲 -锴 -锶 -锷 -锸 -锵 -镁 -镂 -犒 -箐 -箦 -箧 -箍 -箸 -箬 -箅 -箪 -箔 -箜 -箢 -箓 -毓 -僖 -儆 -僳 -僭 -劁 -僮 -魃 -魆 -睾 -艋 -鄱 -膈 -膑 -鲑 -鲔 -鲚 -鲛 -鲟 -獐 -觫 -雒 -夤 -馑 -銮 -塾 -麽 -瘌 -瘊 -瘘 -瘙 -廖 -韶 -旖 -膂 -阚 -鄯 -鲞 -粿 -粼 -粽 -糁 -槊 -鹚 -熘 -熥 -潢 -漕 -滹 -漯 -漶 -潋 -潴 -漪 -漉 -漳 -漩 -澉 -潍 -慵 -搴 -窨 -寤 -綮 -谮 -褡 -褙 -褓 -褛 -褊 -谯 -谰 -谲 -暨 -屣 -鹛 -嫣 -嫱 -嫖 -嫦 -嫚 -嫘 -嫡 -鼐 -翟 -瞀 -鹜 -骠 -缥 -缦 -缧 -缨 -骢 -缪 -缫 -耦 -耧 -瑾 -璜 -璀 -璎 -璁 -璋 -璇 -奭 -髯 -髫 -撷 -撅 -赭 -撸 -鋆 -撙 -撺 -墀 -聩 -觐 -鞑 -蕙 -鞒 -蕈 -蕨 -蕤 -蕞 -蕺 -瞢 -蕃 -蕲 -赜 -槿 -樯 -槭 -樗 -樘 -樊 -槲 -醌 -醅 -靥 -魇 -餍 -磔 -磙 -霈 -辘 -龉 -龊 -觑 -瞌 -瞋 -瞑 -嘭 -噎 -噶 -颙 -暹 -噘 -踔 -踝 -踟 -踒 -踬 -踮 -踯 -踺 -踞 -蝽 -蝾 -蝻 -蝰 -蝮 -螋 -蝓 -蝣 -蝼 -噗 -嘬 -颚 -噍 -噢 -噙 -噜 -噌 -噔 -颛 -幞 -幡 -嶙 -嶝 -骺 -骼 -骸 -镊 -镉 -镌 -镍 -镏 -镒 -镓 -镔 -稷 -箴 -篑 -篁 -篌 -篆 -牖 -儋 -徵 -磐 -虢 -鹞 -膘 -滕 -鲠 -鲡 -鲢 -鲣 -鲥 -鲧 -鲩 -獗 -獠 -觯 -馓 -馔 -麾 -廛 -瘛 -瘼 -瘢 -瘠 -齑 -羯 -羰 -𥻗 -遴 -糌 -糍 -糅 -熜 -熵 -熠 -澍 -澌 -潸 -潦 -潲 -鋈 -潟 -潼 -潺 -憬 -憧 -寮 -窳 -谳 -褴 -褟 -褫 -谵 -熨 -屦 -嬉 -勰 -戮 -蝥 -缬 -缮 -缯 -骣 -畿 -耩 -耨 -耪 -璞 -璟 -靛 -璠 -璘 -聱 -螯 -髻 -髭 -髹 -擀 -熹 -甏 -擞 -縠 -磬 -颞 -蕻 -鞘 -颟 -薤 -薨 -檠 -薏 -薮 -薜 -薅 -樾 -橛 -橇 -樵 -檎 -橹 -樽 -樨 -橼 -墼 -橐 -翮 -醛 -醐 -醍 -醚 -磲 -赝 -飙 -殪 -霖 -霏 -霓 -錾 -辚 -臻 -遽 -氅 -瞟 -瞠 -瞰 -嚄 -嚆 -噤 -暾 -蹀 -踹 -踵 -踽 -蹉 -蹁 -螨 -蟒 -螈 -螅 -螭 -螠 -螟 -噱 -噬 -噫 -噻 -噼 -罹 -圜 -䦃 -镖 -镗 -镘 -镚 -镛 -镝 -镞 -镠 -氇 -氆 -憩 -穑 -篝 -篥 -篦 -篪 -篙 -盥 -劓 -翱 -魉 -魈 -徼 -歙 -膳 -膦 -膙 -鲮 -鲱 -鲲 -鲳 -鲴 -鲵 -鲷 -鲻 -獴 -獭 -獬 -邂 -鹧 -廨 -赟 -瘰 -廪 -瘿 -瘵 -瘴 -癃 -瘳 -斓 -麇 -麈 -嬴 -壅 -羲 -糗 -瞥 -甑 -燎 -燠 -燔 -燧 -濑 -濉 -潞 -澧 -澹 -澥 -澶 -濂 -褰 -寰 -窸 -褶 -禧 -嬖 -犟 -隰 -嬗 -颡 -缱 -缲 -缳 -璨 -璩 -璐 -璪 -螫 -擤 -壕 -觳 -罄 -擢 -薹 -鞡 -鞬 -薷 -薰 -藓 -藁 -檄 -檩 -懋 -醢 -翳 -礅 -磴 -鹩 -龋 -龌 -豳 -壑 -黻 -嚏 -嚅 -蹑 -蹒 -蹊 -蟥 -螬 -螵 -疃 -螳 -蟑 -嚓 -羁 -罽 -罾 -嶷 -黜 -黝 -髁 -髀 -镡 -镢 -镣 -镦 -镧 -镩 -镪 -镫 -罅 -黏 -簌 -篾 -篼 -簖 -簋 -鼢 -黛 -儡 -鹪 -鼾 -皤 -魍 -龠 -繇 -貘 -邈 -貔 -臌 -膻 -臆 -臃 -鲼 -鲽 -鳀 -鳃 -鳅 -鳇 -鳊 -螽 -燮 -鹫 -襄 -糜 -縻 -膺 -癍 -麋 -懑 -濡 -濮 -濞 -濠 -濯 -蹇 -謇 -邃 -襁 -檗 -擘 -孺 -隳 -嬷 -蟊 -鹬 -鍪 -鏊 -鳌 -鬈 -鬃 -瞽 -鞯 -鞨 -鞫 -鞧 -鞣 -藜 -藠 -藩 -醪 -蹙 -礓 -燹 -餮 -瞿 -曛 -颢 -曜 -躇 -蹚 -鹭 -蟛 -蟪 -蟠 -蟮 -鹮 -黠 -黟 -髅 -髂 -镬 -镭 -镯 -馥 -簟 -簪 -鼬 -雠 -艟 -鳎 -鳏 -鳐 -癞 -癔 -癜 -癖 -糨 -蹩 -鎏 -懵 -彝 -邋 -鬏 -攉 -攒 -鞲 -鞴 -藿 -蘧 -蘅 -麓 -醮 -醯 -酃 -霪 -霭 -霨 -黼 -嚯 -蹰 -蹶 -蹽 -蹼 -蹴 -蹾 -蹿 -蠖 -蠓 -蟾 -蠊 -黢 -髋 -髌 -镲 -籀 -籁 -齁 -魑 -艨 -鳓 -鳔 -鳕 -鳗 -鳙 -麒 -鏖 -羸 -㸆 -瀚 -瀣 -瀛 -襦 -谶 -襞 -骥 -缵 -瓒 -攘 -蘩 -蘖 -醴 -霰 -酆 -矍 -曦 -躅 -鼍 -巉 -黩 -黥 -黪 -镳 -镴 -黧 -纂 -璺 -鼯 -臜 -鳜 -鳝 -鳟 -獾 -孀 -骧 -瓘 -鼙 -醺 -礴 -颦 -曩 -鳢 -癫 -麝 -夔 -爝 -灏 -禳 -鐾 -羼 -蠡 -耱 -懿 -蘸 -鹳 -霾 -氍 -饕 -躐 -髑 -镵 -穰 -饔 -鬻 -鬟 -趱 -攫 -攥 -颧 -躜 -鼹 -癯 -麟 -蠲 -蠹 -躞 -衢 -鑫 -灞 -襻 -纛 -鬣 -攮 -囔 -馕 -戆 -爨 -齉 -亍 -尢 -彳 -卬 -殳 -𠙶 -毌 -邘 -戋 -圢 -氕 -伋 -仝 -冮 -氿 -汈 -氾 -忉 -宄 -讱 -扞 -圲 -圫 -芏 -芃 -朳 -朸 -𨙸 -邨 -吒 -吖 -屼 -屾 -辿 -钆 -仳 -伣 -伈 -癿 -甪 -邠 -犴 -冱 -邡 -闫 -汋 -䜣 -讻 -孖 -纩 -玒 -玓 -玘 -玚 -刬 -坜 -坉 -扽 -坋 -扺 -㧑 -毐 -芰 -芣 -苊 -苉 -芘 -芴 -芠 -芤 -杕 -杙 -杄 -杧 -杩 -尪 -尨 -轪 -坒 -芈 -旴 -旵 -呙 -㕮 -岍 -岠 -岜 -呇 -冏 -觃 -岙 -伾 -㑇 -伭 -佖 -伲 -佁 -飏 -狃 -闶 -汧 -汫 -𣲘 -𣲗 -沄 -沘 -汭 -㳇 -沇 -忮 -忳 -忺 -祃 -诇 -邲 -诎 -诐 -屃 -岊 -阽 -䢺 -阼 -妧 -妘 -𨚕 -纮 -驲 -纻 -纼 -玤 -玞 -玱 -玟 -邽 -邿 -坥 -坰 -坬 -坽 -弆 -耵 -䢼 -𦭜 -茋 -苧 -苾 -苠 -枅 -㭎 -枘 -枍 -矼 -矻 -匼 -旿 -昇 -昄 -昒 -昈 -咉 -咇 -咍 -岵 -岽 -岨 -岞 -峂 -㟃 -囷 -钐 -钔 -钖 -牥 -佴 -垈 -侁 -侹 -佸 -佺 -隹 -㑊 -侂 -佽 -侘 -郈 -舠 -郐 -郃 -攽 -肭 -肸 -肷 -狉 -狝 -饳 -忞 -於 -炌 -炆 -泙 -沺 -泂 -泜 -泃 -泇 -怊 -峃 -穸 -祋 -祊 -鸤 -弢 -弨 -陑 -陎 -卺 -乸 -妭 -姈 -迳 -叕 -驵 -䌹 -驺 -绋 -绐 -砉 -耔 -㛃 -玶 -珇 -珅 -珋 -玹 -珌 -玿 -韨 -垚 -垯 -垙 -垲 -埏 -垍 -耇 -垎 -垴 -垟 -垞 -挓 -垵 -垏 -拶 -荖 -荁 -荙 -荛 -茈 -茽 -荄 -茺 -荓 -茳 -𦰡 -茛 -荭 -㭕 -柷 -柃 -柊 -枹 -栐 -柖 -郚 -剅 -䴓 -迺 -厖 -砆 -砑 -砄 -耏 -奓 -䶮 -轵 -轷 -轹 -轺 -昺 -昽 -盷 -咡 -咺 -昳 -昣 -哒 -昤 -昫 -昡 -咥 -昪 -虷 -虸 -哃 -峘 -耑 -峛 -峗 -峧 -帡 -钘 -钜 -钪 -钬 -钭 -矧 -秬 -俫 -舁 -俜 -俙 -俍 -垕 -衎 -舣 -弇 -侴 -鸧 -䏡 -胠 -𦙶 -胈 -胩 -胣 -朏 -飐 -訄 -饻 -庤 -疢 -炣 -炟 -㶲 -洭 -洘 -洓 -洿 -㳚 -泚 -浈 -浉 -洸 -洑 -洢 -洈 -洚 -洺 -洨 -浐 -㳘 -洴 -洣 -恔 -宬 -窀 -扂 -袆 -祏 -祐 -祕 -叚 -陧 -陞 -娀 -姞 -姱 -姤 -姶 -姽 -枲 -绖 -骃 -彖 -骉 -恝 -珪 -珛 -珹 -琊 -玼 -珖 -珽 -珦 -珫 -珒 -珢 -珕 -珝 -埗 -垾 -垺 -埆 -垿 -埌 -埇 -莰 -茝 -鄀 -莶 -莝 -䓖 -莙 -栻 -桠 -桄 -梠 -栴 -梴 -栒 -酎 -酏 -砵 -砠 -砫 -砬 -硁 -恧 -翃 -郪 -𨐈 -辀 -辁 -剕 -赀 -哢 -晅 -晊 -唝 -哳 -哱 -冔 -晔 -晐 -晖 -畖 -蚄 -蚆 -帱 -崁 -峿 -崄 -帨 -崀 -赆 -钷 -眚 -甡 -笫 -倻 -倴 -脩 -倮 -倕 -倞 -倓 -倧 -衃 -虒 -舭 -舯 -舥 -瓞 -鬯 -鸰 -脎 -朓 -胲 -虓 -鱽 -狴 -峱 -狻 -眢 -勍 -痄 -疰 -痃 -竘 -羖 -羓 -桊 -敉 -烠 -烔 -烶 -烻 -涍 -浡 -浭 -浬 -涄 -涢 -涐 -浰 -浟 -浛 -浼 -浲 -涘 -悈 -悃 -悢 -宧 -窅 -窊 -窎 -扅 -扆 -袪 -袗 -袯 -祧 -隺 -堲 -疍 -𨺙 -陴 -烝 -砮 -㛚 -哿 -翀 -翂 -剟 -绤 -骍 -䂮 -琎 -珸 -珵 -琄 -琈 -琀 -珺 -掭 -堎 -堐 -埼 -掎 -埫 -堌 -晢 -掞 -埪 -壸 -㙍 -聍 -菝 -萚 -菥 -莿 -䓫 -勚 -䓬 -萆 -菂 -菍 -菼 -萣 -䓨 -菉 -䓛 -梼 -梽 -桲 -梾 -桯 -梣 -梌 -桹 -敔 -厣 -硔 -硙 -硚 -硊 -硍 -勔 -䴕 -龁 -逴 -唪 -啫 -翈 -㫰 -晙 -畤 -趼 -跂 -蛃 -蚲 -蚺 -啴 -䎃 -崧 -崟 -崞 -崒 -崌 -崡 -铏 -铕 -铖 -铘 -铚 -铞 -铥 -铴 -牻 -牿 -稆 -笱 -笯 -偰 -偡 -鸺 -偭 -偲 -偁 -㿠 -鄅 -偓 -徛 -衒 -舳 -舲 -鸼 -悆 -鄃 -瓻 -䝙 -脶 -脞 -脟 -䏲 -鱾 -猇 -猊 -猄 -觖 -𠅤 -庱 -庼 -庳 -痓 -䴔 -竫 -堃 -阌 -羝 -羕 -焆 -烺 -焌 -淏 -淟 -淜 -淴 -淯 -湴 -涴 -㥄 -惛 -惔 -悰 -惙 -寁 -逭 -袼 -裈 -祲 -谞 -艴 -弸 -弶 -隃 -婞 -娵 -婼 -媖 -婳 -婍 -婌 -婫 -婤 -婘 -婠 -绹 -骕 -絜 -珷 -琲 -琡 -琟 -琔 -琭 -堾 -堼 -揕 -㙘 -堧 -喆 -堨 -塅 -堠 -絷 -𡎚 -葜 -惎 -萳 -葙 -靬 -葴 -蒇 -蒈 -鄚 -蒉 -蓇 -萩 -蒐 -葰 -葎 -鄑 -蒎 -葖 -蒄 -萹 -棤 -棽 -棫 -椓 -椑 -鹀 -椆 -棓 -棬 -棪 -椀 -楗 -甦 -酦 -觌 -奡 -皕 -硪 -欹 -詟 -辌 -棐 -龂 -黹 -牚 -睎 -晫 -晪 -晱 -𧿹 -蛑 -畯 -斝 -喤 -崶 -嵁 -崾 -嵅 -崿 -嵚 -翙 -圌 -圐 -赑 -淼 -赒 -铹 -铽 -𨱇 -锊 -锍 -锎 -锓 -犇 -颋 -稌 -筀 -筘 -筜 -筥 -筅 -傃 -傉 -翛 -傒 -傕 -舾 -畬 -脿 -腘 -䐃 -腙 -腒 -鲃 -猰 -猯 -㺄 -馉 -鄗 -廋 -廆 -鄌 -粢 -遆 -旐 -焞 -欻 -𣸣 -溚 -溁 -湝 -渰 -湓 -㴔 -渟 -溠 -渼 -溇 -湣 -湑 -溞 -愐 -愃 -敩 -甯 -棨 -扊 -裣 -祼 -婻 -媆 -媞 -㛹 -媓 -媂 -媄 -毵 -矞 -缊 -缐 -骙 -瑃 -瑓 -瑅 -瑆 -䴖 -瑖 -瑝 -瑔 -瑀 -𤧛 -瑳 -瑂 -嶅 -瑑 -遘 -髢 -塥 -堽 -赪 -摛 -塝 -搒 -搌 -蒱 -蒨 -蓏 -蔀 -蓢 -蓂 -蒻 -蓣 -椹 -楪 -榃 -榅 -楒 -楞 -楩 -榇 -椸 -楙 -歅 -碃 -碏 -碈 -䃅 -硿 -鄠 -辒 -龆 -觜 -䣘 -暕 -鹍 -㬊 -暅 -跱 -蜐 -蜎 -嵲 -赗 -骱 -锖 -锘 -锳 -锧 -锪 -锫 -锬 -稑 -稙 -䅟 -筻 -筼 -筶 -筦 -筤 -傺 -鹎 -僇 -艅 -艉 -谼 -貆 -腽 -腨 -腯 -鲉 -鲊 -鲌 -䲟 -鲏 -雊 -猺 -飔 -觟 -𦝼 -馌 -裛 -廒 -瘀 -瘅 -鄘 -鹒 -鄜 -麀 -鄣 -阘 -煁 -煃 -煴 -煋 -煟 -煓 -滠 -溍 -溹 -滆 -滉 -溦 -溵 -漷 -滧 -滘 -滍 -愭 -慥 -慆 -塱 -裼 -禋 -禔 -禘 -禒 -谫 -鹔 -愍 -嫄 -媱 -戤 -戣 -缞 -耤 -瑧 -瑨 -瑱 -瑷 -瑢 -斠 -摏 -墕 -墈 -墐 -墘 -摴 -銎 -𡐓 -墚 -撖 -靽 -鞁 -蔌 -蔈 -蓰 -蔹 -蔊 -嘏 -榰 -榑 -槚 -𣗋 -槜 -榍 -疐 -酺 -酾 -酲 -酴 -碶 -䃎 -碨 -𥔲 -碹 -碥 -劂 -䴗 -夥 -瞍 -鹖 -㬎 -跽 -蜾 -幖 -嶍 -圙 -𨱏 -锺 -锼 -锽 -锾 -锿 -镃 -镄 -镅 -馝 -鹙 -箨 -箖 -劄 -僬 -僦 -僔 -僎 -槃 -㙦 -鲒 -鲕 -鲖 -鲗 -鲘 -鲙 -𩽾 -夐 -獍 -飗 -凘 -廑 -廙 -瘗 -瘥 -瘕 -鲝 -鄫 -熇 -漹 -漖 -潆 -漤 -潩 -漼 -漴 -㽏 -漈 -漋 -漻 -慬 -窬 -窭 -㮾 -褕 -禛 -禚 -隩 -嫕 -嫭 -嫜 -嫪 -㻬 -麹 -璆 -漦 -叇 -墣 -墦 -墡 -劐 -薁 -蕰 -蔃 -鼒 -槱 -鹝 -磏 -磉 -殣 -慭 -霅 -暵 -暲 -暶 -踦 -踣 -䗖 -蝘 -蝲 -蝤 -噇 -噂 -噀 -罶 -嶲 -嶓 -㠇 -嶟 -嶒 -镆 -镈 -镋 -镎 -镕 -稹 -儇 -皞 -皛 -䴘 -艎 -艏 -鹟 -𩾃 -鲦 -鲪 -鲬 -橥 -觭 -鹠 -鹡 -糇 -糈 -翦 -鹢 -鹣 -熛 -潖 -潵 -㵐 -澂 -澛 -瑬 -潽 -潾 -潏 -憭 -憕 -戭 -褯 -禤 -嫽 -遹 -璥 -璲 -璒 -憙 -擐 -鄹 -薳 -鞔 -黇 -蕗 -薢 -蕹 -橞 -橑 -橦 -醑 -觱 -磡 -𥕢 -磜 -豮 -鹾 -虤 -暿 -曌 -曈 -㬚 -蹅 -踶 -䗛 -螗 -疁 -㠓 -幪 -嶦 -𨱑 -馞 -穄 -篚 -篯 -簉 -鼽 -衠 -盦 -螣 -縢 -鲭 -鲯 -鲰 -鲺 -鲹 -亸 -癀 -瘭 -羱 -糒 -燋 -熻 -燊 -燚 -燏 -濩 -濋 -澪 -澽 -澴 -澭 -澼 -憷 -憺 -懔 -黉 -嬛 -鹨 -翯 -璱 -𤩽 -璬 -璮 -髽 -擿 -薿 -薸 -檑 -櫆 -檞 -醨 -繄 -磹 -磻 -瞫 -瞵 -蹐 -蟏 -㘎 -镤 -镥 -镨 -𨱔 -矰 -穙 -穜 -穟 -簕 -簃 -簏 -儦 -魋 -斶 -艚 -谿 -䲠 -鲾 -鲿 -鳁 -鳂 -鳈 -鳉 -獯 -䗪 -馘 -襕 -襚 -螱 -甓 -嬬 -嬥 -𦈡 -瓀 -釐 -鬶 -爇 -鞳 -鞮 -藟 -藦 -藨 -鹲 -檫 -黡 -礞 -礌 -𥖨 -蹢 -蹜 -蟫 -䗴 -嚚 -髃 -镮 -镱 -酂 -馧 -簠 -簝 -簰 -鼫 -鼩 -皦 -臑 -䲢 -鳑 -鳒 -鹱 -鹯 -癗 -𦒍 -旞 -翷 -冁 -䎖 -瀔 -瀍 -瀌 -襜 -䴙 -嚭 -㰀 -鬷 -醭 -蹯 -蠋 -翾 -鳘 -儳 -儴 -鼗 -𩾌 -鳚 -鳛 -麑 -麖 -蠃 -彟 -嬿 -鬒 -蘘 -欂 -醵 -颥 -甗 -𨟠 -巇 -酅 -髎 -犨 -𨭉 -㸌 -爔 -瀱 -瀹 -瀼 -瀵 -襫 -孅 -骦 -耰 -𤫉 -瓖 -鬘 -趯 -罍 -鼱 -鳠 -鳡 -鳣 -爟 -爚 -灈 -韂 -糵 -蘼 -礵 -鹴 -躔 -皭 -龢 -鳤 -亹 -籥 -鼷 -玃 -醾 -齇 -觿 -蠼 -𬣙 -𬇕 -𬣞 -𬘓 -𫭟 -𫭢 -𫇭 -𫐄 -𫵷 -𬇙 -𬣡 -𫸩 -𫘜 -𬘘 -𫘝 -𬨂 -𬀩 -𬀪 -𬬩 -𫍣 -𬣳 -𬩽 -𬮿 -𬯀 -𫰛 -𬳵 -𬳶 -𫠊 -𬍛 -鿍 -𬜬 -𪾢 -𪨰 -𫓧 -𬬮 -𬬱 -𬬭 -𬘡 -𬳽 -𬘩 -𫄧 -𪟝 -𬍤 -𫭼 -𬜯 -𬂩 -𫠆 -𬌗 -𫑡 -𪨶 -𬬸 -𬬻 -𬬹 -𬬿 -𬭁 -𫢸 -𫗧 -𬊈 -𬒈 -𬳿 -𫄨 -𬘫 -𫮃 -鿎 -𬱖 -𬟽 -𫓯 -𫟹 -𫟼 -𬇹 -𬍡 -𬤇 -𫍯 -𬤊 -𫍲 -𬯎 -𬘬 -𬘭 -𬴂 -𫘦 -𫟅 -𬘯 -𫘧 -𪣻 -𬃊 -𬷕 -𫐐 -𬹼 -𫶇 -𫖮 -鿏 -𬭊 -𫓶 -𬭎 -𫖯 -𬱟 -𫛭 -𫷷 -𬮱 -𬊤 -𬴃 -𫘨 -𬪩 -𬒔 -𬨎 -𫐓 -𫫇 -𫓹 -𬭚 -𬭛 -𬕂 -𬶋 -𬶍 -𫔶 -𫌀 -𫖳 -𫘪 -𫘬 -𫞩 -𪤗 -𬸘 -𬒗 -𫚖 -𬭤 -𫚕 -𬶐 -𬶏 -𬸚 -𬤝 -𬙂 -𬭩 -𬸣 -𫍽 -𬴊 -𬞟 -𫟦 -𬺈 -𫠜 -𪩘 -𬭬 -𬭯 -𫗴 -𬸦 -𫄷 -𬭳 -𬭶 -𫔍 -𬭸 -𬭼 -𫔎 -𬸪 -𬶟 -𬶠 -𬶨 -𫄸 -𬟁 -𬙊 -𬶭 -𬶮 -𬙋 -𬺓 -𫚭 -廠 -蔔 -兒 -幾 -幹 -虧 -纔 -與 -萬 -韆 -億 -個 -廣 -門 -義 -衛 -飛 -習 -馬 -鄉 -豐 -開 -無 -雲 -專 -藝 -廳 -區 -歷 -曆 -車 -貝 -岡 -見 -氣 -長 -僕 -幣 -僅 -從 -侖 -倉 -風 -烏 -鳳 -爲 -鬥 -憶 -計 -訂 -認 -譏 -醜 -隊 -辦 -鄧 -勸 -雙 -書 -擊 -撲 -節 -術 -厲 -龍 -滅 -軋 -東 -盧 -業 -舊 -帥 -歸 -葉 -電 -號 -衹 -隻 -嘰 -嘆 -們 -儀 -叢 -爾 -樂 -處 -鼕 -鳥 -務 -飢 -饑 -馮 -閃 -蘭 -匯 -彙 -頭 -漢 -寧 -討 -寫 -讓 -禮 -訓 -議 -訊 -記 -齣 -遼 -邊 -發 -髮 -聖 -對 -臺 -颱 -檯 -糾 -絲 -動 -鞏 -執 -擴 -掃 -場 -揚 -亞 -樸 -機 -權 -過 -協 -壓 -厭 -頁 -誇 -奪 -達 -夾 -軌 -堯 -劃 -邁 -畢 -貞 -師 -塵 -當 -噹 -籲 -嚇 -蟲 -麯 -團 -糰 -嗎 -嶼 -歲 -迴 -豈 -則 -剛 -網 -硃 -遷 -喬 -偉 -傳 -優 -傷 -價 -倫 -華 -僞 -嚮 -後 -會 -殺 -閤 -衆 -爺 -傘 -創 -雜 -負 -壯 -衝 -妝 -莊 -慶 -劉 -齊 -産 -閉 -問 -闖 -關 -燈 -湯 -興 -講 -諱 -軍 -訝 -許 -訛 -論 -訟 -農 -諷 -設 -訪 -訣 -尋 -盡 -儘 -導 -孫 -陣 -陽 -階 -陰 -婦 -媽 -戲 -觀 -歡 -買 -紅 -馱 -纖 -縴 -馴 -約 -級 -紀 -馳 -紉 -壽 -麥 -瑪 -進 -遠 -違 -韌 -運 -撫 -壇 -罎 -壞 -摳 -擾 -貢 -垻 -壩 -摺 -掄 -搶 -墳 -護 -殻 -塊 -聲 -報 -擬 -蕪 -葦 -蒼 -嚴 -蘆 -勞 -蘇 -囌 -極 -楊 -兩 -麗 -醫 -勵 -還 -殲 -來 -連 -軒 -鹵 -滷 -堅 -時 -縣 -裏 -嘔 -園 -曠 -圍 -噸 -郵 -睏 -員 -聽 -嗆 -嗚 -彆 -嶇 -崗 -帳 -財 -針 -釘 -亂 -體 -傭 -徹 -餘 -穀 -鄰 -腸 -龜 -猶 -狽 -條 -島 -飯 -飲 -係 -繫 -凍 -狀 -畝 -庫 -療 -應 -這 -廬 -閏 -閑 -間 -悶 -竈 -燦 -瀝 -淪 -滄 -溝 -滬 -瀋 -懷 -憂 -窮 -證 -啓 -評 -補 -識 -詐 -訴 -診 -詞 -譯 -靈 -層 -遲 -張 -際 -陸 -陳 -墜 -勁 -鷄 -緯 -驅 -純 -紗 -綱 -納 -駁 -縱 -紛 -紙 -紋 -紡 -驢 -紐 -環 -責 -現 -錶 -規 -攏 -揀 -擔 -頂 -擁 -勢 -攔 -擰 -撥 -擇 -蘋 -範 -莖 -樞 -櫃 -闆 -鬆 -槍 -楓 -構 -喪 -畫 -棗 -賣 -鬱 -礬 -礦 -碼 -厠 -奮 -態 -歐 -毆 -壟 -轟 -頃 -轉 -斬 -輪 -軟 -齒 -虜 -腎 -賢 -國 -暢 -嚨 -鳴 -羅 -幟 -嶺 -凱 -敗 -賬 -販 -貶 -購 -貯 -圖 -釣 -製 -颳 -俠 -僥 -偵 -側 -憑 -僑 -貨 -質 -徑 -捨 -覓 -貪 -貧 -膚 -腫 -脹 -骯 -脅 -魚 -獰 -備 -飾 -飽 -飼 -變 -龐 -廟 -瘧 -劑 -廢 -閘 -鬧 -鄭 -捲 -單 -爐 -淺 -濘 -瀉 -潑 -澤 -憐 -學 -寶 -寵 -審 -簾 -實 -試 -詩 -誠 -襯 -視 -話 -誕 -詭 -詢 -該 -詳 -肅 -録 -隸 -彌 -瀰 -陝 -駕 -參 -艱 -綫 -練 -組 -紳 -細 -駛 -織 -駒 -終 -駐 -絆 -駝 -紹 -繹 -經 -貫 -貳 -幫 -項 -挾 -撓 -趙 -擋 -墊 -擠 -揮 -薦 -帶 -繭 -蕩 -榮 -葷 -熒 -鬍 -蔭 -藥 -標 -棧 -棟 -欄 -檸 -樹 -鹹 -磚 -硯 -麵 -牽 -鷗 -殘 -軸 -輕 -鴉 -戰 -點 -臨 -覽 -竪 -嘗 -啞 -顯 -貴 -蝦 -蟻 -螞 -雖 -駡 -勛 -嘩 -響 -喲 -峽 -罰 -賤 -貼 -貽 -鈣 -鈍 -鈔 -鍾 -鐘 -鋼 -鈉 -鑰 -欽 -鈞 -鈎 -鈕 -氈 -氫 -選 -適 -種 -鞦 -復 -複 -倆 -貸 -順 -儉 -須 -鬚 -劍 -朧 -膽 -勝 -狹 -獅 -獨 -獄 -貿 -餌 -饒 -蝕 -餃 -餅 -巒 -彎 -將 -奬 -瘡 -瘋 -親 -閨 -聞 -閩 -閥 -閣 -養 -薑 -類 -婁 -總 -煉 -爍 -爛 -窪 -潔 -灑 -澆 -濁 -測 -瀏 -濟 -渾 -濃 -惱 -舉 -覺 -憲 -竊 -誡 -誣 -語 -襖 -誤 -誘 -誨 -説 -誦 -墾 -晝 -費 -遜 -隕 -險 -嬌 -賀 -壘 -綁 -絨 -結 -繞 -驕 -繪 -給 -絢 -駱 -絡 -絶 -絞 -駭 -統 -艷 -蠶 -頑 -盞 -撈 -載 -趕 -鹽 -損 -撿 -摯 -剝 -熱 -搗 -壺 -聶 -萊 -蓮 -獲 -穫 -惡 -噁 -瑩 -鶯 -檔 -橋 -樺 -樁 -樣 -賈 -礫 -礎 -顧 -轎 -較 -頓 -斃 -緻 -慮 -監 -緊 -黨 -曬 -曉 -嘮 -鴨 -暈 -鴦 -罷 -圓 -賊 -賄 -賂 -贜 -錢 -鉗 -鑽 -鉀 -鐵 -鈴 -鉛 -犧 -敵 -積 -稱 -筆 -債 -傾 -賃 -艦 -艙 -聳 -愛 -頒 -頌 -臟 -髒 -臍 -膠 -腦 -膿 -鴕 -鴛 -皺 -餓 -餒 -戀 -槳 -漿 -準 -癥 -齋 -離 -資 -競 -閲 -煩 -燒 -燭 -遞 -濤 -澇 -渦 -塗 -滌 -潤 -澗 -漲 -燙 -澀 -憫 -寬 -傢 -賓 -竅 -請 -諸 -諾 -讀 -誹 -襪 -課 -誰 -調 -諒 -諄 -談 -誼 -懇 -劇 -難 -預 -絹 -綉 -驗 -繼 -駿 -瑣 -擲 -據 -摻 -職 -蘿 -螢 -營 -蕭 -薩 -夢 -檢 -醖 -碩 -聾 -襲 -輔 -輛 -顱 -懸 -躍 -纍 -囉 -嘯 -嶄 -邏 -嬰 -銬 -鐺 -鋁 -銅 -銘 -鏟 -銀 -矯 -穢 -籠 -償 -軀 -釁 -銜 -盤 -鴿 -斂 -領 -臉 -獵 -餡 -館 -癢 -鏇 -閻 -闡 -蓋 -斷 -獸 -鴻 -漸 -淵 -漁 -澱 -滲 -慚 -懼 -驚 -慘 -慣 -謀 -諜 -謊 -諧 -禱 -禍 -謂 -諺 -謎 -彈 -墮 -隨 -隱 -嬸 -頗 -頸 -績 -緒 -續 -騎 -綽 -繩 -維 -綿 -綳 -綢 -綜 -綻 -緑 -綴 -瓊 -趨 -攬 -攙 -擱 -摟 -攪 -聯 -蔣 -韓 -橢 -確 -頰 -靂 -暫 -翹 -輩 -鑿 -輝 -賞 -睞 -噴 -疇 -踐 -遺 -鵑 -賦 -賭 -贖 -賜 -賠 -鑄 -鋪 -鏈 -銷 -鎖 -鋤 -鍋 -銹 -鋒 -鋅 -鋭 -鵝 -築 -篩 -儲 -懲 -禦 -釋 -臘 -魯 -憊 -饋 -饞 -裝 -蠻 -闊 -糞 -滯 -濕 -潰 -濺 -灣 -憤 -竄 -窩 -褲 -禪 -謝 -謡 -謗 -謙 -屬 -屢 -緬 -纜 -緝 -緞 -緩 -締 -縷 -騙 -編 -騷 -緣 -鵡 -攝 -擺 -襬 -攤 -鵲 -藍 -濛 -懞 -矇 -獻 -欖 -樓 -賴 -礙 -尷 -霧 -輻 -輯 -輸 -頻 -齡 -鑒 -蹺 -蝸 -錯 -錨 -錫 -鑼 -錘 -錐 -錦 -鍵 -鋸 -錳 -辭 -頽 -籌 -簽 -籤 -簡 -膩 -鵬 -騰 -鮑 -穎 -觸 -雛 -饃 -餾 -醬 -謄 -糧 -數 -滿 -濾 -濫 -灕 -濱 -灘 -譽 -窺 -寢 -謹 -謬 -闢 -縛 -縫 -纏 -繽 -贅 -墻 -衊 -藹 -檻 -釀 -願 -轄 -輾 -顆 -踴 -蠟 -蠅 -蟬 -賺 -鍬 -鍛 -鍍 -穩 -籮 -簫 -輿 -鮮 -饅 -瀟 -賽 -譚 -譜 -騾 -縮 -攆 -聰 -藴 -櫻 -飄 -黴 -瞞 -題 -囑 -鎮 -鎬 -鎊 -簍 -鯉 -鯽 -癟 -癱 -顔 -鯊 -瀾 -額 -譴 -鶴 -繚 -顛 -轍 -鸚 -贈 -鏡 -贊 -籃 -籬 -鯨 -癮 -辯 -瀕 -懶 -繮 -繳 -矚 -贍 -鰐 -辮 -贏 -驟 -囂 -鐮 -鰭 -鷹 -巔 -顫 -癬 -鱉 -鬢 -鱗 -躪 -贛 -鑲 -韋 -閂 -訃 -勱 -芻 -鄺 -訐 -訌 -訕 -訖 -馭 -璣 -壙 -捫 -薌 -厙 -釔 -傴 -倀 -傖 -獷 -獁 -鳬 -鄔 -餳 -懺 -謳 -詎 -訥 -紆 -紂 -紇 -紈 -璵 -摶 -塢 -㩳 -蕓 -藶 -莧 -萇 -蓯 -磯 -奩 -歟 -軔 -鄴 -嘸 -囈 -嚦 -暘 -唄 -幃 -峴 -嵐 -圇 -釗 -釙 -釕 -僉 -鳩 -鄒 -飩 -餼 -飪 -飫 -飭 -廡 -癤 -闈 -閎 -閔 -煬 -灃 -漚 -渢 -潙 -憮 -慪 -愾 -悵 -愴 -詁 -訶 -詛 -詆 -謅 -詔 -詒 -隴 -陘 -嫵 -嫗 -嬀 -剄 -紜 -紕 -紝 -綸 -紓 -瑋 -匭 -壚 -擓 -蘢 -蔦 -塋 -煢 -櫪 -梘 -棖 -樅 -碭 -甌 -郟 -軛 -鳶 -曇 -蟣 -黽 -嚀 -噝 -巋 -劌 -剴 -嶧 -釷 -釺 -釧 -釩 -釹 -釵 -儈 -儕 -儂 -劊 -慫 -糴 -戧 -膞 -邇 -梟 -餞 -飴 -癘 -瘍 -煒 -熰 -熗 -瀧 -瀘 -濼 -涇 -㥮 -懌 -誆 -誄 -詿 -詰 -詼 -鄆 -禕 -誅 -詵 -詬 -詮 -詣 -諍 -詫 -諢 -詡 -駑 -紺 -紲 -紱 -駟 -駙 -縐 -絀 -驛 -駘 -瓏 -頇 -埡 -撾 -撻 -賁 -壋 -撏 -莢 -貰 -蓽 -蕎 -薈 -薺 -堊 -滎 -犖 -蕁 -藎 -蓀 -蕒 -葤 -櫛 -櫳 -櫨 -櫟 -檉 -酈 -硨 -碸 -殤 -軲 -軻 -轤 -軼 -軫 -蠆 -覘 -瞘 -嘵 -嗶 -噦 -剮 -鄖 -噲 -噥 -嶢 -幀 -嶠 -貺 -鈈 -鈦 -鋇 -鈑 -鈐 -鎢 -鈁 -鈀 -篤 -儔 -儼 -儷 -腖 -臚 -脛 -鴇 -獪 -颮 -猻 -餉 -餄 -餎 -孿 -孌 -癧 -瘲 -颯 -闥 -閭 -闓 -閡 -熾 -烴 -浹 -澮 -滸 -潯 -濜 -慟 -懨 -愷 -惻 -惲 -誚 -禰 -誥 -誑 -鴆 -婭 -嬈 -懟 -絝 -驍 -驊 -絎 -絳 -駢 -頊 -璫 -琿 -塒 -塤 -堝 -贄 -蒔 -萵 -蕕 -鴣 -蒓 -橈 -楨 -榿 -檜 -邐 -礪 -礱 -軾 -輊 -輅 -鶇 -躉 -齔 -鸕 -矓 -嘜 -鴞 -蜆 -嗩 -嶗 -崍 -覬 -賅 -鈺 -鉦 -鈷 -鉢 -鈸 -鉞 -鉭 -鉬 -鈿 -鈾 -鉑 -鑠 -鉚 -鈰 -鉉 -鉈 -鉍 -鈮 -鈹 -鏺 -鐸 -氬 -筧 -頎 -徠 -膾 -鴟 -璽 -鴝 -獫 -裊 -餑 -欒 -攣 -癰 -痙 -頏 -閫 -鬮 -誾 -閬 -鄲 -燁 -燴 -燼 -淶 -漣 -潿 -慳 -諏 -諑 -禎 -諉 -諛 -諗 -諂 -誶 -媧 -嫻 -綆 -驪 -綃 -騁 -綏 -縧 -綈 -駸 -鷥 -燾 -璉 -麩 -擄 -摑 -鷙 -撣 -慤 -摜 -縈 -槤 -覡 -欞 -嗇 -匱 -硤 -磽 -鴯 -龔 -殞 -殮 -賚 -輒 -塹 -嘖 -囀 -嚙 -蹌 -蠣 -蠱 -蟶 -幘 -幗 -賕 -賑 -賒 -銠 -鉺 -鋏 -鐃 -銦 -鎧 -鍘 -銖 -銑 -鋌 -鏵 -銓 -鎩 -鉿 -銚 -鉻 -錚 -銫 -鉸 -銥 -銃 -銨 -銣 -鴰 -穠 -箋 -籩 -僨 -僂 -皚 -鴴 -艫 -龕 -玀 -獼 -餜 -餛 -鸞 -闍 -閾 -閹 -閶 -鬩 -閽 -閼 -羥 -糲 -燜 -漬 -瀆 -澠 -愜 -憚 -諶 -諫 -皸 -謔 -襠 -謁 -諤 -諭 -諼 -讒 -諳 -諦 -諞 -糶 -嬋 -綾 -騏 -綺 -緋 -緔 -騍 -緄 -騅 -綬 -綹 -綣 -綰 -驂 -緇 -靚 -輦 -黿 -頡 -撳 -蟄 -壪 -蔞 -櫝 -欏 -賫 -鵓 -鸝 -殫 -輥 -輞 -槧 -輟 -輜 -瞼 -躒 -蛺 -蟯 -螄 -蠐 -嘍 -嶸 -嶁 -賧 -鋙 -錸 -鏗 -鋥 -鋰 -鋯 -鋨 -銼 -鐧 -銻 -鋃 -鋦 -錒 -犢 -鵠 -篳 -牘 -儻 -儐 -儺 -嬃 -頜 -鵒 -魷 -魨 -魴 -潁 -颶 -觴 -熲 -餷 -餿 -褻 -臠 -癆 -癇 -賡 -頦 -鷳 -闌 -闃 -闋 -鵜 -憒 -嚳 -謨 -褳 -襇 -讜 -謖 -謚 -謐 -騭 -巰 -翬 -騖 -緙 -緗 -緘 -緹 -緲 -緦 -緱 -縋 -緡 -饗 -耮 -驁 -韞 -攄 -擯 -轂 -驀 -鶓 -薊 -蘺 -鎣 -頤 -櫚 -櫸 -磧 -磣 -鵪 -輳 -齟 -齙 -韙 -囁 -躂 -蹕 -躚 -躋 -噯 -鍺 -錛 -錡 -鍀 -錁 -錕 -錮 -鍁 -錈 -錠 -錙 -覦 -頷 -鮁 -鮃 -鮎 -鱸 -穌 -鮒 -鮐 -鵮 -颼 -饈 -鶉 -瘮 -闔 -闐 -闕 -灧 -瀅 -潷 -灤 -澦 -懾 -鱟 -騫 -竇 -謾 -謫 -嬡 -嬪 -縉 -縝 -縟 -轡 -騮 -縞 -縭 -縊 -縑 -騸 -覯 -韜 -靉 -攖 -薔 -藺 -鶘 -檳 -櫧 -釅 -殯 -霽 -轅 -齜 -齦 -瞜 -曖 -躊 -蟈 -鶚 -嚶 -羆 -賻 -罌 -鶻 -鍥 -鍇 -鍶 -鍔 -鍤 -鏘 -鎂 -鏤 -簀 -篋 -簞 -籙 -臏 -鮭 -鮪 -鱭 -鮫 -鱘 -饉 -鑾 -瘻 -闞 -鮝 -糝 -鷀 -瀲 -濰 -譖 -褸 -譙 -讕 -譎 -鶥 -嬙 -鶩 -驃 -縹 -縵 -縲 -纓 -驄 -繆 -繅 -耬 -瓔 -擷 -擼 -攛 -聵 -覲 -韃 -鞽 -蘄 -賾 -檣 -靨 -魘 -饜 -轆 -齬 -齪 -覷 -顒 -躓 -躑 -蠑 -螻 -顎 -嚕 -顓 -鑷 -鎘 -鎸 -鎳 -鎦 -鎰 -鎵 -鑌 -簣 -鷂 -鯁 -鱺 -鰱 -鰹 -鰣 -鯀 -鯇 -觶 -饊 -饌 -齏 -讞 -襤 -譫 -屨 -纈 -繕 -繒 -驏 -擻 -顳 -顢 -藪 -櫓 -櫞 -贋 -飆 -鏨 -轔 -蟎 -鐯 -鏢 -鏜 -鏝 -鏰 -鏞 -鏑 -鏃 -鏐 -氌 -穡 -魎 -鯪 -鯡 -鯤 -鯧 -鯝 -鯢 -鯛 -鯔 -獺 -鷓 -贇 -癭 -斕 -瀨 -顙 -繾 -繰 -繯 -蘚 -鷯 -齲 -齷 -躡 -蹣 -羈 -鐔 -鐝 -鐐 -鐓 -鑭 -鑹 -鏹 -鐙 -籪 -鷦 -鱝 -鰈 -鯷 -鰓 -鰍 -鰉 -鯿 -鷲 -懣 -鷸 -鰲 -韉 -顥 -鷺 -䴉 -髏 -鑊 -鐳 -鐲 -讎 -鰨 -鰥 -鰩 -癩 -攢 -靄 -躥 -髖 -髕 -鑔 -籟 -鰳 -鰾 -鱈 -鰻 -鱅 -讖 -驥 -纘 -瓚 -鼉 -黷 -黲 -鑣 -鑞 -臢 -鱖 -鱔 -鱒 -驤 -顰 -鱧 -癲 -灝 -鸛 -鑱 -趲 -顴 -躦 -饢 -戇 -戔 -訏 -訒 -釓 -俔 -閆 -澫 -訢 -訩 -詝 -紃 -纊 -瑒 -剗 -塸 -壢 -埨 -撝 -蔿 -榪 -軑 -軏 -咼 -㠣 -覎 -㑳 -颺 -閌 -潕 -湋 -澐 -浿 -諓 -禡 -詗 -詘 -詖 -屓 -彄 -紘 -馹 -馼 -紵 -紞 -駃 -紖 -瑲 -薴 -棡 -軝 -暐 -晛 -崬 -釴 -釤 -鍆 -鍚 -鄶 -獮 -飿 -嶨 -詷 -詪 -鄩 -鳲 -隑 -隮 -娙 -逕 -駓 -駔 -駉 -絅 -騶 -䮄 -紼 -紿 -瓅 -韍 -墶 -塏 -薘 -蕘 -蔄 -葒 -鳾 -龑 -軹 -軤 -轢 -軺 -睍 -曨 -噠 -鈃 -鈇 -鉅 -鋹 -釿 -錀 -鈧 -鈥 -鈄 -倈 -艤 -鶬 -颭 -餏 -湞 -溮 -滻 -褘 -絰 -駰 -絪 -駪 -綎 -綖 -驫 -勣 -璕 -𡑍 -䓣 -薟 -藭 -椏 -梜 -頍 -硜 -輄 -輈 -輇 -貲 -嗊 -曄 -暉 -鄳 -幬 -輋 -嶮 -贐 -鉥 -鉕 -鑪 -鉮 -鉊 -鉧 -僤 -鴒 -魛 -餗 -燖 -溳 -礐 -窵 -襏 -駼 -絺 -綌 -騂 -綄 -璡 -墠 -壼 -聹 -蘀 -勩 -罃 -檮 -棶 -厴 -䃮 -磑 -礄 -鴷 -齕 -頔 -廼 -凢 -亾 -枒 -屍 -匃 -匄 -紥 -紮 -疋 -殀 -讐 -觔 -兇 -宂 -㕥 -㠯 -栞 -佈 -佔 -呌 -敂 -冄 -坵 -僊 -怱 -悤 -冊 -夘 -戼 -牠 -妳 -嬭 -摃 -釦 -攷 -託 -衺 -衕 -弔 -喫 -囙 -㠶 -颿 -秊 -倣 -髣 -佀 -朶 -氷 -決 -併 -並 -竝 -汙 -汚 -異 -姦 -廵 -挵 -衖 -搤 -阯 -撦 -埳 -阬 -誌 -㕁 -卻 -刦 -刧 -刼 -芲 -蘤 -桿 -槓 -荳 -獃 -唫 -脗 -皁 -彿 -髴 -疘 -刪 -鉋 -鑤 -況 -牀 -恡 -棄 -洶 -汎 -災 -烖 -菑 -禩 -侷 -跼 -坿 -玅 -姉 -妬 -翫 -搨 -柺 -拕 -牴 -觝 -倖 -抝 -盃 -桮 -傑 -逩 -肎 -菓 -崐 -崑 -呪 -虖 -嘑 -謼 -詠 -㟁 -嵒 -巗 -巖 -雰 -稈 -咊 -嶽 -妷 -姪 -廹 -徃 -餚 -採 -寀 -唸 -週 -昬 -兎 -兔 -亯 -亱 -䘚 -淨 -劵 -匟 -㳒 -灋 -洩 -霑 -淚 -註 -恠 -箒 -屆 -絃 -圅 -旾 -珎 -掛 -垜 -艸 -茘 -査 -栢 -柵 -栁 -桺 -柹 -韮 -揹 -昰 -閧 -鬨 -冐 -暎 -嚥 -倃 -𠴰 -偺 -喒 -齩 -欬 -榘 -㑺 -儁 -敍 -敘 -肧 -脈 -䘑 -衇 -跡 -蹟 -砲 -礮 -薙 -鬀 -恆 -怳 -卹 -䘏 -賉 -婣 -畊 -揑 -綑 -輓 -恥 -躭 -晉 -棲 -覈 -慄 -翄 -脣 -槕 -㨪 -螡 -蟁 -㤙 -陗 -峩 -峯 -乗 -椉 -咲 -筍 -俛 -頫 -勌 -䠶 -躳 -慇 -拏 -㧱 -挐 -脃 -胷 -肐 -貍 -㽞 -畱 -淒 -悽 -蓆 -効 -傚 -涼 -缾 -菸 -煙 -淛 -湧 -誖 -猂 -醼 -讌 -㝠 -寃 -孃 -桒 -毬 -瑠 -璢 -瑯 -㨗 -搥 -搯 -蔆 -惏 -楳 -槑 -捄 -廂 -慽 -慼 -瞇 -埜 -畧 -虵 -稭 -棃 -犂 -迻 -媮 -兠 -舩 -慾 -綵 -腳 -𩓐 -夠 -豬 -貓 -湊 -減 -庻 -蔴 -菴 -朢 -睠 -觕 -麤 -釬 -銲 -痳 -殽 -婬 -滛 -湻 -㴱 -樑 -顇 -㝛 -窰 -窯 -琹 -欵 -墖 -趂 -隄 -愽 -揷 -揫 -煑 -朞 -㪚 -塟 -蔥 -蔕 -稜 -棊 -碁 -椶 -偪 -㕑 -廚 -廈 -鴈 -冣 -㝡 -晳 -鼃 -餧 -餵 -嗁 -諠 -㡌 -賸 -筴 -筞 -筩 -栰 -暠 -皜 -踰 -蝟 -㪟 -燄 -遊 -媿 -嘅 -庽 -窓 -牎 -牕 -窻 -徧 -僱 -帬 -裠 -強 -彊 -疎 -壻 -瓌 -䰟 -皷 -擕 -㩗 -㩦 -攜 -懃 -鞾 -幙 -㮣 -酧 -詶 -醻 -掽 -踫 -㼝 -盌 -磟 -覩 -倸 -㬉 -煗 -煖 -晻 -闇 -炤 -跥 -䗬 -蠭 -寘 -辠 -稺 -穉 -燬 -譭 -瘉 -癒 -顋 -骽 -猨 -蝯 -稟 -痺 -癡 -亷 -㢘 -韻 -泝 -遡 -昚 -躶 -臝 -羣 -㬪 -曡 -疊 -勦 -琍 -瓈 -𤋮 -熈 -牓 -搾 -謌 -堿 -鹻 -鹼 -矁 -燻 -髈 -𤺥 -辢 -旂 -𡚁 -潄 -砦 -詧 -嫰 -櫈 -撐 -墪 -譔 -鞵 -鞌 -蕋 -橤 -蘂 -醕 -譆 -跴 -蹤 -蜨 -蠍 -稾 -殭 -惪 -厀 -襃 -癅 -䊀 -餬 -潛 -癄 -顦 -鷰 -藷 -櫥 -螎 -蹏 -蟇 -譟 -簒 -彫 -琱 -鵰 -餹 -餻 -簷 -粦 -燐 -緐 -幑 -蹧 -粇 -穅 -臋 -籐 -繙 -飜 -孼 -蠏 -燿 -蝡 -稬 -穤 -惷 -覇 -鑵 -戹 -阨 -剳 -帀 -巵 -亙 -佇 -竚 -穽 -岅 -虯 -𦍑 -羗 -啎 -姙 -㘭 -袟 -袠 -逈 -㒺 -犛 -氂 -偘 -甕 -罋 -冺 -姍 -蝨 -琺 -瑇 -尅 -梔 -斮 -斲 -斵 -暱 -毘 -蝱 -吚 -哶 -峝 -粃 -竢 -狥 -秈 -烱 -㳄 -袵 -盇 -涖 -蒞 -碪 -蠔 -唕 -倐 -儵 -雋 -皐 -臯 -衂 -䶊 -臙 -獧 -痾 -皰 -湼 -澣 -濬 -塚 -襢 -娿 -勅 -勑 -戞 -廐 -廄 -眥 -覜 -勗 -啗 -噉 -傯 -挱 -㥫 -惥 -慂 -陻 -蕚 -萲 -蕿 -蘐 -藼 -櫂 -箠 -槨 -啑 -蹠 -蚘 -痐 -蛕 -蜖 -瘖 -遯 -醃 -飱 -冪 -簑 -枏 -柟 -檝 -楥 -矴 -椗 -嘷 -獋 -粺 -䈰 -諐 -齶 -堘 -疿 -雝 -秔 -稉 -槀 -搉 -廝 -叡 -嘠 -蜋 -筯 -篛 -麞 -糉 -緥 -璿 -髥 -臕 -餈 -剹 -橜 -罇 -蜺 -矙 -憇 -翺 -饍 -瞖 -羴 -羶 -爕 -繦 -騌 -鬉 -騣 -蔾 -䠀 -簮 -躕 -蹵 -䝔 -貛 -鼴 -麐 -塡 -あ -い -う -え -お -か -き -く -け -こ -さ -し -す -せ -そ -た -ち -つ -て -と -な -に -ぬ -ね -の -は -ひ -ふ -へ -ほ -ま -み -む -め -も -や -ゆ -よ -ら -り -る -れ -ろ -わ -を -ん -が -ぎ -ぐ -げ -ご -ざ -じ -ず -ぜ -ぞ -だ -ぢ -づ -で -ど -ば -び -ぶ -べ -ぼ -ぱ -ぴ -ぷ -ぺ -ぽ -ぁ -ぃ -ぅ -ぇ -ぉ -っ -ゃ -ゅ -ょ -ゎ -ゕ -ゖ -ア -イ -ウ -エ -オ -カ -キ -ク -ケ -コ -サ -シ -ス -セ -ソ -タ -チ -ツ -テ -ト -ナ -ニ -ヌ -ネ -ノ -ハ -ヒ -フ -ヘ -ホ -マ -ミ -ム -メ -モ -ヤ -ユ -ヨ -ラ -リ -ル -レ -ロ -ワ -ヲ -ン -ガ -ギ -グ -ゲ -ゴ -ザ -ジ -ズ -ゼ -ゾ -ダ -ヂ -ヅ -デ -ド -バ -ビ -ブ -ベ -ボ -パ -ピ -プ -ペ -ポ -ァ -ィ -ゥ -ェ -ォ -ッ -ャ -ュ -ョ -ヮ -ヵ -ヶ -ヷ -ヸ -ヹ -ヺ -・ -ー -ヽ -ヾ -ヿ -ア -イ -ウ -エ -オ -カ -キ -ク -ケ -コ -サ -シ -ス -セ -ソ -タ -チ -ツ -テ -ト -ナ -ニ -ヌ -ネ -ノ -ハ -ヒ -フ -ヘ -ホ -マ -ミ -ム -メ -モ -ヤ -ユ -ヨ -ラ -リ -ル -レ -ロ -ワ -ヲ -ン -゙ -゚ -ァ -ィ -ゥ -ェ -ォ -ッ -ャ -ュ -ョ -円 -気 -糸 -絵 -楽 -帰 -戸 -広 -黒 -図 -線 -読 -売 -歩 -毎 -亜 -悪 -圧 -扱 -囲 -為 -壱 -隠 -栄 -営 -駅 -塩 -縁 -艶 -応 -桜 -穏 -仮 -価 -箇 -ゑ -ゝ -ゞ -ヰ -ヴ -㈱ -両 -丼 -丿 -亀 -仏 -伝 -侶 -俤 -値 -倶 -倹 -偐 -偽 -働 -儛 -兌 -児 -冑 -冨 -凞 -処 -凪 -別 -剣 -剤 -剰 -劔 -労 -勧 -勲 -匁 -匂 -匲 -卍 -単 -厳 -収 -呂 -呉 -呑 -呰 -唖 -喚 -喩 -喰 -噛 -噺 -嚢 -囃 -団 -圀 -圏 -堀 -堺 -塀 -塁 -塙 -増 -墺 -壊 -壌 -壷 -変 -奨 -姫 -娯 -嫐 -嬢 -嬾 -孁 -宍 -実 -宮 -寔 -寛 -対 -専 -尭 -峠 -崋 -嶋 -巀 -巌 -巣 -巻 -帯 -幇 -庁 -廃 -廻 -弉 -弌 -弐 -弖 -弾 -従 -徳 -徴 -忯 -恵 -悩 -惣 -懐 -懽 -戦 -戯 -戻 -払 -抜 -択 -拝 -拠 -拡 -拵 -挙 -挿 -捗 -捜 -掟 -掲 -掻 -揃 -換 -揺 -摂 -撃 -撹 -斉 -斎 -旛 -旡 -晧 -晩 -暁 -暦 -曽 -杁 -杢 -杣 -杮 -枓 -枠 -枡 -柾 -栂 -栃 -桝 -桟 -桾 -梛 -梱 -梲 -梶 -椙 -検 -椥 -楕 -楡 -楢 -榊 -榎 -槇 -様 -槙 -槻 -樋 -権 -樫 -橿 -檥 -欅 -歎 -歓 -歯 -歳 -歴 -毀 -沖 -沢 -浄 -涙 -済 -渉 -渋 -渓 -渕 -満 -滝 -漑 -潅 -澁 -瀞 -瀬 -焔 -焼 -煇 -煕 -煥 -燗 -爼 -犠 -狛 -猟 -獏 -獣 -珊 -瑤 -甞 -畑 -畠 -畳 -畷 -畺 -痩 -癪 -発 -県 -眞 -砕 -碕 -礒 -禖 -禿 -稲 -穂 -穣 -竃 -竜 -竴 -笹 -筈 -筬 -筰 -箆 -箏 -箙 -篠 -篭 -簺 -籾 -粂 -粋 -粛 -粧 -糺 -紬 -絁 -経 -絖 -絣 -絽 -継 -続 -綟 -総 -縄 -縅 -縒 -縦 -繊 -繋 -繍 -繝 -繧 -纐 -纒 -罠 -罧 -罵 -羂 -羇 -羨 -聟 -聡 -聨 -聴 -脇 -脳 -膣 -膵 -臈 -臓 -臥 -舎 -舖 -舗 -舘 -芿 -苅 -茲 -荊 -荘 -莬 -莵 -菫 -萠 -蔵 -薗 -薫 -薬 -薭 -蘊 -蛍 -蝋 -蝿 -蟷 -衞 -衵 -袙 -袞 -袰 -袴 -袿 -裃 -裡 -裲 -褄 -褌 -襴 -襷 -覗 -覚 -覧 -観 -訳 -証 -諌 -諚 -諟 -諡 -諮 -譛 -譲 -讃 -豅 -豊 -豎 -賎 -賛 -贔 -躙 -躰 -転 -軽 -輌 -辥 -辺 -辻 -込 -逓 -遅 -遙 -邉 -郷 -酔 -醗 -醤 -醸 -釈 -鉄 -鉇 -鉤 -鉱 -鉾 -銈 -銕 -銭 -鋲 -鋳 -鋺 -錆 -錍 -錣 -錬 -錵 -鍑 -鍮 -鍼 -鎌 -鎗 -鎚 -鎹 -鐇 -鐚 -鐡 -鑁 -鑑 -鑚 -鑢 -閇 -関 -閦 -闘 -陥 -険 -隣 -隷 -雑 -雫 -霊 -靜 -靫 -靭 -靱 -鞄 -鞆 -頚 -頬 -頴 -頼 -顕 -顗 -餝 -饂 -駄 -駆 -駈 -騒 -験 -騨 -髄 -髙 -髪 -髷 -鯖 -鯰 -鯱 -鰒 -鰯 -鰰 -鳰 -鴎 -鴫 -鵄 -鵞 -鵺 -鶏 -鹸 -麁 -麺 -麿 -黌 -黙 -鼈 -齢 -龗 -縯 -蟅 -坖 -祂 -鼂 -鱚 -蛻 -屌 -呾 -煔 -吶 -扥 -蚖 -銂 -尃 -夋 -鵼 -徬 -寳 -彡 -舨 -湳 -麼 -鍈 -崈 -鱣 -盺 -拺 -瑥 -茷 -焻 -奀 -驎 -鱰 -砢 -痟 -廱 -僜 -瘺 -鱊 -擥 -嶰 -淓 -跅 -浵 -媗 -璦 -煠 -檊 -媃 -峅 -躄 -鉟 -塽 -蟴 -鯮 -弍 -烒 -鵵 -妑 -孋 -蚡 -恊 -輭 -廞 -產 -曅 -盜 -騤 -囪 -鱀 -茇 -葊 -逹 -狓 -崢 -趖 -凃 -羙 -鮸 -昞 -楿 -渽 -圗 -麪 -屇 -鍉 -葝 -沯 -爭 -幵 -筭 -寊 -銋 -貮 -鎭 -熺 -昜 -鍱 -墬 -愒 -磺 -嚈 -稘 -珮 -釆 -殑 -鍩 -䲁 -蕷 -鐿 -僡 -佹 -輶 -冴 -襶 -賔 -猙 -辧 -絛 -磾 -韁 -螔 -譳 -礑 -鋱 -魩 -嚗 -棆 -牆 -敟 -柶 -瓛 -魣 -巎 -轘 -襌 -枼 -鸌 -逺 -錏 -縡 -帢 -騄 -媼 -埅 -鄤 -萐 -祙 -旼 -詥 -鶲 -燉 -卲 -銱 -庲 -伱 -氽 -嵿 -挻 -煵 -窋 -鐤 -鮊 -鱬 -鰧 -嬤 -譞 -諲 -脭 -悳 -崘 -阭 -內 -袾 -冚 -壐 -咗 -礠 -孮 -痲 -埈 -肹 -鰮 -鮓 -濊 -塜 -凜 -蒢 -噰 -桼 -峍 -焴 -鶒 -鋮 -綠 -鶹 -熿 -毴 -咟 -嘥 -睺 -繡 -郎 -瘞 -鉶 -蔎 -秠 -緤 -蝀 -躝 -蟜 -繃 -囮 -墫 -乭 -胊 -濙 -瘓 -榣 -鑛 -鐫 -嶴 -甹 -坮 -銾 -蒭 -睜 -俋 -餠 -榢 -蓳 -盋 -堷 -鍏 -苝 -巛 -蚵 -暏 -熤 -嬨 -墎 -鏽 -戶 -菺 -膮 -熖 -睪 -栜 -捱 -榗 -鍷 -曧 -犽 -韑 -袓 -䖝 -焄 -喦 -髲 -疌 -㴪 -侊 -貐 -蕅 -禠 -蕑 -囯 -暊 -儞 -佋 -柎 -㐱 -鰤 -苳 -鱥 -謤 -遶 -眀 -鑀 -羋 -顏 -陜 -銩 -黶 -苼 -蒤 -棛 -儫 -咁 -抦 -衚 -棩 -焿 -脫 -麅 -玏 -埧 -淸 -黁 -淽 -彠 -鮨 -沜 -糀 -厓 -楧 -嶌 -簹 -檵 -鱇 -嶬 -廸 -卽 -樀 -贌 -酼 -籛 -沒 -晸 -諪 -蕡 -妏 -鄋 -蒍 -奧 -抇 -蓨 -薆 -鱷 -巘 -䝉 -亰 -寈 -槩 -誒 -麴 -蕟 -溎 -蘗 -榦 -斿 -暟 -炲 -拚 -娖 -繖 -橚 -寜 -爀 -饟 -悅 -鯏 -彜 -眾 -葯 -嬝 -埮 -獇 -馛 -溙 -瀦 -熼 -硓 -鈢 -樆 -輬 -鰜 -蔘 -渙 -澔 -嗮 -旉 -籜 -媊 -燘 -儚 -頹 -缽 -俽 -逨 -鱓 -郞 -歊 -杴 -珡 -杋 -醁 -鰏 -鵾 -鐽 -鮋 -巶 -荅 -薾 -囓 -蹻 -獎 -禑 -鎓 -榲 -僴 -綞 -尓 -敭 -曔 -褔 -鬅 -亊 -鏦 -蓘 -裬 -鱲 -薡 -鰗 -箑 -鬪 -縂 -璸 -甙 -茮 -辵 -岻 -覿 -滈 -鯶 -鑂 -囶 -舺 -溋 -拋 -菾 -敾 -虨 -綝 -蝍 -醂 -禨 -賹 -廧 -絕 -槗 -徫 -鎔 -曮 -蠂 -捒 -堈 -莕 -蓪 -敎 -禃 -櫱 -綧 -瀶 -逌 -浤 -碻 -刄 -逤 -剏 -氹 -菈 -娫 -蜛 -嵗 -糎 -螶 -譓 -鏳 -嵙 -瑊 -隲 -檨 -緈 -畵 -砯 -簗 -彅 -鰺 -騋 -窶 -嚒 -嵻 -尙 -頵 -槰 -虉 -醞 -巂 -彔 -偊 -畇 -鱨 -妸 -塲 -畐 -鈫 -錟 -磪 -摠 -彥 -璙 -囝 -寗 -耎 -鮡 -蘓 -弅 -焃 -飥 -戙 -塰 -儱 -槺 -噏 -魟 -禵 -佧 -咘 -盪 -瑈 -鉲 -睭 -鏌 -鼇 -郋 -魮 -朖 -滽 -渃 -滙 -熯 -醿 -鎅 -褀 -鬬 -巄 -螥 -眜 -釚 -柉 -壎 -峇 -姸 -唭 -鮜 -鈖 -嫈 -壄 -洤 -黃 -伕 -堦 -嶔 -鮰 -鞞 -漎 -鉓 -鮗 -壴 -阝 -妀 -矽 -獢 -倗 -銪 -鴓 -橒 -凈 -哖 -屚 -偍 -瑺 -媯 -淍 -驌 -椇 -赬 -薐 -糹 -碽 -濲 -釭 -晭 -纕 -寖 -閞 -歿 -呎 -鶆 -屄 -櫿 -犎 -旲 -㙟 -龎 -翜 -螾 -說 -衜 -泆 -軎 -鵂 -荎 -嚧 -硂 -桖 -褭 -筊 -鰷 -秳 -戩 -轀 -鬹 -飬 -卋 -暸 -狦 -搢 -娋 -鏴 -溫 -毉 -淰 -謩 -餺 -鵙 -鳽 -鮀 -狶 -氻 -轝 -妺 -袛 -蓭 -梂 -娛 -牼 -稅 -兿 -玾 -煚 -僩 -鶿 -鬄 -崠 -鉆 -鯓 -蚢 -庀 -鵟 -坣 -殼 -悞 -熅 -敻 -鍠 -曶 -愼 -搳 -姃 -砳 -槼 -臞 -韾 -靑 -鸊 -薲 -虛 -蠄 -啟 -鶺 -苺 -滾 -褞 -仺 -胇 -憻 -郳 -烉 -驩 -冇 -枖 -夌 -搵 -匸 -盨 -櫾 -霤 -麊 -貒 -噓 -嗢 -笩 -晈 -冂 -銳 -毿 -慜 -囧 -閜 -娸 -庢 -壆 -馯 -桱 -兗 -葃 -侅 -煐 -鐦 -藸 -鷎 -嵰 -逎 -弒 -匋 -鐭 -廔 -砩 -孆 -灴 -伷 -兪 -鴗 -澯 -幚 -旙 -勻 -礽 -婑 -鱮 -娍 -銶 -吳 -鍟 -仼 -鳧 -彞 -娽 -昛 -鰼 -剎 -佉 -鉏 -偸 -鰆 -讙 -橪 -啱 -岀 -孻 -釪 -乹 -鈳 -漇 -檦 -埻 -祿 -爌 -禇 -鱵 -㸃 -梉 -燝 -霙 -炁 -飮 -蠙 -勷 -鵎 -儥 -鐠 -唻 -廰 -嚿 -嵕 -墱 -紑 -搖 -瘜 -皝 -鸑 -瀁 -粵 -撚 -巑 -梀 -啯 -眛 -諴 -夊 -僙 -鍝 -裖 -鮣 -凬 -飡 -灊 -橓 -嫳 -筳 -咑 -粍 -瓑 -璌 -伃 -閰 -傜 -黐 -謢 -驒 -橫 -蛯 -寕 -蠵 -瞓 -旳 -翏 -硏 -寯 -韡 -楤 -鰃 -朿 -侞 -鵯 -愨 -祹 -厔 -丌 -盩 -謏 -魕 -啣 -閱 -曺 -枛 -罉 -卐 -樻 -鷉 -鯒 -鋡 -磱 -枱 -攴 -蠷 -穈 -嚟 -檽 -趐 -奐 -鋐 -檇 -薀 -峼 -咭 -訔 -韠 -鑴 -鸐 -唃 -捦 -鸜 -誴 -罳 -璄 -暃 -夀 -賨 -鞥 -鈊 -灡 -鮍 -懮 -籣 -昐 -陁 -襾 -鮠 -鈏 -囍 -婯 -艔 -貭 -䰾 -姁 -禼 -堖 -鋶 -仛 -鏷 -謜 -鑅 -忬 -蘶 -謠 -觙 -奫 -狟 -泩 -桙 -飈 -垰 -啍 -嚞 -鯕 -蒧 -榞 -徸 -璹 -揔 -欉 -魞 -菶 -玧 -鳯 -廍 -侚 -岰 -岧 -鋕 -凵 -彣 -崱 -媜 -倢 -鵐 -砋 -鷚 -鱠 -鮻 -繻 -摵 -贓 -磵 -錻 -痠 -粩 -胅 -奣 -塨 -瀠 -鸘 -啚 -娳 -霶 -壔 -峚 -甂 -廁 -覌 -鰂 -猳 -鱻 -盫 -裿 -杬 -歛 -澋 -蘞 -嵜 -尐 -旽 -鉌 -鎛 -豿 -凖 -榤 -禓 -龝 -悧 -鷟 -鮟 -吋 -喢 -岪 -吥 -漵 -頠 -豔 -巿 -鑨 -醣 -熳 -懍 -湥 -檡 -韺 -戱 -緖 -鐈 -凉 -緃 -鮹 -媐 -爯 -巆 -褍 -鐬 -昍 -扙 -鍳 -芛 -蟳 -嬅 -糬 -吔 -塭 -譿 -冧 -鏓 -嶪 -嗹 -椵 -姀 -閿 -褧 -錞 -玆 -笘 -篔 -萡 -鶡 -螐 -鮄 -鰟 -脷 -啲 -杤 -蓚 -尗 -娎 -殟 -淥 -蝚 -蓧 -彐 -嚤 -銍 -囒 -坶 -淩 -鶼 -鱂 -喼 -燫 -肏 -姵 -廌 -禟 -籝 -迵 -嵨 -堮 -蟌 -憍 -廕 -蜑 -緁 -唘 -竩 -崙 -璚 -粄 -栨 -罈 -梫 -貤 -藔 -蜯 -訁 -斖 -煶 -馦 -妠 -閟 -疕 -夆 -鎪 -膥 -澻 -嘢 -嚐 -靁 -鎻 -鰛 -穵 -烋 -縕 -褎 -疒 -壠 -溼 -圂 -咅 -鯭 -鯙 -磘 -玨 -珤 -朊 -蚼 -濶 -薞 -嚩 -丟 -嫺 -鯻 -椲 -鰕 -刂 -蠘 -踎 -瀴 -琁 -鰶 -瑴 -肜 -㐂 -欥 -媺 -竻 -讚 -𣇉 -裵 -緜 -廩 -齧 -叄 -俌 -厰 -滀 -錄 -鷫 -鯗 -攞 -姌 -蔝 -幷 -縤 -屻 -鯃 -雞 -纁 -嫲 -嵮 -屭 -嶃 -跩 -鋗 -蕢 -篊 -俬 -淎 -暻 -鏻 -憓 -玗 -溈 -笭 -糢 -勳 -閒 -沍 -咾 -鉷 -蘵 -俁 -崵 -毸 -苪 -掙 -鴡 -萭 -俴 -屜 -蒾 -艹 -剷 -慍 -朮 -枴 -氳 -猓 -甽 -箝 -譁 -贗 -迆 -鈽 -鍊 -鍰 -鏍 -靦 -餽 -丮 -丱 -仜 -仩 -伬 -伔 -仱 -伀 -伻 -佢 -佒 -侀 -侇 -佷 -佌 -佪 -侐 -侜 -俓 -侲 -俉 -侻 -侳 -俇 -倅 -倇 -倰 -倛 -倳 -倷 -俷 -倠 -偯 -偞 -偠 -偋 -偝 -偛 -偢 -偅 -偟 -偩 -偫 -傛 -傔 -傞 -傋 -傌 -傎 -傝 -偨 -傂 -傽 -傿 -僆 -傮 -僄 -僈 -傰 -僁 -傱 -僋 -僗 -僛 -僪 -僝 -僓 -僿 -儃 -儰 -僸 -僶 -僾 -儌 -僽 -儜 -儓 -儗 -儑 -儢 -儤 -儠 -儸 -儹 -儽 -冓 -冘 -冞 -凊 -凅 -凔 -刌 -刉 -刓 -刜 -刞 -刵 -刲 -剆 -刱 -剉 -剚 -剒 -剫 -剭 -剬 -剺 -剸 -剻 -剼 -劀 -劋 -劖 -劘 -劗 -劙 -劦 -勴 -匊 -匢 -匰 -匴 -匷 -匽 -卌 -卼 -厎 -厒 -厗 -厞 -厜 -厤 -厬 -厹 -吰 -吷 -吪 -呿 -咈 -呫 -呺 -呥 -呬 -呴 -茍 -咷 -咮 -咶 -哅 -咠 -咢 -唦 -唗 -唒 -哤 -唚 -唈 -哫 -唅 -唴 -啢 -唶 -啒 -啅 -唌 -唲 -喨 -喥 -喭 -噅 -喓 -喣 -啽 -喌 -嗃 -嗛 -嗋 -嗀 -喿 -喍 -嗏 -嗕 -嗈 -嘕 -嘒 -嗼 -嘐 -嘓 -嘂 -嗺 -嘝 -嘄 -嗿 -噈 -噊 -噆 -噚 -嘳 -嘽 -嘾 -噮 -噳 -噣 -噭 -噞 -嚌 -嚍 -嚃 -嚘 -嚜 -嚫 -嚪 -嚬 -嚲 -嚵 -嚽 -嚾 -囆 -囅 -囋 -囗 -圁 -圞 -圠 -坁 -坅 -坲 -坱 -垀 -坴 -垗 -垝 -垔 -垘 -垽 -垼 -埢 -埶 -堩 -堣 -塈 -堥 -塓 -塉 -塯 -塕 -塼 -墆 -塿 -塴 -墋 -塺 -墝 -墯 -壈 -墽 -壖 -壝 -壛 -壾 -壿 -夃 -夎 -夒 -夗 -奅 -奊 -奰 -奲 -奼 -妦 -妎 -妢 -妐 -妵 -姏 -姎 -㚷 -姡 -姺 -姼 -娭 -婐 -婟 -婥 -婓 -婗 -媔 -媟 -媢 -婸 -媦 -媥 -媬 -媕 -娷 -嫇 -嫋 -媰 -媻 -嫮 -嫥 -嫢 -嫛 -嫿 -嫴 -嫷 -嫶 -嬎 -嬓 -嬐 -嬲 -嬽 -孈 -屘 -孲 -孷 -宎 -宨 -寪 -寍 -寋 -寑 -寙 -寠 -寱 -尌 -尒 -尟 -尰 -尳 -屖 -屔 -屝 -屧 -屩 -屮 -屴 -岏 -岋 -岉 -岒 -岮 -岤 -岯 -岟 -岝 -峐 -峌 -峞 -峉 -峊 -峬 -峮 -峷 -崝 -崨 -崥 -崏 -崰 -崣 -崷 -嵃 -嵑 -崳 -崺 -嵂 -嵱 -嵣 -嵥 -嵞 -嶀 -嵽 -嶆 -嵺 -嵷 -嶊 -嶉 -嶈 -嵾 -嶕 -嶜 -嶡 -嶚 -嶞 -嶱 -嶩 -嶵 -嶭 -巃 -巏 -巕 -巟 -巹 -帊 -帗 -帟 -帣 -帠 -帤 -帩 -帾 -帴 -幏 -幎 -幓 -幩 -幝 -幠 -幧 -幨 -幦 -幭 -幰 -庂 -庉 -庌 -庈 -庰 -庛 -庣 -庨 -庮 -庪 -庬 -庴 -廅 -廇 -廘 -廗 -廎 -廜 -緳 -廦 -廥 -廮 -廯 -蠯 -廾 -弚 -弝 -弣 -弤 -弮 -弳 -彃 -彉 -彋 -彏 -彯 -彴 -彸 -彾 -徦 -徥 -徯 -徲 -徾 -徿 -忀 -忁 -忔 -忕 -忨 -忣 -忷 -忥 -怭 -怲 -怋 -怴 -怗 -怚 -怞 -怬 -怢 -怐 -怮 -怓 -怷 -怹 -恲 -恞 -恅 -恇 -恉 -恛 -恌 -恀 -恟 -悀 -悁 -悕 -悗 -悇 -悊 -悐 -悾 -悺 -惓 -惤 -惈 -悷 -惉 -悹 -惌 -惢 -惄 -愊 -愖 -愅 -惵 -愓 -惸 -惼 -惾 -慉 -慅 -愶 -愲 -愮 -愯 -愬 -慁 -慞 -慱 -慒 -慓 -慲 -憀 -慴 -慔 -慺 -慛 -憃 -慹 -憱 -憰 -憢 -憉 -憛 -憯 -憟 -憪 -憡 -憝 -憖 -懅 -憴 -懆 -懁 -憿 -憸 -憵 -憼 -懧 -懠 -懥 -懤 -懘 -懭 -懱 -懪 -懰 -懫 -懻 -戁 -戃 -戄 -戉 -戠 -酨 -戺 -扐 -扜 -扤 -扡 -扢 -抆 -抌 -抎 -抏 -扻 -抭 -抴 -拑 -抾 -抪 -抶 -抮 -挍 -挋 -挃 -拫 -拹 -挏 -挌 -拸 -挀 -拲 -捖 -挬 -挶 -揤 -捊 -挼 -挩 -捁 -挴 -捘 -捔 -捥 -掝 -掗 -掫 -掯 -捵 -掜 -捼 -掤 -掔 -掱 -揎 -揥 -揨 -揯 -揊 -揲 -揵 -摡 -揟 -揝 -揜 -揘 -揅 -揱 -搆 -搟 -搕 -搘 -搹 -搷 -搣 -搰 -搊 -搚 -摀 -搧 -搫 -摍 -摝 -摲 -摦 -摎 -摋 -摓 -摐 -摿 -摮 -摰 -撢 -撠 -撗 -撜 -撋 -撊 -撌 -撟 -擗 -擖 -擏 -擉 -撽 -擩 -擣 -擫 -擭 -擨 -擽 -擸 -攇 -攐 -攍 -攌 -攗 -攕 -攓 -攡 -攠 -攦 -攩 -攭 -攲 -攳 -敁 -敊 -敆 -敓 -敧 -敪 -敤 -敜 -敯 -敳 -敶 -敺 -敹 -敿 -斁 -斀 -斄 -斒 -斔 -斞 -斨 -斪 -斻 -旍 -旓 -旚 -旝 -旟 -昲 -昦 -昢 -晇 -晥 -晜 -晼 -晬 -暀 -暆 -暍 -暋 -暡 -暰 -暩 -曀 -曊 -曋 -曏 -曒 -曚 -曣 -曭 -朁 -朅 -朄 -朒 -朘 -朣 -朾 -朹 -朻 -朼 -杅 -杇 -杝 -杗 -枎 -杶 -枆 -枌 -柲 -枺 -枻 -柸 -柀 -柅 -柫 -柤 -柍 -柮 -柣 -柂 -柧 -栚 -桋 -桏 -栱 -栵 -栫 -栭 -栯 -栘 -栔 -梡 -梇 -梐 -桭 -梮 -楖 -梬 -梩 -桵 -梒 -椌 -椄 -棜 -棷 -棳 -棌 -椈 -楰 -棯 -椔 -棸 -楟 -楎 -楱 -楅 -楺 -楈 -楛 -楉 -楬 -椳 -楀 -楄 -楶 -楘 -榶 -槉 -榠 -榬 -榼 -榙 -榩 -榾 -榯 -槄 -榽 -榹 -槥 -槸 -樕 -樠 -槬 -槢 -樛 -樝 -槾 -樧 -槮 -樔 -槷 -橀 -樴 -橉 -橧 -樲 -橨 -橝 -橭 -橶 -樿 -橁 -檍 -檖 -檁 -檟 -橾 -檛 -檓 -檕 -檃 -櫅 -檹 -櫡 -櫠 -櫌 -櫑 -櫙 -櫋 -櫜 -櫐 -櫫 -櫬 -櫰 -櫹 -櫺 -櫼 -欃 -欋 -欈 -欐 -欑 -欘 -欨 -欴 -欯 -欭 -欱 -欶 -欳 -欷 -欿 -歂 -歈 -歍 -歋 -歕 -歔 -歜 -歠 -歭 -歾 -肂 -殈 -殏 -殔 -殗 -殙 -殠 -殥 -殢 -殦 -殧 -殰 -殶 -毃 -毄 -毈 -毇 -毊 -毚 -毞 -毦 -毤 -毨 -毣 -毰 -毲 -毻 -毼 -毾 -氁 -氀 -氄 -氠 -氶 -汃 -汒 -汏 -汍 -汸 -沋 -汱 -汯 -沕 -汦 -汳 -泬 -沶 -沬 -泧 -沷 -泭 -泲 -泒 -沴 -洟 -洊 -洀 -浺 -浶 -洍 -涒 -浘 -浢 -涊 -涆 -浧 -涗 -涳 -涬 -淢 -涷 -淔 -渀 -淈 -涾 -淊 -涽 -淭 -湆 -湇 -湅 -湢 -渿 -湁 -渜 -渳 -湀 -渻 -渮 -湨 -湡 -渱 -渨 -湠 -湱 -湩 -渹 -溛 -滖 -溓 -溔 -滒 -溰 -溾 -滜 -滵 -滱 -漃 -漥 -漮 -潎 -漙 -漧 -漘 -漒 -滭 -漊 -潳 -滮 -潀 -漰 -潃 -漅 -濆 -澒 -澅 -潚 -潠 -澖 -潶 -潬 -潒 -潐 -潗 -澓 -潝 -濇 -濎 -濈 -濄 -澞 -澨 -瀄 -濌 -澩 -濴 -濔 -濣 -濭 -濧 -濦 -瀇 -瀎 -濿 -瀀 -濻 -瀙 -瀖 -瀫 -瀡 -瀢 -瀩 -瀯 -瀷 -灂 -瀸 -瀿 -瀺 -灄 -灉 -灖 -灗 -灛 -灟 -灨 -灩 -灪 -炾 -炰 -烓 -烑 -缹 -焍 -烰 -焠 -焮 -焣 -煆 -煣 -煝 -熐 -熉 -熀 -熂 -熚 -燅 -燂 -熸 -燀 -燡 -爁 -爊 -爂 -爓 -爞 -爢 -爣 -牄 -牉 -牋 -牏 -牣 -牬 -牰 -牸 -牷 -犈 -犉 -犆 -犅 -犌 -犑 -犐 -犗 -犕 -犓 -犘 -犚 -犝 -犞 -犥 -犦 -犤 -犣 -犩 -犪 -犮 -犵 -犿 -狆 -狖 -狋 -狘 -狜 -狔 -狚 -狌 -狑 -狊 -狤 -狫 -狪 -狣 -猀 -狾 -猑 -猘 -猈 -狿 -猏 -猋 -猒 -猧 -猲 -猭 -猦 -猣 -猵 -猼 -獂 -獀 -獊 -獑 -獌 -獘 -獞 -獟 -獝 -獛 -獡 -獩 -獦 -獥 -獳 -獶 -獽 -獿 -玂 -玁 -玈 -玊 -玔 -珓 -珶 -琖 -瑵 -璊 -瑽 -璅 -瑿 -璗 -瓁 -瓋 -瓝 -瓟 -瓡 -瓥 -瓨 -瓬 -瓵 -瓾 -瓽 -甀 -甃 -甈 -甋 -甐 -甒 -甔 -甖 -甝 -甮 -甿 -畟 -畣 -畽 -疀 -疧 -痁 -疻 -痀 -痎 -痏 -痋 -痌 -痑 -痚 -痡 -痝 -痗 -痯 -瘏 -痷 -痸 -痻 -瘈 -瘑 -瘝 -瘣 -瘯 -瘱 -瘽 -癈 -癉 -癙 -癐 -癓 -癠 -癵 -癹 -皊 -皏 -皫 -皯 -皵 -皻 -皽 -皾 -盄 -盓 -盝 -盬 -盭 -盳 -眃 -眅 -盻 -眝 -眐 -眓 -眒 -眣 -眑 -眕 -眹 -眱 -眲 -眴 -眳 -眽 -睆 -睅 -睊 -睋 -睌 -睕 -睟 -睒 -睖 -睩 -睧 -睔 -瞁 -睼 -瞂 -睮 -睯 -瞏 -瞉 -瞚 -瞝 -瞡 -瞛 -瞲 -瞷 -瞶 -瞴 -矂 -矉 -矊 -矌 -矎 -矏 -矐 -矔 -矕 -矘 -矠 -矱 -矲 -矹 -矺 -砅 -砐 -砏 -砎 -砨 -硈 -硉 -硠 -硥 -硱 -硰 -硩 -碔 -碄 -碅 -碆 -硾 -碫 -碞 -磍 -磌 -磎 -磈 -磃 -磝 -磩 -磥 -磞 -磛 -磳 -磼 -磿 -礔 -礉 -礝 -礛 -礜 -礥 -礣 -礧 -礨 -礭 -礿 -祌 -祅 -祔 -祒 -祑 -祤 -祩 -祪 -祣 -祫 -祡 -祴 -祳 -禂 -禗 -禜 -禫 -禭 -禬 -禴 -禷 -禸 -歶 -秅 -秏 -秖 -秎 -秮 -秪 -秺 -秶 -稊 -稒 -稫 -穊 -稰 -稯 -穋 -穛 -穖 -穧 -穨 -穮 -穬 -穭 -穱 -穾 -窆 -窉 -窌 -窏 -窔 -窐 -窙 -窢 -窞 -窫 -窲 -窴 -窱 -窾 -竀 -竁 -竷 -笐 -笓 -笅 -笵 -笻 -笴 -笰 -笢 -笝 -笲 -筄 -筡 -箈 -箊 -箌 -箛 -箎 -箘 -箄 -箷 -箾 -篎 -箯 -箹 -篞 -篣 -篧 -篕 -篨 -篹 -簅 -篲 -篿 -篻 -簎 -篴 -簂 -簁 -篸 -篽 -簜 -簩 -簙 -簭 -簦 -簨 -簢 -簥 -簳 -簼 -簬 -簻 -籉 -籈 -籊 -籔 -籗 -籧 -籦 -籯 -籺 -籸 -籹 -粊 -粔 -粻 -糔 -糪 -糱 -糷 -紎 -紟 -紒 -紽 -紸 -紶 -紩 -絇 -紾 -絘 -絯 -絓 -絧 -絏 -絭 -絫 -綀 -綍 -絿 -綅 -絻 -絼 -綔 -綷 -緂 -綪 -緀 -緅 -緎 -緆 -緌 -綯 -綼 -緷 -緛 -緪 -緧 -縃 -緺 -緶 -緰 -縗 -縌 -縓 -縎 -縜 -縚 -縏 -縼 -繂 -縳 -顈 -繈 -縸 -縪 -繉 -繀 -縩 -緵 -縰 -縿 -縶 -繜 -繐 -繣 -繘 -繢 -繟 -繑 -繠 -繶 -繵 -繸 -繷 -繺 -繲 -繴 -纀 -纇 -纋 -纆 -纑 -纗 -纚 -缿 -罊 -罏 -罜 -罞 -罝 -罛 -罣 -罥 -罦 -罭 -罫 -罬 -罻 -罼 -罺 -罿 -羃 -羉 -羍 -羒 -羜 -羛 -羢 -羠 -羦 -羬 -羭 -羵 -羳 -羷 -羺 -羾 -翋 -翍 -翐 -翑 -翇 -翢 -翣 -翭 -翪 -翨 -翴 -翲 -翽 -翿 -耟 -耞 -耡 -耴 -耾 -耹 -聇 -聈 -聑 -聏 -聝 -肕 -肙 -肒 -肣 -肵 -胘 -胑 -胐 -胕 -胉 -胏 -胹 -胵 -脁 -胻 -脀 -胾 -胔 -脰 -脥 -脤 -脙 -脡 -脕 -脧 -腃 -腏 -腄 -腇 -脽 -腍 -腤 -腷 -腜 -腛 -腢 -腲 -朡 -腞 -腶 -膉 -膆 -膃 -膇 -膍 -膌 -膋 -膟 -膕 -膢 -膱 -膹 -膫 -膰 -膬 -膴 -膲 -臇 -膷 -臄 -臅 -臒 -臐 -臗 -臛 -臡 -臦 -臩 -臮 -臲 -臷 -臸 -臿 -舋 -舑 -舕 -舝 -舡 -舼 -舽 -艀 -艂 -艓 -艒 -艐 -艑 -艕 -艛 -艵 -艼 -芀 -芐 -芅 -芓 -芔 -苀 -芚 -芵 -芧 -芞 -芺 -苙 -苨 -苖 -苬 -苲 -苵 -苶 -茙 -茥 -茿 -茦 -茢 -荂 -茪 -荍 -茖 -茤 -茠 -茩 -茻 -莐 -莣 -莍 -荺 -莤 -荴 -莏 -莁 -荵 -莔 -莃 -莌 -莋 -荾 -莥 -菨 -萒 -菧 -菤 -菆 -菣 -菿 -菋 -菎 -菵 -萉 -菞 -菳 -菕 -蓱 -萿 -葹 -葥 -葀 -葧 -萰 -葍 -葽 -蔇 -葞 -萷 -萺 -萴 -葅 -菙 -葋 -萯 -葂 -葟 -葌 -蓎 -蒬 -蒮 -蒫 -蒪 -蒚 -蒝 -蓌 -蒛 -蒩 -蒘 -蒶 -蒠 -蔤 -蔏 -蔩 -蔉 -蔍 -蔧 -蔜 -蓻 -蓺 -蓴 -蔪 -蓲 -蓷 -蓫 -蔒 -蓩 -蔖 -蓾 -蔨 -蔮 -蔂 -蓶 -蔱 -蓹 -蔠 -蔰 -蕫 -蕍 -蕀 -蕆 -蕄 -蕇 -蕣 -蕛 -蕱 -蕵 -蕮 -蕧 -蕠 -蕦 -蕝 -薃 -薧 -薕 -薠 -薋 -薣 -薚 -蕼 -薉 -蕸 -薎 -薖 -薍 -薝 -薂 -藆 -藀 -藃 -藂 -薵 -薽 -藇 -藄 -藋 -藈 -藅 -薱 -薶 -藒 -藫 -藱 -藙 -藡 -藚 -藗 -藲 -藬 -藘 -藣 -藑 -藰 -蘁 -藾 -蘛 -蘉 -蘌 -蘪 -蘦 -蘟 -蘣 -蘜 -蘙 -蘮 -蘡 -蘠 -蘥 -蘴 -蘳 -蘬 -虀 -蘹 -蘱 -蘻 -蘾 -虃 -虆 -虇 -虈 -虌 -虋 -虙 -虡 -虣 -虩 -虪 -虰 -虭 -虴 -蚑 -蚞 -蚇 -蚗 -蚚 -蚅 -蚥 -蚙 -蚿 -蚷 -蛂 -蛁 -蛅 -蛈 -蚹 -蚳 -蚸 -蛌 -蚻 -蛢 -蛦 -蛓 -蛣 -蛚 -蛪 -蛝 -蛫 -蛜 -蛬 -蛗 -蜄 -蛷 -蜌 -蛖 -蛵 -蜁 -蛶 -蜳 -蝫 -蜙 -蝃 -蜬 -蝁 -蝆 -蜠 -蜲 -蜪 -蜭 -蜼 -蜵 -蝂 -蜦 -蜧 -蜸 -蜤 -蜰 -蝖 -蝷 -蟡 -蝳 -蝔 -蝛 -蝒 -蝑 -蝞 -蝭 -蝪 -蝐 -蝝 -蝬 -蝺 -蝜 -螛 -螏 -螓 -螒 -螁 -螖 -螘 -蝹 -螇 -螑 -螝 -螜 -螚 -螪 -螰 -螹 -螼 -螮 -蟉 -蟃 -蟂 -螷 -螴 -螿 -螸 -蟞 -蟧 -蟦 -蟢 -蟟 -蟤 -蟔 -蟓 -蟭 -蟘 -螤 -蟗 -蟙 -蠁 -蟨 -蠀 -蟺 -蠉 -蠌 -蟼 -蠈 -蟿 -蠗 -蠩 -蠝 -蠛 -蠠 -蠤 -蠜 -蠫 -蠬 -蠨 -蠦 -蠪 -蠥 -蠰 -蠮 -蠳 -蠸 -蠾 -蠽 -蠿 -衁 -衈 -衋 -衧 -衪 -衭 -衶 -袀 -衱 -衯 -袃 -袉 -袕 -袨 -袚 -袑 -袡 -袘 -袧 -袬 -袌 -袺 -裗 -袹 -袸 -裀 -袶 -袽 -袲 -裋 -裍 -裞 -裚 -裷 -裧 -裺 -裮 -裶 -裯 -裻 -褁 -褅 -褋 -褗 -褆 -褖 -褑 -褦 -褮 -褱 -褢 -褩 -褵 -褼 -褾 -襒 -褷 -襂 -褽 -襓 -襋 -襆 -襐 -襛 -襗 -襡 -襘 -襝 -襣 -襭 -襩 -襮 -襳 -襹 -襺 -覂 -覅 -覕 -覛 -覝 -覢 -覤 -覣 -覭 -覮 -覶 -觓 -觤 -觡 -觠 -觢 -觩 -觰 -觬 -觲 -觷 -觺 -觻 -觼 -觾 -訑 -訰 -訧 -訬 -訞 -詍 -訹 -詙 -詀 -詄 -詅 -訿 -誂 -詻 -誃 -誫 -誙 -誋 -諆 -誸 -諔 -諕 -誻 -諀 -諅 -諵 -諝 -諰 -諈 -謞 -謘 -謑 -謋 -謒 -謕 -謍 -謈 -謪 -謧 -謣 -謰 -謵 -譇 -謯 -謱 -謥 -謷 -謦 -譐 -譈 -譊 -譀 -譋 -譕 -譑 -譠 -譪 -譝 -譨 -譣 -譥 -譹 -譸 -譅 -譺 -譻 -譾 -讄 -讂 -讆 -讋 -讔 -讘 -讟 -谹 -谻 -谽 -谾 -豃 -豋 -豍 -豏 -豗 -豜 -豝 -豟 -豥 -豤 -豦 -豭 -豰 -豲 -豱 -豯 -豵 -豷 -豶 -豻 -豽 -貁 -貀 -貄 -貏 -貑 -貕 -貙 -貗 -貜 -貣 -貾 -賌 -賥 -賟 -賙 -賵 -賮 -贆 -贕 -贙 -赨 -赩 -赮 -赸 -趀 -趌 -趎 -趏 -趍 -趓 -趠 -趜 -趡 -趥 -趧 -趬 -趪 -趭 -趫 -趮 -趷 -趹 -跘 -跓 -跍 -跇 -跜 -跕 -跙 -跈 -跰 -跠 -跮 -跦 -跢 -跧 -跲 -跫 -踂 -跿 -踍 -踃 -踇 -踆 -跾 -踠 -踥 -踤 -踡 -踕 -踛 -踖 -踑 -踙 -踧 -踘 -踓 -踳 -踾 -踸 -踼 -蹎 -蹍 -蹓 -蹗 -蹖 -蹞 -蹥 -蹛 -蹡 -蹝 -蹔 -蹸 -蹳 -蹪 -躆 -躈 -躖 -躗 -躟 -躠 -躤 -躣 -躩 -躨 -躽 -軓 -軘 -軞 -軯 -軷 -軦 -軮 -軥 -軵 -軧 -軨 -軶 -軱 -軬 -輆 -軿 -輁 -輀 -輂 -輐 -輑 -輤 -輘 -輚 -輠 -輣 -輖 -輗 -輮 -輵 -輲 -輹 -輷 -輴 -轃 -轇 -轈 -轒 -轑 -轏 -轐 -轓 -轙 -轖 -轗 -轕 -轚 -轞 -轛 -轠 -辴 -迉 -迒 -迋 -迍 -迖 -迣 -迡 -迾 -迿 -逜 -逿 -遝 -遳 -遰 -遻 -邆 -邅 -遾 -邍 -邔 -邟 -邥 -邞 -邧 -郱 -郕 -郖 -郠 -郙 -郣 -郥 -郘 -郰 -郲 -郔 -鄬 -郼 -鄈 -郹 -郻 -鄁 -鄇 -郺 -鄐 -鄍 -鄏 -鄎 -鄟 -鄝 -鄡 -鄛 -鄨 -鄪 -鄦 -鄮 -鄵 -鄸 -鄻 -鄾 -酀 -酁 -酄 -酇 -酖 -酘 -酓 -酟 -酳 -醆 -醊 -醓 -醙 -醟 -醥 -醧 -醰 -醱 -醷 -醲 -醳 -醹 -醽 -釂 -釃 -釢 -釱 -釳 -釸 -鈚 -鈌 -鈒 -釽 -鈆 -鉒 -鉠 -鉯 -鈶 -鉼 -銤 -銛 -銔 -鉹 -銗 -鋄 -鋀 -鋟 -鋘 -鋩 -鋝 -鋂 -鋊 -錧 -錼 -錭 -錎 -鋋 -鎡 -鎃 -鎯 -鍖 -鍜 -鍐 -鍭 -鍌 -鎒 -鎷 -鎝 -鎉 -鎎 -鎞 -鏏 -鏂 -鏚 -鏬 -鏙 -鐋 -鐏 -鏾 -鐕 -鐨 -鐍 -鐀 -鐎 -鐖 -鐻 -鐶 -鑐 -鑋 -鑕 -鑮 -鑯 -钂 -钀 -钁 -钃 -镺 -镻 -镼 -镽 -閈 -閍 -閺 -閵 -闀 -闉 -闅 -閷 -闒 -闑 -闚 -闛 -闠 -闟 -闤 -阞 -阢 -阤 -阠 -阰 -阹 -阸 -阺 -陏 -陓 -陊 -陼 -陭 -陫 -隇 -陾 -隉 -隒 -隓 -隞 -隤 -隿 -雂 -雈 -雓 -雔 -雗 -雚 -雟 -雘 -雺 -雽 -雿 -霂 -霋 -霒 -霐 -霠 -霣 -霢 -霩 -霫 -霬 -霮 -霵 -霿 -靆 -靃 -靪 -靮 -靷 -靲 -靾 -鞃 -鞀 -鞂 -靻 -鞊 -鞎 -鞈 -鞙 -鞗 -鞚 -鞜 -鞤 -鞪 -鞷 -鞶 -鞹 -鞻 -鞿 -韄 -韅 -韇 -韎 -韐 -韏 -韕 -韔 -韗 -韝 -韟 -韣 -韥 -韰 -韱 -韹 -韽 -頄 -頖 -頞 -頝 -頩 -頨 -頯 -頲 -顁 -顄 -顊 -顉 -顅 -顐 -顑 -顜 -顝 -顠 -顣 -顟 -顤 -顪 -顩 -顲 -颬 -颲 -颸 -颽 -颻 -颾 -飁 -飂 -飉 -飋 -飌 -飣 -飶 -餂 -餀 -飺 -餔 -餖 -餕 -餤 -餟 -餥 -餫 -餪 -餲 -餯 -餭 -餱 -餰 -饁 -饇 -饐 -饎 -饙 -饘 -饛 -饡 -馣 -馲 -馰 -馵 -馻 -馺 -駂 -馽 -駜 -駍 -駏 -駎 -駖 -駮 -駬 -駥 -駤 -駣 -駩 -駺 -駴 -駷 -駹 -駶 -駻 -駽 -駾 -騃 -騉 -騑 -騊 -騇 -騚 -騕 -騥 -騝 -騛 -騢 -騠 -騧 -騞 -騜 -騵 -騲 -騴 -騱 -騬 -騪 -騩 -騹 -騽 -驆 -騺 -驓 -驔 -驈 -驉 -驖 -驞 -驠 -驦 -驨 -骭 -骫 -骹 -骿 -骴 -骾 -髇 -髊 -髆 -髍 -髐 -髟 -髧 -髬 -髳 -髶 -髺 -髾 -鬁 -髼 -鬋 -鬊 -鬎 -鬌 -鬐 -鬕 -鬗 -鬖 -鬙 -鬞 -鬠 -鬤 -鬫 -鬳 -鬵 -鬺 -鬾 -鬿 -魊 -魌 -魖 -魠 -魡 -魧 -魱 -魦 -魶 -魵 -鮅 -鮇 -魼 -魾 -魻 -鮂 -鮚 -鮞 -鮛 -鮦 -鮥 -鮤 -鮆 -鯆 -鮿 -鮵 -鯈 -鯫 -鯠 -鯞 -鯦 -鯬 -鰌 -鰋 -鰅 -鯸 -鰫 -鰝 -鰬 -鱆 -鰿 -鱄 -鱁 -鰴 -鱐 -鱍 -鱋 -鱕 -鱦 -鱢 -鱞 -鱴 -鱳 -鱹 -鳦 -鳪 -鳭 -鳱 -鳵 -鳼 -鳺 -鳿 -鳷 -鴀 -鳹 -鳻 -鴅 -鴃 -鴥 -鴠 -鴔 -鴩 -鴘 -鴢 -鴐 -鴳 -鵁 -鵧 -鴶 -鴮 -鴱 -鴸 -鵅 -鵃 -鴾 -鵀 -鴽 -鵏 -鵊 -鵛 -鵋 -鵖 -鵌 -鵗 -鵔 -鵷 -鶁 -鶊 -鶄 -鶈 -鵱 -鶀 -鵸 -鶋 -鶌 -鵽 -鵫 -鵴 -鵩 -鶅 -鵳 -鵻 -鶂 -鵹 -鶟 -鶙 -鶤 -鶝 -鶐 -鶛 -鶠 -鶔 -鶜 -鶪 -鶗 -鶢 -鶨 -鶞 -鶣 -鶖 -鶷 -鶶 -鷁 -鷇 -鷊 -鷏 -鶾 -鷅 -鷃 -鶵 -鷈 -鶱 -鶭 -鷛 -鷒 -鷞 -鷋 -鷐 -鷜 -鷑 -鷩 -鷘 -鷖 -鷵 -鷕 -鷻 -鷷 -鷣 -鷤 -鷶 -鷡 -鷮 -鷢 -鸂 -鷾 -鸇 -鸃 -鸆 -鸅 -鸀 -鸁 -鸉 -鷿 -鷽 -鸄 -鸋 -鸍 -鸏 -鸒 -鸔 -鸓 -鸗 -鸙 -鹺 -麃 -麆 -麉 -麎 -麌 -麔 -麙 -麛 -麚 -麜 -麠 -麡 -麧 -麮 -麰 -麶 -麷 -黀 -黂 -黈 -黓 -黕 -黖 -黚 -黤 -黫 -黮 -黭 -黰 -黳 -黵 -黺 -鼁 -鼀 -鼆 -鼊 -鼏 -鼖 -鼛 -鼘 -鼜 -鼤 -鼣 -鼥 -鼪 -鼨 -鼭 -鼰 -鼮 -鼵 -鼳 -鼲 -鼸 -鼶 -齀 -齂 -齃 -齌 -齍 -齎 -齖 -齗 -齘 -齛 -齠 -齞 -齝 -齥 -齤 -齫 -齱 -齰 -齮 -齯 -齴 -齵 -齸 -齻 -齺 -齹 -齾 -龒 -龤 -堔 -礂 -蒏 -蒆 -兙 -兛 -兞 -兝 -兡 -兣 -嗧 -瓩 -忼 -擡 -氊 -穇 -擧 -譌 -! -\ -# -$ -% -& -' -( -) -* -+ -, -- -. -/ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -: -; -< -= -> -? -A -B -C -D -E -F -G -H -I -J -K -L -M -N -O -P -Q -R -S -T -U -V -W -X -Y -Z -[ -] -_ -` -a -b -c -d -e -f -g -h -i -j -k -l -m -n -o -p -q -r -s -t -u -v -w -x -y -z -© -° -² -´ -½ -Á -Ä -Å -Ç -È -É -Í -Ó -Ö -× -Ü -ß -à -á -â -ã -ä -å -æ -ç -è -é -ê -ë -í -ð -ñ -ò -ó -ô -õ -ö -ø -ú -û -ü -ý -ā -ă -ą -ć -Č -č -đ -ē -ė -ę -ğ -ī -ı -Ł -ł -ń -ň -ō -ř -Ş -ş -Š -š -ţ -ū -ż -Ž -ž -Ș -ș -ț -Δ -α -λ -μ -φ -Г -О -а -в -л -о -р -с -т -я -ồ -— -― -’ -“ -” -… -℃ -→ -∇ -− -■ -☆ -、 -。 -々 -〆 -〈 -〉 -「 -」 -『 -』 -〔 -〕 -〜 -! -# -% -& -( -) -+ -, -- -. -/ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -: -; -= -? -@ -A -B -C -D -E -F -G -H -I -J -K -L -M -N -O -P -R -S -T -U -V -W -X -Z -a -b -c -d -e -f -g -h -i -j -k -l -m -n -o -p -q -r -s -t -u -v -w -x -y -z -~ -・ -ǎ -ǒ -ě -ǐ -ì -ǔ -ù -ǖ -ǘ -ǚ -ǜ -【 -】 -《 -》 -‥ -{ -} -\\ -| -@ -^ -~ -÷ -∕ -∙ -⋅ -· -⊕ -⊖ -⊗ -⊘ -⊙ -± -∓ -∩ -∪ -□ -⊎ -⊓ -⊔ -≠ -≈ -≡ -≤ -≥ -≪ -≫ -≲ -≳ -≶ -≷ -≺ -≻ -≼ -≽ -∈ -∉ -⊂ -⊃ -⊆ -⊇ -⊄ -⊅ -∅ -∖ -∁ -∆ -∧ -∨ -¬ -⊻ -⊼ -⊽ -← -↔ -⇒ -⇐ -⇔ -∀ -∃ -∄ -∴ -∵ -∝ -∞ -⊥ -∟ -∠ -∡ -∢ -′ -″ -∥ -⊾ -⊿ -∂ -∫ -∬ -∭ -∮ -∯ -∰ -∑ -∏ -√ -∛ -∜ -∱ -∲ -∳ -∶ -∷ -∼ -® -≄ -≅ -≃ -≦ -≧ -⊈ -⊉ -⊢ -⊤ -⊨ -⊧ -℉ -Ω -℧ -Å -⌀ -ℏ -⅀ -⍺ -⍵ -¢ -€ -£ -¥ -¥ -₿ -↑ -↓ -↕ -↖ -↗ -↘ -↙ -↺ -↻ -↼ -↽ -↾ -↿ -⇀ -⇁ -⇂ -⇃ -⇋ -⇌ -ª -º -⁰ -¹ -³ -⁴ -⁵ -⁶ -⁷ -⁸ -⁹ -⁺ -⁻ -⁼ -⁽ -⁾ -ⁿ -₀ -₁ -₂ -₃ -₄ -₅ -₆ -₇ -₈ -₉ -₊ -₋ -₌ -₍ -₎ -Ⅰ -Ⅱ -Ⅲ -Ⅳ -Ⅴ -Ⅵ -Ⅶ -Ⅷ -Ⅸ -Ⅹ -Ⅺ -Ⅻ -ⅰ -ⅱ -ⅲ -ⅳ -ⅴ -ⅵ -ⅶ -ⅷ -ⅸ -ⅹ -ⅺ -ⅻ -☰ -☱ -☲ -☳ -☴ -☵ -☶ -☷ -♀ -♂ -♳ -♴ -♵ -♶ -♷ -♸ -♹ -♺ -♩ -♪ -♫ -♬ -⚪ -⚫ -⚬ -✶ -✷ -✸ -➀ -➁ -➂ -➃ -➄ -➅ -➆ -➇ -➈ -➉ -➊ -➋ -➌ -➍ -➎ -➏ -➐ -➑ -➒ -➓ -⏀ -⏁ -⏂ -⏃ -⏄ -⏅ -⏆ -⏇ -⏈ -⏉ -⏊ -⏋ -⏌ -⏚ -⏴ -⏵ -⏶ -⏷ -⏸ -⏹ -⏺ -⏻ -⏼ -Α -Β -Γ -Ε -Ζ -Η -Θ -Ι -Κ -Λ -Μ -Ν -Ξ -Ο -Π -Ρ -Σ -Τ -Υ -Φ -Χ -Ψ -β -γ -δ -ε -ζ -η -θ -ι -κ -ν -ξ -ο -π -ρ -σ -τ -υ -χ -ψ -ω -ϐ -ϑ -ϒ -ϕ -█ -ϖ -ϰ -ϱ -ϴ -ϵ -ϝ -Ϟ -ϟ -Ϡ -ϡ -Ϣ -ϣ -Ϥ -ϥ -Ϧ -ϧ -Ϩ -ϩ -Ϫ -ϫ -Ϭ -ϭ -Ϯ -ϯ -∸ -∹ -∺ -∻ -∽ -∾ -∿ -≀ -≁ -≂ -≆ -≇ -≉ -≊ -≋ -≌ -≍ -≎ -≏ -≐ -≑ -≒ -≓ -≔ -≕ -≖ -≗ -≘ -≙ -≚ -≛ -≜ -≝ -≞ -≟ -≢ -≣ -≨ -≩ -≬ -≭ -≮ -≯ -≰ -≱ -≴ -≵ -≸ -≹ -≾ -≿ -⊀ -⊁ -⊊ -⊋ -⊌ -⊍ -⊏ -⊐ -⊑ -⊒ -⊚ -⊛ -⊜ -⊝ -⊞ -⊟ -⊠ -⊡ -⊣ -⊦ -⊩ -⊪ -⊫ -⊬ -⊭ -⊮ -⊯ -⊰ -⊱ -⊲ -⊳ -⊴ -⊵ -⊶ -⊷ -⊸ -⊹ -⊺ -ℎ -℘ -ℜ -ℑ -ℵ -ℶ -ℷ -ℸ -⌬ -⌭ -⌮ -⌯ -⎔ -¤ -₠ -₡ -₢ -₣ -₤ -₥ -₦ -₧ -₨ -₩ -₪ -₫ -₭ -₮ -₯ -₰ -₱ -₲ -₳ -₴ -₵ -₶ -₷ -₸ -₹ -₺ -₻ -₼ -₽ -₾ -↚ -↛ -↜ -↝ -↞ -↟ -↠ -↡ -↢ -↣ -↤ -↥ -↦ -↧ -↨ -↩ -↪ -↫ -↬ -↭ -↮ -↯ -↰ -↱ -↲ -↳ -↴ -↵ -↶ -↷ -↸ -↹ -⇄ -⇅ -⇆ -⇇ -⇈ -⇉ -⇊ -⇍ -⇎ -⇏ -⇑ -⇓ -⇕ -⇖ -⇗ -⇘ -⇙ -⇚ -⇛ -⇜ -⇝ -⇞ -⇟ -⇠ -⇡ -⇢ -⇣ -⇤ -⇥ -⇦ -⇧ -⇨ -⇩ -⇪ -⇫ -⇬ -⇭ -⇮ -⇯ -⇰ -⇱ -⇲ -⇳ -⇴ -⇵ -⇶ -⇷ -⇸ -⇹ -⇺ -⇻ -⇼ -⇽ -⇾ -⇿ -ↀ -ↁ -ↂ -☀ -☁ -☂ -☃ -☄ -★ -☇ -☈ -☉ -☊ -☋ -☌ -☍ -☎ -☏ -☐ -☑ -☒ -☓ -☔ -☕ -☖ -☗ -☘ -☙ -☚ -☛ -☜ -☝ -☞ -☟ -☠ -☡ -☢ -☣ -☤ -☥ -☦ -☧ -☨ -☩ -☪ -☫ -☬ -☭ -☮ -☯ -☸ -☹ -☺ -☻ -☼ -☽ -☾ -☿ -♁ -♃ -♄ -♅ -♆ -♇ -♔ -♕ -♖ -♗ -♘ -♙ -♚ -♛ -♜ -♝ -♞ -♟ -♠ -♡ -♢ -♣ -♤ -♥ -♦ -♧ -♨ -♭ -♮ -♯ -♰ -♱ -♲ -♻ -♼ -♽ -♾ -⚀ -⚁ -⚂ -⚃ -⚄ -⚅ -⚆ -⚇ -⚈ -⚉ -⚊ -⚋ -⚌ -⚍ -⚎ -⚏ -⚐ -⚑ -⚒ -⚓ -⚔ -⚕ -⚖ -⚗ -⚘ -⚙ -⚚ -⚛ -⚜ -⚝ -⚞ -⚟ -⚠ -⚡ -⚢ -⚣ -⚤ -⚥ -⚦ -⚧ -⚨ -⚩ -⚭ -⚮ -⚯ -⚰ -⚱ -⚲ -⚳ -⚴ -⚵ -⚶ -⚷ -⚸ -⚹ -⚺ -⚻ -⚼ -⚿ -⛀ -⛁ -⛂ -⛃ -⛆ -⛇ -⛈ -⛉ -⛊ -⛋ -⛌ -⛍ -⛏ -⛐ -⛑ -⛒ -⛓ -⛕ -⛖ -⛗ -⛘ -⛙ -⛚ -⛛ -⛜ -⛝ -⛞ -⛠ -⛡ -⛢ -⛣ -⛤ -⛥ -⛦ -⛧ -⛨ -⛩ -⛪ -⛫ -⛬ -⛭ -⛮ -⛯ -⛶ -⛾ -⛿ -✆ -✇ -✈ -✉ -✌ -✍ -✎ -✏ -✐ -✑ -✒ -✓ -✔ -✕ -✙ -✚ -✛ -✜ -✝ -✞ -✟ -✠ -✡ -✢ -✣ -✤ -✥ -✦ -✧ -✩ -✪ -✫ -✬ -✭ -✮ -✯ -✰ -✱ -✲ -✳ -✴ -✵ -✹ -✺ -✻ -✼ -✽ -✾ -✿ -❀ -❁ -❂ -❃ -❄ -❅ -❆ -❇ -❈ -❉ -❊ -❋ -❍ -❏ -❐ -❑ -❒ -❖ -❘ -❙ -❚ -❛ -❜ -❝ -❞ -❡ -❢ -❣ -❤ -❥ -❦ -❧ -❨ -❩ -❪ -❫ -❬ -❭ -❮ -❯ -❰ -❱ -❲ -❳ -❴ -❵ -❶ -❷ -❸ -❹ -❺ -❻ -❼ -❽ -❾ -❿ -① -② -③ -④ -⑤ -⑥ -⑦ -⑧ -⑨ -⑩ -➔ -➕ -➖ -➗ -➘ -➙ -➚ -➛ -➜ -➝ -➞ -➟ -➠ -➡ -➢ -➣ -➤ -➥ -➦ -➧ -➨ -➩ -➪ -➫ -➬ -➭ -➮ -➯ -➰ -➱ -➲ -➳ -➴ -➵ -➶ -➷ -➸ -➹ -➺ -➻ -➼ -➽ -➾ -➿ -⌘ -⌥ -⌃ -⎋ -⌫ -⌦ -⏏ -⌤ -⌧ -⌨ -⎆ -⎇ -⎈ -⎉ -⎊ -⎌ -⎍ -⎎ -⎏ -⎐ -⎑ -⎒ -⎓ -⎕ -⎖ -⎗ -⎘ -⎙ -⎚ -⎛ -⎜ -⎝ -⎞ -⎟ -⎠ -⎡ -⎢ -⎣ -⎤ -⎥ -⎦ -⎧ -⎨ -⎩ -⎪ -⎫ -⎬ -⎭ -⎮ -⎯ -⎰ -⎱ -⎲ -⎳ -⎴ -⎵ -⎶ -⎷ -⎸ -⎹ -⎺ -⎻ -⎼ -⎽ -⎾ -⎿ -⏍ -⏎ -⏐ -⏑ -⏒ -⏓ -⏔ -⏕ -⏖ -⏗ -⏘ -⏙ -⏛ -⏜ -⏝ -⏞ -⏟ -⏠ -⏡ -⏢ -⏣ -⏤ -⏥ -⏦ -⏧ -⏨ -⏭ -⏮ -⏯ -⏱ -⏲ -▲ -▽ -◐ -⏽ -⏾ -⏿ -ɐ -ɑ -ɒ -ɓ -ɔ -ɕ -ɖ -ɗ -ɘ -ə -ɚ -ɛ -ɜ -ɝ -ɞ -ɟ -ɠ -ɡ -ɢ -ɣ -ɤ -ɥ -ɦ -ɧ -ɨ -ɩ -ɪ -ɫ -ɬ -ɭ -ɮ -ɯ -ɰ -ɱ -ɲ -ɳ -ɴ -ɵ -ɶ -ɷ -ɸ -ɹ -ɺ -ɻ -ɼ -ɽ -ɾ -ɿ -ʀ -ʁ -ʂ -ʃ -ʄ -ʅ -ʆ -ʇ -ʈ -ʉ -ʊ -ʋ -ʌ -ʍ -ʎ -ʏ -ʐ -ʑ -ʒ -ʓ -ʔ -ʕ -ʖ -ʗ -ʘ -ʙ -ʚ -ʛ -ʜ -ʝ -ʞ -ʟ -ʠ -ʡ -ʢ -ʣ -ʤ -ʥ -ʦ -ʧ -ʨ -ʩ -ʪ -ʫ -ʬ -ʭ -ʮ -ʯ -━ -Ǝ -Ã -● -▶ -| -𝑢 -〖 -〗 -︽ -– -﹥ -𝜓 -• -∋ -ƒ -० -✘ -Е -◉ -〒 -𝒱 -𝜆 -⟹ -﹪ -◊ -╆ -오 -˂ -〉 -𝝎 -▪ -△ -▁ -◼ -〇 -▷ -▬ -𝒮 -† -ₒ -⼁ -〵 -⭐ -╳ -⟶ -으 -⬆ -Ạ -◀ - -▫ -丄 -︾ -◥ -‖ -𝜌 -ⅼ -▼ -⁎ -﹏ -😁 -😂 -😃 -😄 -😅 -😆 -😉 -😊 -😋 -😌 -😍 -😏 -😒 -😓 -😔 -😖 -😘 -😚 -😜 -😝 -😞 -😠 -😡 -😢 -😣 -😤 -😥 -😨 -😩 -😪 -😫 -😭 -😰 -😱 -😲 -😳 -😵 -😷 -😸 -😹 -😺 -😻 -😼 -😽 -😾 -😿 -🙀 -🙅 -🙆 -🙇 -🙈 -🙉 -🙊 -🙋 -🙌 -🙍 -🙎 -🙏 -✂ -✅ -✊ -✋ -✖ -✨ -❌ -❎ -❓ -❔ -❕ -❗ -🚀 -🚃 -🚄 -🚅 -🚇 -🚉 -🚌 -🚏 -🚑 -🚒 -🚓 -🚕 -🚗 -🚙 -🚚 -🚢 -🚤 -🚥 -🚧 -🚨 -🚩 -🚪 -🚫 -🚬 -🚭 -🚲 -🚶 -🚹 -🚺 -🚻 -🚼 -🚽 -🚾 -🛀 -Ⓜ -🅰 -🅱 -🅾 -🅿 -🆎 -🆑 -🆒 -🆓 -🆔 -🆕 -🆖 -🆗 -🆘 -🆙 -🆚 -🇩🇪 -🇬🇧 -🇨🇳 -🇯🇵 -🇫🇷 -🇰🇷 -🇪🇸 -🇮🇹 -🇷🇺 -🇺🇸 -🈁 -ℹ -⌚ -⌛ -⏩ -⏪ -⏫ -⏬ -⏰ -⏳ -◻ -◽ -◾ -♈ -♉ -♊ -♋ -♌ -♍ -♎ -♏ -♐ -♑ -♒ -♓ -♿ -⚽ -⚾ -⛄ -⛅ -⛎ -⛔ -⛲ -⛳ -⛵ -⛺ -⛽ -⤴ -⤵ -⬅ -⬇ -⬛ -⬜ -⭕ -〰 -〽 -㊗ -㊙ -🀄 -🃏 -🌀 -🌁 -🌂 -🌃 -🌄 -🌅 -🌆 -🌇 -🌈 -🌉 -🌊 -🌋 -🌌 -🌏 -🌑 -🌓 -🌔 -🌕 -🌙 -🌛 -🌟 -🌠 -🌰 -🌱 -🌴 -🌵 -🌷 -🌸 -🌹 -🌺 -🌻 -🌼 -🌽 -🌾 -🌿 -🍀 -🍁 -🍂 -🍃 -🍄 -🍅 -🍆 -🍇 -🍈 -🍉 -🍊 -🍌 -🍍 -🍎 -🍏 -🍑 -🍒 -🍓 -🍔 -🍕 -🍖 -🍗 -🍘 -🍙 -🍚 -🍛 -🍜 -🍝 -🍞 -🍟 -🍠 -🍡 -🍢 -🍣 -🍤 -🍥 -🍦 -🍧 -🍨 -🍩 -🍪 -🍫 -🍬 -🍭 -🍮 -🍯 -🍰 -🍱 -🍲 -🍳 -🍴 -🍵 -🍶 -🍷 -🍸 -🍹 -🍺 -🍻 -🎀 -🎁 -🎂 -🎃 -🎄 -🎅 -🎆 -🎇 -🎈 -🎉 -🎊 -🎋 -🎌 -🎍 -🎎 -🎏 -🎐 -🎑 -🎒 -🎓 -🎠 -🎡 -🎢 -🎣 -🎤 -🎥 -🎦 -🎧 -🎨 -🎩 -🎪 -🎫 -🎬 -🎭 -🎮 -🎯 -🎰 -🎱 -🎲 -🎳 -🎴 -🎵 -🎶 -🎷 -🎸 -🎹 -🎺 -🎻 -🎼 -🎽 -🎾 -🎿 -🏀 -🏁 -🏂 -🏃 -🏄 -🏆 -🏈 -🏊 -🏠 -🏡 -🏢 -🏣 -🏥 -🏦 -🏧 -🏨 -🏩 -🏪 -🏫 -🏬 -🏭 -🏮 -🏯 -🏰 -🐌 -🐍 -🐎 -🐑 -🐒 -🐔 -🐗 -🐘 -🐙 -🐚 -🐛 -🐜 -🐝 -🐞 -🐟 -🐠 -🐡 -🐢 -🐣 -🐤 -🐥 -🐦 -🐧 -🐨 -🐩 -🐫 -🐬 -🐭 -🐮 -🐯 -🐰 -🐱 -🐲 -🐳 -🐴 -🐵 -🐶 -🐷 -🐸 -🐹 -🐺 -🐻 -🐼 -🐽 -🐾 -👀 -👂 -👃 -👄 -👅 -👆 -👇 -👈 -👉 -👊 -👋 -👌 -👍 -👎 -👏 -👐 -👑 -👒 -👓 -👔 -👕 -👖 -👗 -👘 -👙 -👚 -👛 -👜 -👝 -👞 -👟 -👠 -👡 -👢 -👣 -👤 -👦 -👧 -👨 -👩 -👪 -👫 -👮 -👯 -👰 -👱 -👲 -👳 -👴 -👵 -👶 -👷 -👸 -👹 -👺 -👻 -👼 -👽 -👾 -👿 -💀 -💁 -💂 -💃 -💄 -💅 -💆 -💇 -💈 -💉 -💊 -💋 -💌 -💍 -💎 -💏 -💐 -💑 -💒 -💓 -💔 -💕 -💖 -💗 -💘 -💙 -💚 -💛 -💜 -💝 -💞 -💟 -💠 -💡 -💢 -💣 -💤 -💥 -💦 -💧 -💨 -💩 -💪 -💫 -💬 -💮 -💯 -💰 -💲 -💳 -💴 -💵 -💸 -💹 -💺 -💻 -💼 -💽 -💾 -💿 -📀 -📁 -📂 -📃 -📄 -📅 -📆 -📇 -📈 -📉 -📊 -📋 -📌 -📍 -📎 -📏 -📐 -📑 -📒 -📓 -📔 -📕 -📖 -📗 -📘 -📙 -📚 -📛 -📜 -📝 -📞 -📟 -📠 -📡 -📢 -📣 -📤 -📥 -📦 -📧 -📨 -📩 -📪 -📫 -📮 -📰 -📱 -📲 -📳 -📴 -📶 -📷 -📹 -📺 -📻 -📼 -🔃 -🔊 -🔋 -🔌 -🔍 -🔎 -🔏 -🔐 -🔑 -🔒 -🔓 -🔔 -🔖 -🔗 -🔘 -🔙 -🔚 -🔛 -🔜 -🔝 -🔞 -🔟 -🔠 -🔡 -🔢 -🔣 -🔤 -🔥 -🔦 -🔧 -🔨 -🔩 -🔪 -🔫 -🔮 -🔯 -🔰 -🔱 -🔲 -🔳 -🔴 -🔵 -🔶 -🔷 -🔸 -🔹 -🔺 -🔻 -🔼 -🔽 -🕐 -🕑 -🕒 -🕓 -🕔 -🕕 -🕖 -🕗 -🕘 -🕙 -🕚 -🕛 -🗻 -🗼 -🗽 -🗾 -🗿 -😀 -😇 -😈 -😎 -😐 -😑 -😕 -😗 -😙 -😛 -😟 -😦 -😧 -😬 -😮 -😯 -😴 -😶 -🚁 -🚂 -🚆 -🚈 -🚊 -🚍 -🚎 -🚐 -🚔 -🚖 -🚘 -🚛 -🚜 -🚝 -🚞 -🚟 -🚠 -🚡 -🚣 -🚦 -🚮 -🚯 -🚰 -🚱 -🚳 -🚴 -🚵 -🚷 -🚸 -🚿 -🛁 -🛂 -🛃 -🛄 -🛅 -🌍 -🌎 -🌐 -🌒 -🌖 -🌗 -🌘 -🌚 -🌜 -🌝 -🌞 -🌲 -🌳 -🍋 -🍐 -🍼 -🏇 -🏉 -🏤 -🐀 -🐁 -🐂 -🐃 -🐄 -🐅 -🐆 -🐇 -🐈 -🐉 -🐊 -🐋 -🐏 -🐐 -🐓 -🐕 -🐖 -🐪 -👥 -👬 -👭 -💭 -💶 -💷 -📬 -📭 -📯 -📵 -🔀 -🔁 -🔂 -🔄 -🔅 -🔆 -🔇 -🔉 -🔕 -🔬 -🔭 -🕜 -🕝 -🕞 -🕟 -🕠 -🕡 -🕢 -🕣 -🕤 -🕥 -🕦 -🕧 diff --git a/src/main.cpp b/src/main.cpp index 3b3cc32..710ad5e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include namespace fs = std::filesystem; @@ -22,31 +25,168 @@ static void signal_handler(int sig) { } } -static void print_usage(const char* prog) { +static void print_usage(const char* prog, bool advanced = false) { std::cout << "Usage: " << prog << " [options]\n" << "Options:\n" + << " --model-type PP-OCRv6 model type: tiny, small, medium (default: small)\n" + << " --device Inference device: cpu or gpu (default: cpu)\n" + << " --model-dir Directory containing LiteOCR ncnn models (default: ..\\LiteOCR\\models)\n" + << " --port HTTP listen port (default: 8082)\n" + << " --host HTTP listen host (default: 127.0.0.1)\n" + << " --help Show this help message\n" + << " --help-advanced Show developer and tuning options\n"; + if (!advanced) { + return; + } + + std::cout << "\nAdvanced options:\n" << " --backend OCR backend: tesseract or ncnn (default: auto)\n" << " --datapath Path to tessdata directory for Tesseract\n" << " --lang Tesseract OCR language, e.g. eng, chi_sim (default: eng)\n" - << " --model-dir Directory containing ncnn PP-OCRv5 models (default: models)\n" - << " --model-type ncnn model type: mobile or server (default: mobile)\n" - << " --use-vulkan Enable ncnn Vulkan compute\n" - << " --port HTTP listen port (default: 8080)\n" - << " --host HTTP listen host (default: 0.0.0.0)\n" - << " --help Show this help message\n"; + << " --model-version ncnn model version: v5 or v6 (default: v6)\n" + << " --quality Compatibility alias: fast, balanced, accurate\n" + << " --use-vulkan Enable ncnn Vulkan compute (same as --device gpu)\n" + << " --gpu-device ncnn Vulkan GPU device id (default: 0 when GPU is enabled)\n" + << " --threads ncnn CPU inference thread count (default: 4)\n" + << " --fp16 Enable ncnn FP16 arithmetic/storage/packing\n" + << " --fast-mode Skip direction classifier and 180-degree fallback recognition\n" + << " --bf16 Enable ncnn BF16 storage/packing\n"; +} + +#ifdef OCR_HAS_NCNN +static bool contains(const std::vector& values, const std::string& value) { + return std::find(values.begin(), values.end(), value) != values.end(); +} + +static fs::path first_existing_path(const fs::path& root, const std::vector& names) { + for (const auto& name : names) { + fs::path path = root / name; + if (fs::exists(path)) { + return path; + } + } + return root / names.front(); +} + +static std::vector ocr_model_file_candidates(const std::vector& prefixes, + const std::string& role, + const std::string& extension) { + std::vector names; + for (const auto& prefix : prefixes) { + names.push_back(prefix + "_" + role + "." + extension); + } + return names; +} + +static void set_first_existing_model_pair(const fs::path& root, + const std::vector>& candidates, + std::string& param_path, + std::string& bin_path) { + for (const auto& [param_name, bin_name] : candidates) { + const fs::path param = root / param_name; + const fs::path bin = root / bin_name; + if (fs::exists(param) && fs::exists(bin)) { + param_path = param.string(); + bin_path = bin.string(); + return; + } + } + + param_path = (root / candidates.front().first).string(); + bin_path = (root / candidates.front().second).string(); } +static bool apply_quality_alias(const std::string& quality, std::string& model_version, std::string& model_type) { + if (quality == "fast") { + model_version = "v6"; + model_type = "tiny"; + return true; + } + if (quality == "balanced") { + model_version = "v6"; + model_type = "small"; + return true; + } + if (quality == "accurate") { + model_version = "v6"; + model_type = "medium"; + return true; + } + + std::cerr << "Error: --quality must be fast, balanced, or accurate" << std::endl; + return false; +} + +static bool resolve_ncnn_model_paths(const fs::path& root, const std::string& model_version, + const std::string& requested_model_type, + ocr::NcnnOcrModelPaths& model_paths, + std::string& resolved_model_type) { + std::vector prefixes; + std::vector dict_candidates; + + if (model_version == "v5") { + resolved_model_type = requested_model_type == "auto" ? "mobile" : requested_model_type; + if (!contains({"mobile", "server"}, resolved_model_type)) { + std::cerr << "Error: v5 --model-type must be auto, mobile, or server" << std::endl; + return false; + } + + prefixes = { + "PP-OCRv5_" + resolved_model_type, + }; + dict_candidates = { + "PP-OCRv5_vocab.txt", + }; + } else if (model_version == "v6") { + resolved_model_type = requested_model_type == "auto" ? "small" : requested_model_type; + if (!contains({"tiny", "small", "medium"}, resolved_model_type)) { + std::cerr << "Error: v6 --model-type must be auto, tiny, small, or medium" << std::endl; + return false; + } + + prefixes = { + "PP-OCRv6_" + resolved_model_type, + }; + dict_candidates = resolved_model_type == "tiny" + ? std::vector{"PP-OCRv6_vocab_tiny.txt", "PP-OCRv6_vocab.txt"} + : std::vector{"PP-OCRv6_vocab.txt"}; + } else { + std::cerr << "Error: --model-version must be v5 or v6" << std::endl; + return false; + } + + model_paths.det_param = first_existing_path(root, ocr_model_file_candidates(prefixes, "det", "param")).string(); + model_paths.det_bin = first_existing_path(root, ocr_model_file_candidates(prefixes, "det", "bin")).string(); + model_paths.rec_param = first_existing_path(root, ocr_model_file_candidates(prefixes, "rec", "param")).string(); + model_paths.rec_bin = first_existing_path(root, ocr_model_file_candidates(prefixes, "rec", "bin")).string(); + model_paths.dict_path = first_existing_path(root, dict_candidates).string(); + set_first_existing_model_pair(root, + std::vector>{ + {"PP-LCNet_x1_0_textline_ori.param", "PP-LCNet_x1_0_textline_ori.bin"}, + }, + model_paths.cls_param, model_paths.cls_bin); + return true; +} +#endif + int main(int argc, char* argv[]) { std::string backend = "auto"; std::string datapath; std::string lang = "eng"; - std::string model_dir = "models"; - std::string model_type = "mobile"; - std::string host = "0.0.0.0"; - int port = 8080; - bool use_vulkan = false; + std::string model_dir = "../LiteOCR/models"; + std::string model_version = "v6"; + std::string model_type = "small"; + std::string resolved_model_type; + std::string quality_alias; + bool model_version_specified = false; + bool model_type_specified = false; + std::string host = "127.0.0.1"; + int port = 8082; +#ifdef OCR_HAS_NCNN + ocr::NcnnOcrOptions ncnn_options; +#endif - // Simple argument parsing + // 这里保持轻量解析,避免为了少量启动参数引入额外依赖。 for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "--backend" && i + 1 < argc) { @@ -57,17 +197,74 @@ int main(int argc, char* argv[]) { lang = argv[++i]; } else if (arg == "--model-dir" && i + 1 < argc) { model_dir = argv[++i]; + } else if (arg == "--quality" && i + 1 < argc) { + quality_alias = argv[++i]; + } else if (arg == "--device" && i + 1 < argc) { + const std::string device = argv[++i]; + if (device == "cpu") { +#ifdef OCR_HAS_NCNN + ncnn_options.use_vulkan = false; + ncnn_options.gpu_device_id = -1; +#endif + } else if (device == "gpu") { +#ifdef OCR_HAS_NCNN + ncnn_options.use_vulkan = true; + if (ncnn_options.gpu_device_id < 0) { + ncnn_options.gpu_device_id = 0; + } +#endif + } else { + std::cerr << "Error: --device must be cpu or gpu" << std::endl; + return 1; + } + } else if (arg == "--model-version" && i + 1 < argc) { + model_version = argv[++i]; + model_version_specified = true; } else if (arg == "--model-type" && i + 1 < argc) { model_type = argv[++i]; + model_type_specified = true; } else if (arg == "--port" && i + 1 < argc) { port = std::stoi(argv[++i]); } else if (arg == "--host" && i + 1 < argc) { host = argv[++i]; } else if (arg == "--use-vulkan") { - use_vulkan = true; +#ifdef OCR_HAS_NCNN + ncnn_options.use_vulkan = true; + if (ncnn_options.gpu_device_id < 0) { + ncnn_options.gpu_device_id = 0; + } +#endif + } else if (arg == "--gpu-device" && i + 1 < argc) { +#ifdef OCR_HAS_NCNN + ncnn_options.gpu_device_id = std::stoi(argv[++i]); + ncnn_options.use_vulkan = ncnn_options.gpu_device_id >= 0; +#else + ++i; +#endif + } else if (arg == "--threads" && i + 1 < argc) { +#ifdef OCR_HAS_NCNN + ncnn_options.num_threads = std::max(1, std::stoi(argv[++i])); +#else + ++i; +#endif + } else if (arg == "--fp16") { +#ifdef OCR_HAS_NCNN + ncnn_options.use_fp16 = true; +#endif + } else if (arg == "--fast-mode") { +#ifdef OCR_HAS_NCNN + ncnn_options.fast_mode = true; +#endif + } else if (arg == "--bf16") { +#ifdef OCR_HAS_NCNN + ncnn_options.use_bf16 = true; +#endif } else if (arg == "--help") { print_usage(argv[0]); return 0; + } else if (arg == "--help-advanced") { + print_usage(argv[0], true); + return 0; } else { std::cerr << "Unknown option: " << arg << std::endl; print_usage(argv[0]); @@ -86,7 +283,7 @@ int main(int argc, char* argv[]) { #endif } - // Set up signal handlers for graceful shutdown + // 服务常驻运行,收到终止信号时先让 HTTP server 退出监听。 std::signal(SIGINT, signal_handler); std::signal(SIGTERM, signal_handler); @@ -130,22 +327,26 @@ int main(int argc, char* argv[]) { return 1; #else const fs::path root = fs::path(model_dir); - if (model_type != "mobile" && model_type != "server") { - std::cerr << "Error: --model-type must be mobile or server" << std::endl; + ocr::NcnnOcrModelPaths model_paths; + if (!quality_alias.empty() && (model_version_specified || model_type_specified)) { + std::cerr << "Error: --quality cannot be used with --model-version or --model-type" << std::endl; + return 1; + } + if (!quality_alias.empty() && !apply_quality_alias(quality_alias, model_version, model_type)) { + return 1; + } + if (!model_version_specified && model_type_specified && contains({"mobile", "server"}, model_type)) { + model_version = "v5"; + } + if (model_version_specified && !model_type_specified && model_version == "v5") { + model_type = "auto"; + } + if (!resolve_ncnn_model_paths(root, model_version, model_type, model_paths, resolved_model_type)) { return 1; } - - const std::string model_prefix = model_type == "server" ? "PP_OCRv5_server" : "PP_OCRv5_mobile"; - ocr::NcnnOcrModelPaths model_paths; - model_paths.det_param = (root / (model_prefix + "_det.param")).string(); - model_paths.det_bin = (root / (model_prefix + "_det.bin")).string(); - model_paths.rec_param = (root / (model_prefix + "_rec.param")).string(); - model_paths.rec_bin = (root / (model_prefix + "_rec.bin")).string(); - model_paths.cls_param = (root / "PP_LCNet_x0_25_textline_ori.param").string(); - model_paths.cls_bin = (root / "PP_LCNet_x0_25_textline_ori.bin").string(); ncnn_engine = std::make_unique(); - if (!ncnn_engine->init(model_paths, use_vulkan)) { + if (!ncnn_engine->init(model_paths, ncnn_options)) { std::cerr << "Failed to initialize ncnn OCR engine" << std::endl; return 1; } @@ -166,7 +367,18 @@ int main(int argc, char* argv[]) { std::cout << "=== OCR HTTP Service ===" << std::endl; std::cout << "Backend: " << backend << std::endl; if (backend == "ncnn") { - std::cout << "Model type: " << model_type << std::endl; + if (!quality_alias.empty()) { + std::cout << "Quality alias: " << quality_alias << std::endl; + } + std::cout << "Model version: " << model_version << std::endl; + std::cout << "Model type: " << resolved_model_type << std::endl; +#ifdef OCR_HAS_NCNN + std::cout << "Threads: " << ncnn_options.num_threads << std::endl; + std::cout << "GPU device: " << ncnn_options.gpu_device_id << std::endl; + std::cout << "FP16: " << (ncnn_options.use_fp16 ? "on" : "off") << std::endl; + std::cout << "BF16: " << (ncnn_options.use_bf16 ? "on" : "off") << std::endl; + std::cout << "Fast mode: " << (ncnn_options.fast_mode ? "on" : "off") << std::endl; +#endif } std::cout << "Version: " << version << std::endl; std::cout << "Endpoints:" << std::endl; diff --git a/src/ncnn_ocr_engine.cpp b/src/ncnn_ocr_engine.cpp index 24f7d43..7ba9027 100644 --- a/src/ncnn_ocr_engine.cpp +++ b/src/ncnn_ocr_engine.cpp @@ -2,6 +2,9 @@ #ifdef OCR_HAS_NCNN #include +#if NCNN_VULKAN +#include +#endif #endif #include @@ -18,6 +21,10 @@ namespace fs = std::filesystem; +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + namespace ocr { #ifdef OCR_HAS_NCNN @@ -39,6 +46,22 @@ struct PointF { float y = 0.f; }; +struct PointI { + int x = 0; + int y = 0; +}; + +struct SizeF { + float width = 0.f; + float height = 0.f; +}; + +struct RotatedRect { + PointF center; + SizeF size; + float angle = 0.f; +}; + struct RotatedTextBox { std::array corners; float score = 0.f; @@ -118,10 +141,16 @@ static std::string decode_text(const std::vector& dict, const std:: int conf_count = 0; for (const auto& token : tokens) { - if (token.id < 0 || token.id >= static_cast(dict.size())) + if (token.id < 0) continue; - text += dict[token.id]; + if (token.id < static_cast(dict.size())) { + text += dict[token.id]; + } else if (token.id == static_cast(dict.size()) && !text.empty() && text.back() != ' ') { + text += ' '; + } else { + continue; + } conf_sum += token.prob; conf_count++; } @@ -159,6 +188,235 @@ static float polygon_area(const std::array& points) { return std::abs(area) * 0.5f; } +static float polygon_area(const std::vector& points) { + if (points.size() < 3) + return 0.f; + + float area = 0.f; + for (size_t i = 0; i < points.size(); ++i) { + const auto& a = points[i]; + const auto& b = points[(i + 1) % points.size()]; + area += a.x * b.y - a.y * b.x; + } + return std::abs(area) * 0.5f; +} + +static std::vector convex_hull(std::vector points) { + if (points.size() <= 1) + return points; + + std::sort(points.begin(), points.end(), [](const PointI& a, const PointI& b) { + return a.x < b.x || (a.x == b.x && a.y < b.y); + }); + + const auto cross = [](const PointI& o, const PointI& a, const PointI& b) -> long long { + return static_cast(a.x - o.x) * (b.y - o.y) - + static_cast(a.y - o.y) * (b.x - o.x); + }; + + std::vector hull; + hull.reserve(points.size() * 2); + for (const auto& p : points) { + while (hull.size() >= 2 && cross(hull[hull.size() - 2], hull.back(), p) <= 0) + hull.pop_back(); + hull.push_back(p); + } + + const size_t lower_size = hull.size(); + for (int i = static_cast(points.size()) - 2; i >= 0; --i) { + const auto& p = points[static_cast(i)]; + while (hull.size() > lower_size && cross(hull[hull.size() - 2], hull.back(), p) <= 0) + hull.pop_back(); + hull.push_back(p); + } + + if (!hull.empty()) + hull.pop_back(); + return hull; +} + +static RotatedRect min_area_rect(const std::vector& contour) { + if (contour.empty()) + return {}; + if (contour.size() == 1) + return {{static_cast(contour[0].x), static_cast(contour[0].y)}, {}, 0.f}; + + const auto hull = convex_hull(contour); + if (hull.size() == 2) { + const float cx = (hull[0].x + hull[1].x) * 0.5f; + const float cy = (hull[0].y + hull[1].y) * 0.5f; + const float dx = static_cast(hull[1].x - hull[0].x); + const float dy = static_cast(hull[1].y - hull[0].y); + const float len = std::sqrt(dx * dx + dy * dy); + const float angle = std::atan2(dy, dx) * 180.f / static_cast(M_PI); + return {{cx, cy}, {len, 0.f}, angle}; + } + + float best_area = std::numeric_limits::max(); + RotatedRect best; + for (size_t i = 0; i < hull.size(); ++i) { + const auto& a = hull[i]; + const auto& b = hull[(i + 1) % hull.size()]; + const float ex = static_cast(b.x - a.x); + const float ey = static_cast(b.y - a.y); + const float len = std::sqrt(ex * ex + ey * ey); + if (len < 1e-6f) + continue; + + const float ux = ex / len; + const float uy = ey / len; + const float vx = -uy; + const float vy = ux; + float min_u = std::numeric_limits::max(); + float max_u = std::numeric_limits::lowest(); + float min_v = std::numeric_limits::max(); + float max_v = std::numeric_limits::lowest(); + + for (const auto& p : hull) { + const float px = static_cast(p.x - a.x); + const float py = static_cast(p.y - a.y); + const float pu = px * ux + py * uy; + const float pv = px * vx + py * vy; + min_u = std::min(min_u, pu); + max_u = std::max(max_u, pu); + min_v = std::min(min_v, pv); + max_v = std::max(max_v, pv); + } + + const float rect_w = max_u - min_u; + const float rect_h = max_v - min_v; + const float area = rect_w * rect_h; + if (area >= best_area) + continue; + + const float cu = (min_u + max_u) * 0.5f; + const float cv = (min_v + max_v) * 0.5f; + best_area = area; + best.center = { + static_cast(a.x) + cu * ux + cv * vx, + static_cast(a.y) + cu * uy + cv * vy, + }; + best.size = {rect_w, rect_h}; + best.angle = std::atan2(uy, ux) * 180.f / static_cast(M_PI); + } + + if (best.angle >= 90.f) + best.angle -= 180.f; + if (best.angle < -90.f) + best.angle += 180.f; + if (best.angle >= 0.f) { + std::swap(best.size.width, best.size.height); + best.angle -= 90.f; + } + return best; +} + +static std::array rotated_rect_points(const RotatedRect& rect) { + const float half_w = rect.size.width * 0.5f; + const float half_h = rect.size.height * 0.5f; + const float angle = rect.angle * static_cast(M_PI) / 180.f; + const float c = std::cos(angle); + const float s = std::sin(angle); + + return { + PointF{rect.center.x - half_w * c + half_h * s, rect.center.y - half_w * s - half_h * c}, + PointF{rect.center.x + half_w * c + half_h * s, rect.center.y + half_w * s - half_h * c}, + PointF{rect.center.x + half_w * c - half_h * s, rect.center.y + half_w * s + half_h * c}, + PointF{rect.center.x - half_w * c - half_h * s, rect.center.y - half_w * s + half_h * c}, + }; +} + +static std::array order_box_points(std::array points) { + std::sort(points.begin(), points.end(), [](const PointF& a, const PointF& b) { + return a.x < b.x; + }); + + const PointF tl = points[0].y < points[1].y ? points[0] : points[1]; + const PointF bl = points[0].y < points[1].y ? points[1] : points[0]; + const PointF tr = points[2].y < points[3].y ? points[2] : points[3]; + const PointF br = points[2].y < points[3].y ? points[3] : points[2]; + return {tl, tr, br, bl}; +} + +static bool point_in_polygon(float x, float y, const std::vector& polygon) { + bool inside = false; + for (size_t i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) { + const auto& a = polygon[i]; + const auto& b = polygon[j]; + const bool crosses = ((a.y > y) != (b.y > y)) && + (x < (b.x - a.x) * (y - a.y) / ((b.y - a.y) + 1e-6f) + a.x); + if (crosses) + inside = !inside; + } + return inside; +} + +static float box_score(const ncnn::Mat& prob, const std::vector& box) { + if (box.size() < 4) + return 0.f; + + float min_x = std::numeric_limits::max(); + float min_y = std::numeric_limits::max(); + float max_x = std::numeric_limits::lowest(); + float max_y = std::numeric_limits::lowest(); + for (const auto& p : box) { + min_x = std::min(min_x, p.x); + min_y = std::min(min_y, p.y); + max_x = std::max(max_x, p.x); + max_y = std::max(max_y, p.y); + } + + const int x1 = std::clamp(static_cast(std::floor(min_x)), 0, prob.w - 1); + const int y1 = std::clamp(static_cast(std::floor(min_y)), 0, prob.h - 1); + const int x2 = std::clamp(static_cast(std::ceil(max_x)), x1, prob.w - 1); + const int y2 = std::clamp(static_cast(std::ceil(max_y)), y1, prob.h - 1); + + double sum = 0.0; + int count = 0; + for (int y = y1; y <= y2; ++y) { + const float* row = prob.row(y); + for (int x = x1; x <= x2; ++x) { + if (point_in_polygon(x + 0.5f, y + 0.5f, box)) { + sum += row[x]; + count++; + } + } + } + return count > 0 ? static_cast(sum / count) : 0.f; +} + +static std::vector unclip_box(const std::vector& box, float ratio) { + if (box.size() < 4) + return box; + + float cx = 0.f; + float cy = 0.f; + for (const auto& p : box) { + cx += p.x; + cy += p.y; + } + cx /= static_cast(box.size()); + cy /= static_cast(box.size()); + + float perimeter = 0.f; + for (size_t i = 0; i < box.size(); ++i) { + perimeter += distance_between(box[i], box[(i + 1) % box.size()]); + } + const float area = polygon_area(box); + const float distance = perimeter > 1e-6f ? area * ratio / perimeter : 0.f; + + std::vector expanded; + expanded.reserve(box.size()); + for (const auto& p : box) { + const float dx = p.x - cx; + const float dy = p.y - cy; + const float len = std::sqrt(dx * dx + dy * dy); + const float scale = len > 1e-6f ? (len + distance) / len : 1.f; + expanded.push_back({cx + dx * scale, cy + dy * scale}); + } + return expanded; +} + static void axis_aligned_bounds(const RotatedTextBox& box, int image_width, int image_height, int& x1, int& y1, int& x2, int& y2) { float min_x = std::numeric_limits::max(); @@ -340,7 +598,8 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s return {}; } - // DB 检测输出是文字概率图,这里提取连通区域并转换为旋转文本框。 + // DB 检测输出是文字概率图。这里按 LiteOCR/PaddleOCR 的常规后处理: + // 二值连通区域 -> 最小外接旋转矩形 -> mask 平均分 -> unclip。 const int map_width = out.w; const int map_height = out.h; std::vector visited(static_cast(map_width) * map_height, 0); @@ -348,9 +607,9 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s const float threshold = 0.3f; const int min_area = 6; - const float box_thresh = 0.5f; - const float unclip_ratio = 1.58f; - const float min_size = 3.f * scale; + const float box_thresh = 0.6f; + const float unclip_ratio = 1.5f; + const float min_size = 3.f; for (int y = 0; y < map_height; ++y) { const float* row = out.row(y); @@ -359,9 +618,8 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s if (visited[index] || row[x] < threshold) continue; - float score_sum = 0.f; int count = 0; - std::vector component_points; + std::vector component_points; std::queue> pending; pending.push({x, y}); visited[index] = 1; @@ -370,10 +628,8 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s const auto [cx, cy] = pending.front(); pending.pop(); - const float score = out.row(cy)[cx]; - score_sum += score; count++; - component_points.push_back({cx + 0.5f, cy + 0.5f}); + component_points.push_back({cx, cy}); constexpr int dx[4] = {1, -1, 0, 0}; constexpr int dy[4] = {0, 0, 1, -1}; @@ -395,85 +651,27 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s if (count < min_area) continue; - const float component_score = score_sum / count; - if (component_score < box_thresh) + const RotatedRect rect = min_area_rect(component_points); + if (std::min(rect.size.width, rect.size.height) < min_size) continue; - float mean_x = 0.f; - float mean_y = 0.f; - for (const auto& p : component_points) { - mean_x += p.x; - mean_y += p.y; - } - mean_x /= component_points.size(); - mean_y /= component_points.size(); - - float cov_xx = 0.f; - float cov_xy = 0.f; - float cov_yy = 0.f; - for (const auto& p : component_points) { - const float dx = p.x - mean_x; - const float dy = p.y - mean_y; - cov_xx += dx * dx; - cov_xy += dx * dy; - cov_yy += dy * dy; - } - - const float angle = 0.5f * std::atan2(2.f * cov_xy, cov_xx - cov_yy); - PointF major{std::cos(angle), std::sin(angle)}; - if (major.x < 0.f) { - major.x = -major.x; - major.y = -major.y; - } - PointF minor{-major.y, major.x}; - if (minor.y < 0.f) { - minor.x = -minor.x; - minor.y = -minor.y; - } + const auto raw_array = order_box_points(rotated_rect_points(rect)); + const std::vector raw_box(raw_array.begin(), raw_array.end()); + const float component_score = box_score(out, raw_box); + if (component_score < box_thresh) + continue; - float min_major = std::numeric_limits::max(); - float max_major = std::numeric_limits::lowest(); - float min_minor = std::numeric_limits::max(); - float max_minor = std::numeric_limits::lowest(); - for (const auto& p : component_points) { - const float px = p.x - mean_x; - const float py = p.y - mean_y; - const float major_projection = px * major.x + py * major.y; - const float minor_projection = px * minor.x + py * minor.y; - min_major = std::min(min_major, major_projection); - max_major = std::max(max_major, major_projection); - min_minor = std::min(min_minor, minor_projection); - max_minor = std::max(max_minor, minor_projection); + const auto expanded = unclip_box(raw_box, unclip_ratio); + std::vector expanded_contour; + expanded_contour.reserve(expanded.size()); + for (const auto& p : expanded) { + expanded_contour.push_back({static_cast(std::round(p.x)), static_cast(std::round(p.y))}); } - - float text_width = std::max(1.f, max_major - min_major + 1.f); - float text_height = std::max(1.f, max_minor - min_minor + 1.f); - if (std::max(text_width, text_height) < min_size) + const RotatedRect expanded_rect = min_area_rect(expanded_contour); + if (std::min(expanded_rect.size.width, expanded_rect.size.height) < min_size + 2.f) continue; - const float center_major = (min_major + max_major) * 0.5f; - const float center_minor = (min_minor + max_minor) * 0.5f; - PointF center{ - mean_x + major.x * center_major + minor.x * center_minor, - mean_y + major.y * center_major + minor.y * center_minor, - }; - - const std::array raw_box{ - PointF{center.x - major.x * text_width * 0.5f - minor.x * text_height * 0.5f, - center.y - major.y * text_width * 0.5f - minor.y * text_height * 0.5f}, - PointF{center.x + major.x * text_width * 0.5f - minor.x * text_height * 0.5f, - center.y + major.y * text_width * 0.5f - minor.y * text_height * 0.5f}, - PointF{center.x + major.x * text_width * 0.5f + minor.x * text_height * 0.5f, - center.y + major.y * text_width * 0.5f + minor.y * text_height * 0.5f}, - PointF{center.x - major.x * text_width * 0.5f + minor.x * text_height * 0.5f, - center.y - major.y * text_width * 0.5f + minor.y * text_height * 0.5f}, - }; - const float perimeter = 2.f * (text_width + text_height); - const float unclip_distance = perimeter > 1e-6f ? polygon_area(raw_box) * unclip_ratio / perimeter : 0.f; - text_width += unclip_distance * 2.f; - text_height += unclip_distance * 2.f; - const float half_width = text_width * 0.5f; - const float half_height = text_height * 0.5f; + const auto mapped_box = order_box_points(rotated_rect_points(expanded_rect)); const float sx = static_cast(in_pad.w) / map_width; const float sy = static_cast(in_pad.h) / map_height; @@ -485,31 +683,20 @@ static std::vector detect_text_boxes(ncnn::Net& det_net, const s }; RotatedTextBox box; - box.corners[0] = - to_original({center.x - major.x * half_width - minor.x * half_height, - center.y - major.y * half_width - minor.y * half_height}); - box.corners[1] = - to_original({center.x + major.x * half_width - minor.x * half_height, - center.y + major.y * half_width - minor.y * half_height}); - box.corners[2] = - to_original({center.x + major.x * half_width + minor.x * half_height, - center.y + major.y * half_width + minor.y * half_height}); - box.corners[3] = - to_original({center.x - major.x * half_width + minor.x * half_height, - center.y - major.y * half_width + minor.y * half_height}); + for (size_t i = 0; i < box.corners.size(); ++i) { + box.corners[i] = to_original(mapped_box[i]); + } box.score = component_score; boxes.push_back(box); } } std::sort(boxes.begin(), boxes.end(), [](const RotatedTextBox& a, const RotatedTextBox& b) { - const float ay = (a.corners[0].y + a.corners[1].y + a.corners[2].y + a.corners[3].y) * 0.25f; - const float by = (b.corners[0].y + b.corners[1].y + b.corners[2].y + b.corners[3].y) * 0.25f; - if (std::abs(ay - by) > 10) - return ay < by; - const float ax = (a.corners[0].x + a.corners[1].x + a.corners[2].x + a.corners[3].x) * 0.25f; - const float bx = (b.corners[0].x + b.corners[1].x + b.corners[2].x + b.corners[3].x) * 0.25f; - return ax < bx; + const auto a_points = order_box_points(a.corners); + const auto b_points = order_box_points(b.corners); + if (std::abs(a_points[0].y - b_points[0].y) > 10.f) + return a_points[0].y < b_points[0].y; + return a_points[0].x < b_points[0].x; }); return boxes; @@ -579,23 +766,23 @@ static bool classify_needs_180(ncnn::Net& cls_net, const uint8_t* bgr, int width static bool recognize_crop_with_classifier(ncnn::Net& rec_net, ncnn::Net* cls_net, const std::vector& dict, const uint8_t* bgr, int width, int height, bool force_180, - std::string& text, float& confidence) { + bool fast_mode, std::string& text, float& confidence) { // 竖排长框先转成横向,再交给 PP-OCR 识别模型处理。 if (height >= static_cast(width * 1.5f)) { int rotated_width = 0; int rotated_height = 0; const auto rotated = rotate_90_counterclockwise_bgr(bgr, width, height, rotated_width, rotated_height); return recognize_crop_with_classifier(rec_net, cls_net, dict, rotated.data(), rotated_width, rotated_height, - force_180, text, confidence); + force_180, fast_mode, text, confidence); } - if (force_180) { + if (!fast_mode && force_180) { const auto rotated = rotate_180_bgr(bgr, width, height); return recognize_crop(rec_net, dict, rotated.data(), width, height, text, confidence); } bool prefer_180 = false; - if (cls_net != nullptr) { + if (!fast_mode && cls_net != nullptr) { float cls_score = 0.f; classify_needs_180(*cls_net, bgr, width, height, prefer_180, cls_score); } @@ -629,6 +816,11 @@ static bool recognize_crop_with_classifier(ncnn::Net& rec_net, ncnn::Net* cls_ne } const bool first_ok = recognize_crop(rec_net, dict, bgr, width, height, first_text, first_confidence); + if (fast_mode) { + text = std::move(first_text); + confidence = first_confidence; + return first_ok; + } if (first_ok && first_confidence >= 0.80f) { text = std::move(first_text); confidence = first_confidence; @@ -655,6 +847,7 @@ static bool recognize_crop_with_classifier(ncnn::Net& rec_net, ncnn::Net* cls_ne struct NcnnOcrEngine::Impl { NcnnOcrModelPaths model_paths; + NcnnOcrOptions options; std::vector character_dict; bool initialized = false; bool use_vulkan = false; @@ -680,9 +873,16 @@ const char* NcnnOcrEngine::version() { } bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, bool use_vulkan) { + NcnnOcrOptions options; + options.use_vulkan = use_vulkan; + options.gpu_device_id = use_vulkan ? 0 : -1; + return init(model_paths, options); +} + +bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, const NcnnOcrOptions& options) { #ifndef OCR_HAS_NCNN (void)model_paths; - (void)use_vulkan; + (void)options; std::cerr << "[NcnnOcrEngine] ncnn support is not enabled in this build" << std::endl; return false; #else @@ -705,7 +905,12 @@ bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, bool use_vulkan) return false; } - const fs::path dict_path = fs::path(model_paths.rec_param).parent_path() / "ppocrv5_dict.txt"; + const fs::path dict_path = model_paths.dict_path.empty() + ? fs::path(model_paths.rec_param).parent_path() / "PP-OCRv5_vocab.txt" + : fs::path(model_paths.dict_path); + if (!require_file(dict_path.string(), "dict_path")) { + return false; + } impl_->character_dict = load_character_dict(dict_path); if (impl_->character_dict.empty()) { std::cerr << "[NcnnOcrEngine] Character dict is empty: " << dict_path.string() << std::endl; @@ -716,9 +921,55 @@ bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, bool use_vulkan) impl_->rec_net.clear(); impl_->cls_net.clear(); - impl_->det_net.opt.use_vulkan_compute = use_vulkan; - impl_->rec_net.opt.use_vulkan_compute = use_vulkan; - impl_->cls_net.opt.use_vulkan_compute = use_vulkan; + // det/rec/cls 共用同一套推理选项,Vulkan 设备只探测一次,避免重复告警。 + bool enable_vulkan = false; + int vulkan_device_id = -1; +#if NCNN_VULKAN + if (options.use_vulkan || options.gpu_device_id >= 0) { + const int gpu_count = ncnn::get_gpu_count(); + if (gpu_count > 0) { + const int requested_device = options.gpu_device_id >= 0 ? options.gpu_device_id : 0; + if (requested_device < gpu_count) { + enable_vulkan = true; + vulkan_device_id = requested_device; + } else { + std::cerr << "[NcnnOcrEngine] GPU device " << requested_device + << " is unavailable; falling back to CPU" << std::endl; + } + } else { + std::cerr << "[NcnnOcrEngine] Vulkan requested but no GPU device is available; falling back to CPU" + << std::endl; + } + } +#else + if (options.use_vulkan || options.gpu_device_id >= 0) { + std::cerr << "[NcnnOcrEngine] Vulkan requested but this ncnn build has no Vulkan support; falling back to CPU" + << std::endl; + } +#endif + + auto apply_options = [&options, enable_vulkan, vulkan_device_id](ncnn::Net& net) { + net.opt.num_threads = std::max(1, options.num_threads); + net.opt.use_fp16_arithmetic = options.use_fp16; + net.opt.use_fp16_storage = options.use_fp16; + net.opt.use_fp16_packed = options.use_fp16; + if (options.use_bf16) { + net.opt.use_fp16_arithmetic = false; + net.opt.use_fp16_storage = false; + net.opt.use_fp16_packed = false; + net.opt.use_bf16_storage = true; + net.opt.use_bf16_packed = true; + } +#if NCNN_VULKAN + if (enable_vulkan) { + net.set_vulkan_device(vulkan_device_id); + net.opt.use_vulkan_compute = true; + } +#endif + }; + apply_options(impl_->det_net); + apply_options(impl_->rec_net); + apply_options(impl_->cls_net); if (impl_->det_net.load_param(model_paths.det_param.c_str()) != 0 || impl_->det_net.load_model(model_paths.det_bin.c_str()) != 0) { @@ -733,7 +984,9 @@ bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, bool use_vulkan) } impl_->cls_initialized = false; - if (!model_paths.cls_param.empty() && !model_paths.cls_bin.empty() && + if (options.fast_mode) { + impl_->cls_net.clear(); + } else if (!model_paths.cls_param.empty() && !model_paths.cls_bin.empty() && fs::exists(model_paths.cls_param) && fs::exists(model_paths.cls_bin)) { if (impl_->cls_net.load_param(model_paths.cls_param.c_str()) != 0 || impl_->cls_net.load_model(model_paths.cls_bin.c_str()) != 0) { @@ -748,14 +1001,21 @@ bool NcnnOcrEngine::init(const NcnnOcrModelPaths& model_paths, bool use_vulkan) } impl_->model_paths = model_paths; - impl_->use_vulkan = use_vulkan; + impl_->options = options; + impl_->use_vulkan = impl_->det_net.opt.use_vulkan_compute; impl_->initialized = true; std::cout << "[NcnnOcrEngine] Initialized" << " det=" << model_paths.det_param << " rec=" << model_paths.rec_param + << " dict=" << dict_path.string() << " cls=" << (impl_->cls_initialized ? model_paths.cls_param : "disabled") - << " use_vulkan=" << (use_vulkan ? "true" : "false") + << " threads=" << std::max(1, options.num_threads) + << " gpu_device=" << options.gpu_device_id + << " fp16=" << (options.use_fp16 ? "true" : "false") + << " bf16=" << (options.use_bf16 ? "true" : "false") + << " fast_mode=" << (options.fast_mode ? "true" : "false") + << " use_vulkan=" << (impl_->use_vulkan ? "true" : "false") << std::endl; return true; #endif @@ -786,7 +1046,8 @@ OcrResponse NcnnOcrEngine::recognize_with_profile(const uint8_t* image, int widt const auto det_start = Clock::now(); const auto boxes = detect_text_boxes(impl_->det_net, bgr, width, height); response.profile.det_ms = elapsed_ms(det_start, Clock::now()); - ncnn::Net* cls_net = impl_->cls_initialized ? &impl_->cls_net : nullptr; + const bool fast_mode = impl_->options.fast_mode; + ncnn::Net* cls_net = (!fast_mode && impl_->cls_initialized) ? &impl_->cls_net : nullptr; // 先用所有文本行投票判断整张图是否整体倒置,再逐行识别。 bool force_180 = false; @@ -821,7 +1082,7 @@ OcrResponse NcnnOcrEngine::recognize_with_profile(const uint8_t* image, int widt float confidence = 0.f; const auto rec_start = Clock::now(); if (!recognize_crop_with_classifier(impl_->rec_net, cls_net, impl_->character_dict, crop.data(), crop_width, - crop_height, force_180, text, confidence)) { + crop_height, force_180, fast_mode, text, confidence)) { response.profile.rec_ms += elapsed_ms(rec_start, Clock::now()); continue; } @@ -843,24 +1104,6 @@ OcrResponse NcnnOcrEngine::recognize_with_profile(const uint8_t* image, int widt response.results.push_back(std::move(result)); } - if (response.results.empty()) { - std::string text; - float confidence = 0.f; - const auto rec_start = Clock::now(); - if (recognize_crop_with_classifier(impl_->rec_net, cls_net, impl_->character_dict, bgr.data(), width, height, - force_180, text, confidence)) { - OcrResult result; - result.x1 = 0; - result.y1 = 0; - result.x2 = width; - result.y2 = height; - result.text = text; - result.confidence = confidence; - response.results.push_back(std::move(result)); - } - response.profile.rec_ms += elapsed_ms(rec_start, Clock::now()); - } - response.profile.total_ms = elapsed_ms(total_start, Clock::now()); return response; #endif diff --git a/src/ncnn_ocr_engine.h b/src/ncnn_ocr_engine.h index 9d2ba2d..241b3a3 100644 --- a/src/ncnn_ocr_engine.h +++ b/src/ncnn_ocr_engine.h @@ -12,10 +12,20 @@ struct NcnnOcrModelPaths { std::string det_bin; std::string rec_param; std::string rec_bin; + std::string dict_path; std::string cls_param; std::string cls_bin; }; +struct NcnnOcrOptions { + bool use_vulkan = false; + int gpu_device_id = -1; + int num_threads = 4; + bool use_fp16 = false; + bool use_bf16 = false; + bool fast_mode = false; +}; + class NcnnOcrEngine { public: NcnnOcrEngine(); @@ -24,8 +34,9 @@ class NcnnOcrEngine { NcnnOcrEngine(const NcnnOcrEngine&) = delete; NcnnOcrEngine& operator=(const NcnnOcrEngine&) = delete; - /// 使用已转换的 PP-OCRv5 ncnn 模型初始化 OCR 引擎。 - bool init(const NcnnOcrModelPaths& model_paths, bool use_vulkan = false); + /// 使用已转换的 PP-OCRv5/PP-OCRv6 ncnn 模型初始化 OCR 引擎。 + bool init(const NcnnOcrModelPaths& model_paths, const NcnnOcrOptions& options = {}); + bool init(const NcnnOcrModelPaths& model_paths, bool use_vulkan); /// 从原始图像字节中识别文字,返回文字内容、外接矩形和置信度。 std::vector recognize(const uint8_t* image, int width, int height, int bpp); diff --git a/tests/benchmark_ncnn_models.py b/tests/benchmark_ncnn_models.py new file mode 100644 index 0000000..8177b11 --- /dev/null +++ b/tests/benchmark_ncnn_models.py @@ -0,0 +1,227 @@ +import argparse +import base64 +import csv +import json +import statistics +import subprocess +import time +import urllib.request +from pathlib import Path + + +DEFAULT_VARIANTS = "v5:mobile,v6:tiny,v6:small,v6:medium" + + +def parse_variants(value): + variants = [] + for item in value.split(","): + item = item.strip() + if not item: + continue + version, _, model_type = item.partition(":") + if not version or not model_type: + raise SystemExit(f"Invalid variant {item!r}; expected version:type") + variants.append((version, model_type)) + if not variants: + raise SystemExit("No benchmark variants were provided") + return variants + + +def load_images(image_dir): + if not image_dir: + return [("synthetic-white-256x96", 256, 96, 1, bytes([255]) * 256 * 96)] + + try: + from PIL import Image + except ImportError as exc: + raise SystemExit("Pillow is required when --image-dir is used") from exc + + paths = [ + p for p in Path(image_dir).iterdir() + if p.suffix.lower() in {".png", ".jpg", ".jpeg", ".bmp"} + ] + if not paths: + raise SystemExit(f"No images found in {image_dir}") + + images = [] + for path in sorted(paths): + image = Image.open(path).convert("RGBA") + images.append((path.name, image.width, image.height, 4, image.tobytes())) + return images + + +def post_json(url, payload=None, timeout=20): + if payload is None: + request = urllib.request.Request(url) + else: + request = urllib.request.Request( + url, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"}, + ) + with urllib.request.urlopen(request, timeout=timeout) as response: + return response.status, json.loads(response.read().decode("utf-8")) + + +def wait_for_health(port, process, timeout): + deadline = time.time() + timeout + url = f"http://127.0.0.1:{port}/health" + while time.time() < deadline: + if process.poll() is not None: + return False + try: + status, body = post_json(url, timeout=2) + if status == 200 and body.get("status") == "ok": + return True + except Exception: + time.sleep(0.2) + return False + + +def stop_process(process): + if process.poll() is not None: + return + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + + +def run_variant(args, variant_index, version, model_type, images): + port = args.start_port + variant_index + command = [ + str(args.exe), + "--backend", "ncnn", + "--model-dir", str(args.model_dir), + "--model-version", version, + "--model-type", model_type, + "--host", "127.0.0.1", + "--port", str(port), + "--threads", str(args.threads), + ] + if args.use_vulkan: + command.append("--use-vulkan") + if args.gpu_device is not None: + command += ["--gpu-device", str(args.gpu_device)] + if args.fp16: + command.append("--fp16") + if args.bf16: + command.append("--bf16") + + process = subprocess.Popen( + command, + cwd=args.cwd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + encoding="utf-8", + errors="replace", + ) + try: + if not wait_for_health(port, process, args.startup_timeout): + output = process.stdout.read() if process.stdout else "" + raise SystemExit(f"{version}:{model_type} did not become healthy\n{output}") + + rows = [] + url = f"http://127.0.0.1:{port}/api/v1/ocr" + for image_name, width, height, bpp, pixels in images: + payload = { + "width": width, + "height": height, + "bpp": bpp, + "image": base64.b64encode(pixels).decode("ascii"), + } + for run in range(1, args.repeat + 1): + start = time.perf_counter() + status, body = post_json(url, payload, timeout=args.request_timeout) + elapsed_ms = (time.perf_counter() - start) * 1000.0 + if status != 200: + raise SystemExit(f"{version}:{model_type} returned HTTP {status}") + profile = body.get("profile_ms", {}) + rows.append({ + "variant": f"{version}:{model_type}", + "image": image_name, + "run": run, + "count": len(body.get("results", [])), + "elapsed_ms": elapsed_ms, + "det_ms": profile.get("det", 0.0), + "cls_ms": profile.get("cls", 0.0), + "rec_ms": profile.get("rec", 0.0), + "total_ms": profile.get("total", 0.0), + }) + return rows + finally: + stop_process(process) + + +def summarize(rows): + grouped = {} + for row in rows: + grouped.setdefault(row["variant"], []).append(row) + + for variant, items in grouped.items(): + elapsed = [r["elapsed_ms"] for r in items] + total = [float(r["total_ms"]) for r in items] + counts = [int(r["count"]) for r in items] + print( + f"{variant}: requests={len(items)} " + f"avg_elapsed={statistics.mean(elapsed):.2f}ms " + f"p50_elapsed={statistics.median(elapsed):.2f}ms " + f"avg_profile_total={statistics.mean(total):.2f}ms " + f"avg_results={statistics.mean(counts):.2f}" + ) + + +def main(): + parser = argparse.ArgumentParser(description="Benchmark op_ocr_engine ncnn model variants.") + parser.add_argument("--exe", type=Path, default=Path("build-vs2026-x64/Release/ocr_server.exe")) + parser.add_argument("--model-dir", type=Path, default=Path("../LiteOCR/models")) + parser.add_argument("--image-dir", type=Path, default=None) + parser.add_argument("--variants", default=DEFAULT_VARIANTS) + parser.add_argument("--repeat", type=int, default=3) + parser.add_argument("--threads", type=int, default=4) + parser.add_argument("--use-vulkan", action="store_true") + parser.add_argument("--gpu-device", type=int, default=None) + parser.add_argument("--fp16", action="store_true") + parser.add_argument("--bf16", action="store_true") + parser.add_argument("--start-port", type=int, default=18100) + parser.add_argument("--startup-timeout", type=float, default=30.0) + parser.add_argument("--request-timeout", type=float, default=60.0) + parser.add_argument("--csv", type=Path, default=None) + args = parser.parse_args() + + if args.repeat <= 0: + raise SystemExit("--repeat must be greater than 0") + if args.start_port <= 0 or args.start_port > 65535: + raise SystemExit("--start-port must be between 1 and 65535") + + args.cwd = Path.cwd() + args.exe = args.exe.resolve() + args.model_dir = args.model_dir.resolve() + if not args.exe.exists(): + raise SystemExit(f"Server executable not found: {args.exe}") + if not args.model_dir.exists(): + raise SystemExit(f"Model directory not found: {args.model_dir}") + + images = load_images(args.image_dir) + variants = parse_variants(args.variants) + + all_rows = [] + for index, (version, model_type) in enumerate(variants): + all_rows.extend(run_variant(args, index, version, model_type, images)) + + summarize(all_rows) + + if args.csv: + args.csv.parent.mkdir(parents=True, exist_ok=True) + with args.csv.open("w", newline="", encoding="utf-8") as file: + writer = csv.DictWriter(file, fieldnames=list(all_rows[0].keys())) + writer.writeheader() + writer.writerows(all_rows) + print(f"wrote {args.csv}") + + +if __name__ == "__main__": + main()