├── .vscode ├── launch.json └── settings.json ├── CMakeLists.txt ├── README.md ├── data ├── layout_publaynet_dict.txt ├── ocr.jpg ├── ppocr_keys_v1.txt ├── structure.png ├── table_structure_dict.txt └── table_structure_dict_ch.txt ├── include ├── args.h ├── clipper.h ├── ocr_cls.h ├── ocr_det.h ├── ocr_rec.h ├── paddleocr.h ├── paddlestructure.h ├── postprocess_op.h ├── preprocess_op.h ├── structure_layout.h ├── structure_table.h └── utility.h ├── main.cpp ├── ocr_result.jpg ├── ov_inference.py ├── paddle_inference.py ├── src ├── args.cpp ├── clipper.cpp ├── ocr_cls.cpp ├── ocr_det.cpp ├── ocr_rec.cpp ├── paddleocr.cpp ├── paddlestructure.cpp ├── postprocess_op.cpp ├── preprocess_op.cpp ├── rec.bak ├── structure_layout.cpp ├── structure_table.cpp └── utility.cpp ├── structure_result6.jpg └── structure_result7.jpg /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "cppdbg", 9 | "request": "launch", 10 | "name": "(gdb) Launch", 11 | "program": "/home/ethan/PaddleOCR_OpenVINO_CPP/build/ocr_reader", 12 | "args": ["/home/ethan/PaddleOCR_OpenVINO_CPP/data/00009282.jpg", 13 | "/home/ethan/PaddleOCR_OpenVINO_CPP/data/ppocr_keys_v1.txt", 14 | "/home/ethan/Downloads/PaddleOCR/ch_PP-OCRv3_det_infer/inference.pdmodel", 15 | "/home/ethan/Downloads/PaddleOCR/ch_ppocr_mobile_v2.0_cls_infer/inference.pdmodel", 16 | "/home/ethan/Downloads/PaddleOCR/ch_PP-OCRv3_rec_infer/inference.pdmodel" 17 | ], 18 | "stopOnEntry": true, 19 | "cwd": "/", 20 | "arguments": "" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.tcc": "cpp", 4 | "vector": "cpp", 5 | "string": "cpp", 6 | "cctype": "cpp", 7 | "clocale": "cpp", 8 | "cmath": "cpp", 9 | "cstdarg": "cpp", 10 | "cstddef": "cpp", 11 | "cstdio": "cpp", 12 | "cstdlib": "cpp", 13 | "cstring": "cpp", 14 | "ctime": "cpp", 15 | "cwchar": "cpp", 16 | "cwctype": "cpp", 17 | "array": "cpp", 18 | "atomic": "cpp", 19 | "bitset": "cpp", 20 | "chrono": "cpp", 21 | "cinttypes": "cpp", 22 | "complex": "cpp", 23 | "condition_variable": "cpp", 24 | "cstdint": "cpp", 25 | "deque": "cpp", 26 | "list": "cpp", 27 | "unordered_map": "cpp", 28 | "exception": "cpp", 29 | "algorithm": "cpp", 30 | "functional": "cpp", 31 | "iterator": "cpp", 32 | "map": "cpp", 33 | "memory": "cpp", 34 | "memory_resource": "cpp", 35 | "numeric": "cpp", 36 | "optional": "cpp", 37 | "random": "cpp", 38 | "ratio": "cpp", 39 | "set": "cpp", 40 | "string_view": "cpp", 41 | "system_error": "cpp", 42 | "tuple": "cpp", 43 | "type_traits": "cpp", 44 | "utility": "cpp", 45 | "fstream": "cpp", 46 | "initializer_list": "cpp", 47 | "iomanip": "cpp", 48 | "iosfwd": "cpp", 49 | "iostream": "cpp", 50 | "istream": "cpp", 51 | "limits": "cpp", 52 | "mutex": "cpp", 53 | "new": "cpp", 54 | "ostream": "cpp", 55 | "sstream": "cpp", 56 | "stdexcept": "cpp", 57 | "streambuf": "cpp", 58 | "thread": "cpp", 59 | "typeindex": "cpp", 60 | "typeinfo": "cpp", 61 | "variant": "cpp", 62 | "bit": "cpp" 63 | } 64 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | set(CMAKE_CXX_STANDARD 11) 3 | find_package(OpenCV REQUIRED) 4 | find_package(gflags REQUIRED) 5 | #find_package(OpenVINO REQUIRED) 6 | 7 | set(openvino_LIBRARIES "/opt/intel/openvino_2022.2/runtime/lib/intel64/libopenvino.so") 8 | 9 | include_directories( 10 | ./ 11 | /opt/intel/openvino_2022.2/runtime/include 12 | /opt/intel/openvino_2022.2/runtime/include/ie 13 | /opt/intel/openvino_2022.2/runtime/include/ngraph 14 | /opt/intel/openvino_2022.2/runtime/include/openvino 15 | ${OpenCV_INCLUDE_DIR} 16 | ) 17 | link_directories("/opt/intel/openvino_2022.2/runtime/lib") 18 | aux_source_directory(src SRC) 19 | add_executable(reader main.cpp ${SRC}) 20 | target_link_libraries(reader PRIVATE ${openvino_LIBRARIES} ${OpenCV_LIBS} gflags) 21 | 22 | SET(CMAKE_BUILD_TYPE "Debug") 23 | SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb") 24 | SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PaddleOCR_OpenVINO_CPP 2 | This sample shows how to use the OpenVINO C++ 2.0 API to deploy Paddle PP-OCRv3 and PP-structure models, modified from the example in [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.6/deploy/cpp_infer). 3 | 4 | ## PP-OCR 5 | PP-OCR is a two-stage OCR system, in which the text detection algorithm is DB, and the text recognition algorithm is SVTR. Besides, a text direction classifier is added between the detection and recognition modules to deal with text in different directions. 6 | 7 | ppocrv3_framework 8 | 9 | ## Layout Information Extraction 10 | In the layout analysis task, the image first goes through the layout analysis model to divide the image into different areas such as text, table, and figure, and then analyze these areas separately. For example, the table area is sent to the form recognition module for structured recognition, and the text area is sent to the OCR engine for text recognition. Finally, the layout recovery module restores it to a word or pdf file with the same layout as the original image. 11 | 12 | 13 | 14 | 15 | ## System requirements 16 | 17 | | Optimized for | Description 18 | |----------------- | ---------------------------------------- 19 | | OS | Ubuntu* 20.04 20 | | Hardware | Intel® - CPU platform 21 | | Software | Intel® - OpenVINO 2022.2 22 | 23 | ## How to build the sample 24 | 25 | ### Install OpenVINO toolkits 2022.2 from achieved package 26 | Download and install OpenVINO C++ runtime: 27 | https://docs.openvino.ai/latest/openvino_docs_install_guides_installing_openvino_from_archive_linux.html 28 | 29 | ### Download the repository 30 | ```shell 31 | $ git clone git@github.com:OpenVINO-dev-contest/PaddleOCR_OpenVINO_CPP.git 32 | ``` 33 | 34 | ### Configure the CMakeLists.txt 35 | set-up the OpenVINO library path according your installation. 36 | ```shell 37 | ... 38 | set(openvino_LIBRARIES "/opt/intel/openvino_2022.2/runtime/lib/intel64/libopenvino.so") 39 | 40 | include_directories( 41 | ./ 42 | /opt/intel/openvino_2022.2/runtime/include 43 | /opt/intel/openvino_2022.2/runtime/include/ie 44 | /opt/intel/openvino_2022.2/runtime/include/ngraph 45 | /opt/intel/openvino_2022.2/runtime/include/openvino 46 | ${OpenCV_INCLUDE_DIR} 47 | ) 48 | link_directories("/opt/intel/openvino_2022.2/runtime/lib") 49 | ... 50 | ``` 51 | 52 | ### Build the source code 53 | ``` 54 | $ mkdir build 55 | $ cd build 56 | $ cmake .. 57 | $ make 58 | ``` 59 | 60 | ### Download test model 61 | Download the models: 62 | 63 | **1) PP-OCRv3 Series Model List** 64 | 65 | | Model introduction | Model name | Recommended scene | Detection model | Direction classifier | Recognition model | 66 | | ------------------------------------------------------------ | ---------------------------- | ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 67 | | Chinese and English ultra-lightweight PP-OCRv3 model(16.2M) | ch_PP-OCRv3_xx | Mobile & Server | [inference model](https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar) | [inference model](https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar) | [inference model](https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar) | 68 | 69 | **2) PP-structure models** 70 | 71 | You can find the latest Layout Analysis model and Table Recognition model at [here](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/ppstructure/docs/models_list_en.md). 72 | 73 | ### Run the program 74 | **1) OCR** 75 | ``` 76 | $ ./build/reader \ 77 | -type ocr \ 78 | -input ~/input_image.jpg \ 79 | -label_dir ../data/ppocr_keys_v1.txt \ 80 | -det_model_dir ~/detection.pdmodel \ 81 | -cls_model_dir ~/classifier.pdmodel \ 82 | -rec_model_dir ~/recognizer.pdmodel 83 | ``` 84 | 85 | **2) Layout Information Extraction** 86 | ``` 87 | $ ./build/reader \ 88 | -type structure \ 89 | -input ~/input_image.jpg \ 90 | -label_dir ../data/ppocr_keys_v1.txt \ 91 | -layout_dict_dir ./data/layout_publaynet_dict.txt \ 92 | -table_dict_dir ./data/table_structure_dict.txt \ 93 | -det_model_dir ~/detection.pdmodel \ 94 | -rec_model_dir ~/recognizer.pdmodel \ 95 | -lay_model_dir ~/layout.pdmodel \ 96 | -tab_model_dir ~/table.pdmodel 97 | ``` 98 | 99 | p.s You can try [Paddle2onnx](https://github.com/PaddlePaddle/Paddle2ONNX) to convert a model unsupportted by OpenVINO yet. 100 | ### Output example 101 | 102 | **1) OCR** 103 | 104 | ![00056221](https://user-images.githubusercontent.com/91237924/205421176-77296ee7-f200-4914-a719-dc1e827d0dd1.jpg) 105 | ![result](https://user-images.githubusercontent.com/91237924/205421169-08045ce3-5e7d-42f5-bd1a-911f76aac59b.jpg) 106 | 107 | ``` 108 | 0 det boxes: [[0,0],[160,0],[160,51],[0,51]] rec text: 7788.com rec score: 0.9815 cls label: 0 cls score: 0.93939 109 | 1 det boxes: [[74,100],[231,98],[231,126],[74,128]] rec text: Z57A001950 rec score: 0.9929 cls label: 0 cls score: 1 110 | 2 det boxes: [[406,101],[508,101],[508,133],[406,133]] rec text: 杭州东售 rec score: 0.99703 cls label: 0 cls score: 1 111 | 3 det boxes: [[66,138],[325,137],[325,162],[66,163]] rec text: 2013年07月07日13:39开 rec score: 0.924703 cls label: 0 cls score: 1 112 | 4 det boxes: [[391,139],[506,139],[506,161],[391,161]] rec text: 06车12B号 rec score: 0.913608 cls label: 0 cls score: 1 113 | 5 det boxes: [[440,158],[508,156],[509,185],[441,187]] rec text: 二等座 rec score: 0.985737 cls label: 0 cls score: 0.998492 114 | 6 det boxes: [[89,179],[198,179],[198,217],[89,217]] rec text: 杭州东 rec score: 0.996495 cls label: 0 cls score: 1 115 | 7 det boxes: [[236,171],[354,173],[354,205],[236,203]] rec text: G7512次 rec score: 0.945879 cls label: 0 cls score: 1 116 | 8 det boxes: [[382,180],[521,182],[521,217],[382,215]] rec text: 上海虹桥 rec score: 0.982963 cls label: 0 cls score: 1 117 | 9 det boxes: [[78,214],[223,216],[223,241],[78,239]] rec text: HangZhouDong rec score: 0.989637 cls label: 0 cls score: 0.99992 118 | 10 det boxes: [[360,216],[529,216],[529,240],[360,240]] rec text: Shang HaiHongQiao rec score: 0.927789 cls label: 0 cls score: 1 119 | 11 det boxes: [[75,245],[181,245],[181,266],[75,266]] rec text: ¥73.00元 rec score: 0.937644 cls label: 0 cls score: 1 120 | 12 det boxes: [[75,273],[220,273],[220,298],[75,298]] rec text: 限乘当日当次车 rec score: 0.97018 cls label: 0 cls score: 1 121 | 13 det boxes: [[72,299],[148,299],[148,327],[72,327]] rec text: 余友红 rec score: 0.902762 cls label: 0 cls score: 1 122 | 14 det boxes: [[296,314],[406,304],[409,336],[299,346]] rec text: 检票口16 rec score: 0.981898 cls label: 0 cls score: 0.999999 123 | 15 det boxes: [[69,327],[286,321],[287,352],[70,358]] rec text: 3623301993****0941 rec score: 0.958505 cls label: 0 cls score: 1 124 | 16 det boxes: [[427,345],[449,343],[450,353],[428,355]] rec text: DA rec score: 0.379216 cls label: 0 cls score: 0.946252 125 | 17 det boxes: [[61,363],[327,363],[327,387],[61,387]] rec text: 9004-1300-5707-08A0-0195-0 rec score: 0.911793 cls label: 0 cls score: 0.999793 126 | 18 det boxes: [[419,357],[512,357],[512,382],[419,382]] rec text: 和谐号 rec score: 0.995543 cls label: 0 cls score: 0.999999 127 | 19 det boxes: [[14,492],[242,491],[242,506],[14,507]] rec text: Canon PowerShot A3400 IS F2.8 1/20s IS0400 rec score: 0.914529 cls label: 0 cls score: 0.998959 128 | ``` 129 | 130 | **2) Layout Information Extraction** 131 | ![ppstructure](https://user-images.githubusercontent.com/91237924/213063872-81380100-227e-469a-a7bd-5becb9c14220.GIF) 132 | -------------------------------------------------------------------------------- /data/layout_publaynet_dict.txt: -------------------------------------------------------------------------------- 1 | text 2 | title 3 | list 4 | table 5 | figure -------------------------------------------------------------------------------- /data/ocr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvino-dev-samples/PaddleOCR_OpenVINO_CPP/ce03e959f333b78abbd6e6eb62345b28bfc09a44/data/ocr.jpg -------------------------------------------------------------------------------- /data/ppocr_keys_v1.txt: -------------------------------------------------------------------------------- 1 | ' 2 | 疗 3 | 绚 4 | 诚 5 | 娇 6 | 溜 7 | 题 8 | 贿 9 | 者 10 | 廖 11 | 更 12 | 纳 13 | 加 14 | 奉 15 | 公 16 | 一 17 | 就 18 | 汴 19 | 计 20 | 与 21 | 路 22 | 房 23 | 原 24 | 妇 25 | 2 26 | 0 27 | 8 28 | - 29 | 7 30 | 其 31 | > 32 | : 33 | ] 34 | , 35 | , 36 | 骑 37 | 刈 38 | 全 39 | 消 40 | 昏 41 | 傈 42 | 安 43 | 久 44 | 钟 45 | 嗅 46 | 不 47 | 影 48 | 处 49 | 驽 50 | 蜿 51 | 资 52 | 关 53 | 椤 54 | 地 55 | 瘸 56 | 专 57 | 问 58 | 忖 59 | 票 60 | 嫉 61 | 炎 62 | 韵 63 | 要 64 | 月 65 | 田 66 | 节 67 | 陂 68 | 鄙 69 | 捌 70 | 备 71 | 拳 72 | 伺 73 | 眼 74 | 网 75 | 盎 76 | 大 77 | 傍 78 | 心 79 | 东 80 | 愉 81 | 汇 82 | 蹿 83 | 科 84 | 每 85 | 业 86 | 里 87 | 航 88 | 晏 89 | 字 90 | 平 91 | 录 92 | 先 93 | 1 94 | 3 95 | 彤 96 | 鲶 97 | 产 98 | 稍 99 | 督 100 | 腴 101 | 有 102 | 象 103 | 岳 104 | 注 105 | 绍 106 | 在 107 | 泺 108 | 文 109 | 定 110 | 核 111 | 名 112 | 水 113 | 过 114 | 理 115 | 让 116 | 偷 117 | 率 118 | 等 119 | 这 120 | 发 121 | ” 122 | 为 123 | 含 124 | 肥 125 | 酉 126 | 相 127 | 鄱 128 | 七 129 | 编 130 | 猥 131 | 锛 132 | 日 133 | 镀 134 | 蒂 135 | 掰 136 | 倒 137 | 辆 138 | 栾 139 | 栗 140 | 综 141 | 涩 142 | 州 143 | 雌 144 | 滑 145 | 馀 146 | 了 147 | 机 148 | 块 149 | 司 150 | 宰 151 | 甙 152 | 兴 153 | 矽 154 | 抚 155 | 保 156 | 用 157 | 沧 158 | 秩 159 | 如 160 | 收 161 | 息 162 | 滥 163 | 页 164 | 疑 165 | 埠 166 | ! 167 | ! 168 | 姥 169 | 异 170 | 橹 171 | 钇 172 | 向 173 | 下 174 | 跄 175 | 的 176 | 椴 177 | 沫 178 | 国 179 | 绥 180 | 獠 181 | 报 182 | 开 183 | 民 184 | 蜇 185 | 何 186 | 分 187 | 凇 188 | 长 189 | 讥 190 | 藏 191 | 掏 192 | 施 193 | 羽 194 | 中 195 | 讲 196 | 派 197 | 嘟 198 | 人 199 | 提 200 | 浼 201 | 间 202 | 世 203 | 而 204 | 古 205 | 多 206 | 倪 207 | 唇 208 | 饯 209 | 控 210 | 庚 211 | 首 212 | 赛 213 | 蜓 214 | 味 215 | 断 216 | 制 217 | 觉 218 | 技 219 | 替 220 | 艰 221 | 溢 222 | 潮 223 | 夕 224 | 钺 225 | 外 226 | 摘 227 | 枋 228 | 动 229 | 双 230 | 单 231 | 啮 232 | 户 233 | 枇 234 | 确 235 | 锦 236 | 曜 237 | 杜 238 | 或 239 | 能 240 | 效 241 | 霜 242 | 盒 243 | 然 244 | 侗 245 | 电 246 | 晁 247 | 放 248 | 步 249 | 鹃 250 | 新 251 | 杖 252 | 蜂 253 | 吒 254 | 濂 255 | 瞬 256 | 评 257 | 总 258 | 隍 259 | 对 260 | 独 261 | 合 262 | 也 263 | 是 264 | 府 265 | 青 266 | 天 267 | 诲 268 | 墙 269 | 组 270 | 滴 271 | 级 272 | 邀 273 | 帘 274 | 示 275 | 已 276 | 时 277 | 骸 278 | 仄 279 | 泅 280 | 和 281 | 遨 282 | 店 283 | 雇 284 | 疫 285 | 持 286 | 巍 287 | 踮 288 | 境 289 | 只 290 | 亨 291 | 目 292 | 鉴 293 | 崤 294 | 闲 295 | 体 296 | 泄 297 | 杂 298 | 作 299 | 般 300 | 轰 301 | 化 302 | 解 303 | 迂 304 | 诿 305 | 蛭 306 | 璀 307 | 腾 308 | 告 309 | 版 310 | 服 311 | 省 312 | 师 313 | 小 314 | 规 315 | 程 316 | 线 317 | 海 318 | 办 319 | 引 320 | 二 321 | 桧 322 | 牌 323 | 砺 324 | 洄 325 | 裴 326 | 修 327 | 图 328 | 痫 329 | 胡 330 | 许 331 | 犊 332 | 事 333 | 郛 334 | 基 335 | 柴 336 | 呼 337 | 食 338 | 研 339 | 奶 340 | 律 341 | 蛋 342 | 因 343 | 葆 344 | 察 345 | 戏 346 | 褒 347 | 戒 348 | 再 349 | 李 350 | 骁 351 | 工 352 | 貂 353 | 油 354 | 鹅 355 | 章 356 | 啄 357 | 休 358 | 场 359 | 给 360 | 睡 361 | 纷 362 | 豆 363 | 器 364 | 捎 365 | 说 366 | 敏 367 | 学 368 | 会 369 | 浒 370 | 设 371 | 诊 372 | 格 373 | 廓 374 | 查 375 | 来 376 | 霓 377 | 室 378 | 溆 379 | ¢ 380 | 诡 381 | 寥 382 | 焕 383 | 舜 384 | 柒 385 | 狐 386 | 回 387 | 戟 388 | 砾 389 | 厄 390 | 实 391 | 翩 392 | 尿 393 | 五 394 | 入 395 | 径 396 | 惭 397 | 喹 398 | 股 399 | 宇 400 | 篝 401 | | 402 | ; 403 | 美 404 | 期 405 | 云 406 | 九 407 | 祺 408 | 扮 409 | 靠 410 | 锝 411 | 槌 412 | 系 413 | 企 414 | 酰 415 | 阊 416 | 暂 417 | 蚕 418 | 忻 419 | 豁 420 | 本 421 | 羹 422 | 执 423 | 条 424 | 钦 425 | H 426 | 獒 427 | 限 428 | 进 429 | 季 430 | 楦 431 | 于 432 | 芘 433 | 玖 434 | 铋 435 | 茯 436 | 未 437 | 答 438 | 粘 439 | 括 440 | 样 441 | 精 442 | 欠 443 | 矢 444 | 甥 445 | 帷 446 | 嵩 447 | 扣 448 | 令 449 | 仔 450 | 风 451 | 皈 452 | 行 453 | 支 454 | 部 455 | 蓉 456 | 刮 457 | 站 458 | 蜡 459 | 救 460 | 钊 461 | 汗 462 | 松 463 | 嫌 464 | 成 465 | 可 466 | . 467 | 鹤 468 | 院 469 | 从 470 | 交 471 | 政 472 | 怕 473 | 活 474 | 调 475 | 球 476 | 局 477 | 验 478 | 髌 479 | 第 480 | 韫 481 | 谗 482 | 串 483 | 到 484 | 圆 485 | 年 486 | 米 487 | / 488 | * 489 | 友 490 | 忿 491 | 检 492 | 区 493 | 看 494 | 自 495 | 敢 496 | 刃 497 | 个 498 | 兹 499 | 弄 500 | 流 501 | 留 502 | 同 503 | 没 504 | 齿 505 | 星 506 | 聆 507 | 轼 508 | 湖 509 | 什 510 | 三 511 | 建 512 | 蛔 513 | 儿 514 | 椋 515 | 汕 516 | 震 517 | 颧 518 | 鲤 519 | 跟 520 | 力 521 | 情 522 | 璺 523 | 铨 524 | 陪 525 | 务 526 | 指 527 | 族 528 | 训 529 | 滦 530 | 鄣 531 | 濮 532 | 扒 533 | 商 534 | 箱 535 | 十 536 | 召 537 | 慷 538 | 辗 539 | 所 540 | 莞 541 | 管 542 | 护 543 | 臭 544 | 横 545 | 硒 546 | 嗓 547 | 接 548 | 侦 549 | 六 550 | 露 551 | 党 552 | 馋 553 | 驾 554 | 剖 555 | 高 556 | 侬 557 | 妪 558 | 幂 559 | 猗 560 | 绺 561 | 骐 562 | 央 563 | 酐 564 | 孝 565 | 筝 566 | 课 567 | 徇 568 | 缰 569 | 门 570 | 男 571 | 西 572 | 项 573 | 句 574 | 谙 575 | 瞒 576 | 秃 577 | 篇 578 | 教 579 | 碲 580 | 罚 581 | 声 582 | 呐 583 | 景 584 | 前 585 | 富 586 | 嘴 587 | 鳌 588 | 稀 589 | 免 590 | 朋 591 | 啬 592 | 睐 593 | 去 594 | 赈 595 | 鱼 596 | 住 597 | 肩 598 | 愕 599 | 速 600 | 旁 601 | 波 602 | 厅 603 | 健 604 | 茼 605 | 厥 606 | 鲟 607 | 谅 608 | 投 609 | 攸 610 | 炔 611 | 数 612 | 方 613 | 击 614 | 呋 615 | 谈 616 | 绩 617 | 别 618 | 愫 619 | 僚 620 | 躬 621 | 鹧 622 | 胪 623 | 炳 624 | 招 625 | 喇 626 | 膨 627 | 泵 628 | 蹦 629 | 毛 630 | 结 631 | 5 632 | 4 633 | 谱 634 | 识 635 | 陕 636 | 粽 637 | 婚 638 | 拟 639 | 构 640 | 且 641 | 搜 642 | 任 643 | 潘 644 | 比 645 | 郢 646 | 妨 647 | 醪 648 | 陀 649 | 桔 650 | 碘 651 | 扎 652 | 选 653 | 哈 654 | 骷 655 | 楷 656 | 亿 657 | 明 658 | 缆 659 | 脯 660 | 监 661 | 睫 662 | 逻 663 | 婵 664 | 共 665 | 赴 666 | 淝 667 | 凡 668 | 惦 669 | 及 670 | 达 671 | 揖 672 | 谩 673 | 澹 674 | 减 675 | 焰 676 | 蛹 677 | 番 678 | 祁 679 | 柏 680 | 员 681 | 禄 682 | 怡 683 | 峤 684 | 龙 685 | 白 686 | 叽 687 | 生 688 | 闯 689 | 起 690 | 细 691 | 装 692 | 谕 693 | 竟 694 | 聚 695 | 钙 696 | 上 697 | 导 698 | 渊 699 | 按 700 | 艾 701 | 辘 702 | 挡 703 | 耒 704 | 盹 705 | 饪 706 | 臀 707 | 记 708 | 邮 709 | 蕙 710 | 受 711 | 各 712 | 医 713 | 搂 714 | 普 715 | 滇 716 | 朗 717 | 茸 718 | 带 719 | 翻 720 | 酚 721 | ( 722 | 光 723 | 堤 724 | 墟 725 | 蔷 726 | 万 727 | 幻 728 | 〓 729 | 瑙 730 | 辈 731 | 昧 732 | 盏 733 | 亘 734 | 蛀 735 | 吉 736 | 铰 737 | 请 738 | 子 739 | 假 740 | 闻 741 | 税 742 | 井 743 | 诩 744 | 哨 745 | 嫂 746 | 好 747 | 面 748 | 琐 749 | 校 750 | 馊 751 | 鬣 752 | 缂 753 | 营 754 | 访 755 | 炖 756 | 占 757 | 农 758 | 缀 759 | 否 760 | 经 761 | 钚 762 | 棵 763 | 趟 764 | 张 765 | 亟 766 | 吏 767 | 茶 768 | 谨 769 | 捻 770 | 论 771 | 迸 772 | 堂 773 | 玉 774 | 信 775 | 吧 776 | 瞠 777 | 乡 778 | 姬 779 | 寺 780 | 咬 781 | 溏 782 | 苄 783 | 皿 784 | 意 785 | 赉 786 | 宝 787 | 尔 788 | 钰 789 | 艺 790 | 特 791 | 唳 792 | 踉 793 | 都 794 | 荣 795 | 倚 796 | 登 797 | 荐 798 | 丧 799 | 奇 800 | 涵 801 | 批 802 | 炭 803 | 近 804 | 符 805 | 傩 806 | 感 807 | 道 808 | 着 809 | 菊 810 | 虹 811 | 仲 812 | 众 813 | 懈 814 | 濯 815 | 颞 816 | 眺 817 | 南 818 | 释 819 | 北 820 | 缝 821 | 标 822 | 既 823 | 茗 824 | 整 825 | 撼 826 | 迤 827 | 贲 828 | 挎 829 | 耱 830 | 拒 831 | 某 832 | 妍 833 | 卫 834 | 哇 835 | 英 836 | 矶 837 | 藩 838 | 治 839 | 他 840 | 元 841 | 领 842 | 膜 843 | 遮 844 | 穗 845 | 蛾 846 | 飞 847 | 荒 848 | 棺 849 | 劫 850 | 么 851 | 市 852 | 火 853 | 温 854 | 拈 855 | 棚 856 | 洼 857 | 转 858 | 果 859 | 奕 860 | 卸 861 | 迪 862 | 伸 863 | 泳 864 | 斗 865 | 邡 866 | 侄 867 | 涨 868 | 屯 869 | 萋 870 | 胭 871 | 氡 872 | 崮 873 | 枞 874 | 惧 875 | 冒 876 | 彩 877 | 斜 878 | 手 879 | 豚 880 | 随 881 | 旭 882 | 淑 883 | 妞 884 | 形 885 | 菌 886 | 吲 887 | 沱 888 | 争 889 | 驯 890 | 歹 891 | 挟 892 | 兆 893 | 柱 894 | 传 895 | 至 896 | 包 897 | 内 898 | 响 899 | 临 900 | 红 901 | 功 902 | 弩 903 | 衡 904 | 寂 905 | 禁 906 | 老 907 | 棍 908 | 耆 909 | 渍 910 | 织 911 | 害 912 | 氵 913 | 渑 914 | 布 915 | 载 916 | 靥 917 | 嗬 918 | 虽 919 | 苹 920 | 咨 921 | 娄 922 | 库 923 | 雉 924 | 榜 925 | 帜 926 | 嘲 927 | 套 928 | 瑚 929 | 亲 930 | 簸 931 | 欧 932 | 边 933 | 6 934 | 腿 935 | 旮 936 | 抛 937 | 吹 938 | 瞳 939 | 得 940 | 镓 941 | 梗 942 | 厨 943 | 继 944 | 漾 945 | 愣 946 | 憨 947 | 士 948 | 策 949 | 窑 950 | 抑 951 | 躯 952 | 襟 953 | 脏 954 | 参 955 | 贸 956 | 言 957 | 干 958 | 绸 959 | 鳄 960 | 穷 961 | 藜 962 | 音 963 | 折 964 | 详 965 | ) 966 | 举 967 | 悍 968 | 甸 969 | 癌 970 | 黎 971 | 谴 972 | 死 973 | 罩 974 | 迁 975 | 寒 976 | 驷 977 | 袖 978 | 媒 979 | 蒋 980 | 掘 981 | 模 982 | 纠 983 | 恣 984 | 观 985 | 祖 986 | 蛆 987 | 碍 988 | 位 989 | 稿 990 | 主 991 | 澧 992 | 跌 993 | 筏 994 | 京 995 | 锏 996 | 帝 997 | 贴 998 | 证 999 | 糠 1000 | 才 1001 | 黄 1002 | 鲸 1003 | 略 1004 | 炯 1005 | 饱 1006 | 四 1007 | 出 1008 | 园 1009 | 犀 1010 | 牧 1011 | 容 1012 | 汉 1013 | 杆 1014 | 浈 1015 | 汰 1016 | 瑷 1017 | 造 1018 | 虫 1019 | 瘩 1020 | 怪 1021 | 驴 1022 | 济 1023 | 应 1024 | 花 1025 | 沣 1026 | 谔 1027 | 夙 1028 | 旅 1029 | 价 1030 | 矿 1031 | 以 1032 | 考 1033 | s 1034 | u 1035 | 呦 1036 | 晒 1037 | 巡 1038 | 茅 1039 | 准 1040 | 肟 1041 | 瓴 1042 | 詹 1043 | 仟 1044 | 褂 1045 | 译 1046 | 桌 1047 | 混 1048 | 宁 1049 | 怦 1050 | 郑 1051 | 抿 1052 | 些 1053 | 余 1054 | 鄂 1055 | 饴 1056 | 攒 1057 | 珑 1058 | 群 1059 | 阖 1060 | 岔 1061 | 琨 1062 | 藓 1063 | 预 1064 | 环 1065 | 洮 1066 | 岌 1067 | 宀 1068 | 杲 1069 | 瀵 1070 | 最 1071 | 常 1072 | 囡 1073 | 周 1074 | 踊 1075 | 女 1076 | 鼓 1077 | 袭 1078 | 喉 1079 | 简 1080 | 范 1081 | 薯 1082 | 遐 1083 | 疏 1084 | 粱 1085 | 黜 1086 | 禧 1087 | 法 1088 | 箔 1089 | 斤 1090 | 遥 1091 | 汝 1092 | 奥 1093 | 直 1094 | 贞 1095 | 撑 1096 | 置 1097 | 绱 1098 | 集 1099 | 她 1100 | 馅 1101 | 逗 1102 | 钧 1103 | 橱 1104 | 魉 1105 | [ 1106 | 恙 1107 | 躁 1108 | 唤 1109 | 9 1110 | 旺 1111 | 膘 1112 | 待 1113 | 脾 1114 | 惫 1115 | 购 1116 | 吗 1117 | 依 1118 | 盲 1119 | 度 1120 | 瘿 1121 | 蠖 1122 | 俾 1123 | 之 1124 | 镗 1125 | 拇 1126 | 鲵 1127 | 厝 1128 | 簧 1129 | 续 1130 | 款 1131 | 展 1132 | 啃 1133 | 表 1134 | 剔 1135 | 品 1136 | 钻 1137 | 腭 1138 | 损 1139 | 清 1140 | 锶 1141 | 统 1142 | 涌 1143 | 寸 1144 | 滨 1145 | 贪 1146 | 链 1147 | 吠 1148 | 冈 1149 | 伎 1150 | 迥 1151 | 咏 1152 | 吁 1153 | 览 1154 | 防 1155 | 迅 1156 | 失 1157 | 汾 1158 | 阔 1159 | 逵 1160 | 绀 1161 | 蔑 1162 | 列 1163 | 川 1164 | 凭 1165 | 努 1166 | 熨 1167 | 揪 1168 | 利 1169 | 俱 1170 | 绉 1171 | 抢 1172 | 鸨 1173 | 我 1174 | 即 1175 | 责 1176 | 膦 1177 | 易 1178 | 毓 1179 | 鹊 1180 | 刹 1181 | 玷 1182 | 岿 1183 | 空 1184 | 嘞 1185 | 绊 1186 | 排 1187 | 术 1188 | 估 1189 | 锷 1190 | 违 1191 | 们 1192 | 苟 1193 | 铜 1194 | 播 1195 | 肘 1196 | 件 1197 | 烫 1198 | 审 1199 | 鲂 1200 | 广 1201 | 像 1202 | 铌 1203 | 惰 1204 | 铟 1205 | 巳 1206 | 胍 1207 | 鲍 1208 | 康 1209 | 憧 1210 | 色 1211 | 恢 1212 | 想 1213 | 拷 1214 | 尤 1215 | 疳 1216 | 知 1217 | S 1218 | Y 1219 | F 1220 | D 1221 | A 1222 | 峄 1223 | 裕 1224 | 帮 1225 | 握 1226 | 搔 1227 | 氐 1228 | 氘 1229 | 难 1230 | 墒 1231 | 沮 1232 | 雨 1233 | 叁 1234 | 缥 1235 | 悴 1236 | 藐 1237 | 湫 1238 | 娟 1239 | 苑 1240 | 稠 1241 | 颛 1242 | 簇 1243 | 后 1244 | 阕 1245 | 闭 1246 | 蕤 1247 | 缚 1248 | 怎 1249 | 佞 1250 | 码 1251 | 嘤 1252 | 蔡 1253 | 痊 1254 | 舱 1255 | 螯 1256 | 帕 1257 | 赫 1258 | 昵 1259 | 升 1260 | 烬 1261 | 岫 1262 | 、 1263 | 疵 1264 | 蜻 1265 | 髁 1266 | 蕨 1267 | 隶 1268 | 烛 1269 | 械 1270 | 丑 1271 | 盂 1272 | 梁 1273 | 强 1274 | 鲛 1275 | 由 1276 | 拘 1277 | 揉 1278 | 劭 1279 | 龟 1280 | 撤 1281 | 钩 1282 | 呕 1283 | 孛 1284 | 费 1285 | 妻 1286 | 漂 1287 | 求 1288 | 阑 1289 | 崖 1290 | 秤 1291 | 甘 1292 | 通 1293 | 深 1294 | 补 1295 | 赃 1296 | 坎 1297 | 床 1298 | 啪 1299 | 承 1300 | 吼 1301 | 量 1302 | 暇 1303 | 钼 1304 | 烨 1305 | 阂 1306 | 擎 1307 | 脱 1308 | 逮 1309 | 称 1310 | P 1311 | 神 1312 | 属 1313 | 矗 1314 | 华 1315 | 届 1316 | 狍 1317 | 葑 1318 | 汹 1319 | 育 1320 | 患 1321 | 窒 1322 | 蛰 1323 | 佼 1324 | 静 1325 | 槎 1326 | 运 1327 | 鳗 1328 | 庆 1329 | 逝 1330 | 曼 1331 | 疱 1332 | 克 1333 | 代 1334 | 官 1335 | 此 1336 | 麸 1337 | 耧 1338 | 蚌 1339 | 晟 1340 | 例 1341 | 础 1342 | 榛 1343 | 副 1344 | 测 1345 | 唰 1346 | 缢 1347 | 迹 1348 | 灬 1349 | 霁 1350 | 身 1351 | 岁 1352 | 赭 1353 | 扛 1354 | 又 1355 | 菡 1356 | 乜 1357 | 雾 1358 | 板 1359 | 读 1360 | 陷 1361 | 徉 1362 | 贯 1363 | 郁 1364 | 虑 1365 | 变 1366 | 钓 1367 | 菜 1368 | 圾 1369 | 现 1370 | 琢 1371 | 式 1372 | 乐 1373 | 维 1374 | 渔 1375 | 浜 1376 | 左 1377 | 吾 1378 | 脑 1379 | 钡 1380 | 警 1381 | T 1382 | 啵 1383 | 拴 1384 | 偌 1385 | 漱 1386 | 湿 1387 | 硕 1388 | 止 1389 | 骼 1390 | 魄 1391 | 积 1392 | 燥 1393 | 联 1394 | 踢 1395 | 玛 1396 | 则 1397 | 窿 1398 | 见 1399 | 振 1400 | 畿 1401 | 送 1402 | 班 1403 | 钽 1404 | 您 1405 | 赵 1406 | 刨 1407 | 印 1408 | 讨 1409 | 踝 1410 | 籍 1411 | 谡 1412 | 舌 1413 | 崧 1414 | 汽 1415 | 蔽 1416 | 沪 1417 | 酥 1418 | 绒 1419 | 怖 1420 | 财 1421 | 帖 1422 | 肱 1423 | 私 1424 | 莎 1425 | 勋 1426 | 羔 1427 | 霸 1428 | 励 1429 | 哼 1430 | 帐 1431 | 将 1432 | 帅 1433 | 渠 1434 | 纪 1435 | 婴 1436 | 娩 1437 | 岭 1438 | 厘 1439 | 滕 1440 | 吻 1441 | 伤 1442 | 坝 1443 | 冠 1444 | 戊 1445 | 隆 1446 | 瘁 1447 | 介 1448 | 涧 1449 | 物 1450 | 黍 1451 | 并 1452 | 姗 1453 | 奢 1454 | 蹑 1455 | 掣 1456 | 垸 1457 | 锴 1458 | 命 1459 | 箍 1460 | 捉 1461 | 病 1462 | 辖 1463 | 琰 1464 | 眭 1465 | 迩 1466 | 艘 1467 | 绌 1468 | 繁 1469 | 寅 1470 | 若 1471 | 毋 1472 | 思 1473 | 诉 1474 | 类 1475 | 诈 1476 | 燮 1477 | 轲 1478 | 酮 1479 | 狂 1480 | 重 1481 | 反 1482 | 职 1483 | 筱 1484 | 县 1485 | 委 1486 | 磕 1487 | 绣 1488 | 奖 1489 | 晋 1490 | 濉 1491 | 志 1492 | 徽 1493 | 肠 1494 | 呈 1495 | 獐 1496 | 坻 1497 | 口 1498 | 片 1499 | 碰 1500 | 几 1501 | 村 1502 | 柿 1503 | 劳 1504 | 料 1505 | 获 1506 | 亩 1507 | 惕 1508 | 晕 1509 | 厌 1510 | 号 1511 | 罢 1512 | 池 1513 | 正 1514 | 鏖 1515 | 煨 1516 | 家 1517 | 棕 1518 | 复 1519 | 尝 1520 | 懋 1521 | 蜥 1522 | 锅 1523 | 岛 1524 | 扰 1525 | 队 1526 | 坠 1527 | 瘾 1528 | 钬 1529 | @ 1530 | 卧 1531 | 疣 1532 | 镇 1533 | 譬 1534 | 冰 1535 | 彷 1536 | 频 1537 | 黯 1538 | 据 1539 | 垄 1540 | 采 1541 | 八 1542 | 缪 1543 | 瘫 1544 | 型 1545 | 熹 1546 | 砰 1547 | 楠 1548 | 襁 1549 | 箐 1550 | 但 1551 | 嘶 1552 | 绳 1553 | 啤 1554 | 拍 1555 | 盥 1556 | 穆 1557 | 傲 1558 | 洗 1559 | 盯 1560 | 塘 1561 | 怔 1562 | 筛 1563 | 丿 1564 | 台 1565 | 恒 1566 | 喂 1567 | 葛 1568 | 永 1569 | ¥ 1570 | 烟 1571 | 酒 1572 | 桦 1573 | 书 1574 | 砂 1575 | 蚝 1576 | 缉 1577 | 态 1578 | 瀚 1579 | 袄 1580 | 圳 1581 | 轻 1582 | 蛛 1583 | 超 1584 | 榧 1585 | 遛 1586 | 姒 1587 | 奘 1588 | 铮 1589 | 右 1590 | 荽 1591 | 望 1592 | 偻 1593 | 卡 1594 | 丶 1595 | 氰 1596 | 附 1597 | 做 1598 | 革 1599 | 索 1600 | 戚 1601 | 坨 1602 | 桷 1603 | 唁 1604 | 垅 1605 | 榻 1606 | 岐 1607 | 偎 1608 | 坛 1609 | 莨 1610 | 山 1611 | 殊 1612 | 微 1613 | 骇 1614 | 陈 1615 | 爨 1616 | 推 1617 | 嗝 1618 | 驹 1619 | 澡 1620 | 藁 1621 | 呤 1622 | 卤 1623 | 嘻 1624 | 糅 1625 | 逛 1626 | 侵 1627 | 郓 1628 | 酌 1629 | 德 1630 | 摇 1631 | ※ 1632 | 鬃 1633 | 被 1634 | 慨 1635 | 殡 1636 | 羸 1637 | 昌 1638 | 泡 1639 | 戛 1640 | 鞋 1641 | 河 1642 | 宪 1643 | 沿 1644 | 玲 1645 | 鲨 1646 | 翅 1647 | 哽 1648 | 源 1649 | 铅 1650 | 语 1651 | 照 1652 | 邯 1653 | 址 1654 | 荃 1655 | 佬 1656 | 顺 1657 | 鸳 1658 | 町 1659 | 霭 1660 | 睾 1661 | 瓢 1662 | 夸 1663 | 椁 1664 | 晓 1665 | 酿 1666 | 痈 1667 | 咔 1668 | 侏 1669 | 券 1670 | 噎 1671 | 湍 1672 | 签 1673 | 嚷 1674 | 离 1675 | 午 1676 | 尚 1677 | 社 1678 | 锤 1679 | 背 1680 | 孟 1681 | 使 1682 | 浪 1683 | 缦 1684 | 潍 1685 | 鞅 1686 | 军 1687 | 姹 1688 | 驶 1689 | 笑 1690 | 鳟 1691 | 鲁 1692 | 》 1693 | 孽 1694 | 钜 1695 | 绿 1696 | 洱 1697 | 礴 1698 | 焯 1699 | 椰 1700 | 颖 1701 | 囔 1702 | 乌 1703 | 孔 1704 | 巴 1705 | 互 1706 | 性 1707 | 椽 1708 | 哞 1709 | 聘 1710 | 昨 1711 | 早 1712 | 暮 1713 | 胶 1714 | 炀 1715 | 隧 1716 | 低 1717 | 彗 1718 | 昝 1719 | 铁 1720 | 呓 1721 | 氽 1722 | 藉 1723 | 喔 1724 | 癖 1725 | 瑗 1726 | 姨 1727 | 权 1728 | 胱 1729 | 韦 1730 | 堑 1731 | 蜜 1732 | 酋 1733 | 楝 1734 | 砝 1735 | 毁 1736 | 靓 1737 | 歙 1738 | 锲 1739 | 究 1740 | 屋 1741 | 喳 1742 | 骨 1743 | 辨 1744 | 碑 1745 | 武 1746 | 鸠 1747 | 宫 1748 | 辜 1749 | 烊 1750 | 适 1751 | 坡 1752 | 殃 1753 | 培 1754 | 佩 1755 | 供 1756 | 走 1757 | 蜈 1758 | 迟 1759 | 翼 1760 | 况 1761 | 姣 1762 | 凛 1763 | 浔 1764 | 吃 1765 | 飘 1766 | 债 1767 | 犟 1768 | 金 1769 | 促 1770 | 苛 1771 | 崇 1772 | 坂 1773 | 莳 1774 | 畔 1775 | 绂 1776 | 兵 1777 | 蠕 1778 | 斋 1779 | 根 1780 | 砍 1781 | 亢 1782 | 欢 1783 | 恬 1784 | 崔 1785 | 剁 1786 | 餐 1787 | 榫 1788 | 快 1789 | 扶 1790 | ‖ 1791 | 濒 1792 | 缠 1793 | 鳜 1794 | 当 1795 | 彭 1796 | 驭 1797 | 浦 1798 | 篮 1799 | 昀 1800 | 锆 1801 | 秸 1802 | 钳 1803 | 弋 1804 | 娣 1805 | 瞑 1806 | 夷 1807 | 龛 1808 | 苫 1809 | 拱 1810 | 致 1811 | % 1812 | 嵊 1813 | 障 1814 | 隐 1815 | 弑 1816 | 初 1817 | 娓 1818 | 抉 1819 | 汩 1820 | 累 1821 | 蓖 1822 | " 1823 | 唬 1824 | 助 1825 | 苓 1826 | 昙 1827 | 押 1828 | 毙 1829 | 破 1830 | 城 1831 | 郧 1832 | 逢 1833 | 嚏 1834 | 獭 1835 | 瞻 1836 | 溱 1837 | 婿 1838 | 赊 1839 | 跨 1840 | 恼 1841 | 璧 1842 | 萃 1843 | 姻 1844 | 貉 1845 | 灵 1846 | 炉 1847 | 密 1848 | 氛 1849 | 陶 1850 | 砸 1851 | 谬 1852 | 衔 1853 | 点 1854 | 琛 1855 | 沛 1856 | 枳 1857 | 层 1858 | 岱 1859 | 诺 1860 | 脍 1861 | 榈 1862 | 埂 1863 | 征 1864 | 冷 1865 | 裁 1866 | 打 1867 | 蹴 1868 | 素 1869 | 瘘 1870 | 逞 1871 | 蛐 1872 | 聊 1873 | 激 1874 | 腱 1875 | 萘 1876 | 踵 1877 | 飒 1878 | 蓟 1879 | 吆 1880 | 取 1881 | 咙 1882 | 簋 1883 | 涓 1884 | 矩 1885 | 曝 1886 | 挺 1887 | 揣 1888 | 座 1889 | 你 1890 | 史 1891 | 舵 1892 | 焱 1893 | 尘 1894 | 苏 1895 | 笈 1896 | 脚 1897 | 溉 1898 | 榨 1899 | 诵 1900 | 樊 1901 | 邓 1902 | 焊 1903 | 义 1904 | 庶 1905 | 儋 1906 | 蟋 1907 | 蒲 1908 | 赦 1909 | 呷 1910 | 杞 1911 | 诠 1912 | 豪 1913 | 还 1914 | 试 1915 | 颓 1916 | 茉 1917 | 太 1918 | 除 1919 | 紫 1920 | 逃 1921 | 痴 1922 | 草 1923 | 充 1924 | 鳕 1925 | 珉 1926 | 祗 1927 | 墨 1928 | 渭 1929 | 烩 1930 | 蘸 1931 | 慕 1932 | 璇 1933 | 镶 1934 | 穴 1935 | 嵘 1936 | 恶 1937 | 骂 1938 | 险 1939 | 绋 1940 | 幕 1941 | 碉 1942 | 肺 1943 | 戳 1944 | 刘 1945 | 潞 1946 | 秣 1947 | 纾 1948 | 潜 1949 | 銮 1950 | 洛 1951 | 须 1952 | 罘 1953 | 销 1954 | 瘪 1955 | 汞 1956 | 兮 1957 | 屉 1958 | r 1959 | 林 1960 | 厕 1961 | 质 1962 | 探 1963 | 划 1964 | 狸 1965 | 殚 1966 | 善 1967 | 煊 1968 | 烹 1969 | 〒 1970 | 锈 1971 | 逯 1972 | 宸 1973 | 辍 1974 | 泱 1975 | 柚 1976 | 袍 1977 | 远 1978 | 蹋 1979 | 嶙 1980 | 绝 1981 | 峥 1982 | 娥 1983 | 缍 1984 | 雀 1985 | 徵 1986 | 认 1987 | 镱 1988 | 谷 1989 | = 1990 | 贩 1991 | 勉 1992 | 撩 1993 | 鄯 1994 | 斐 1995 | 洋 1996 | 非 1997 | 祚 1998 | 泾 1999 | 诒 2000 | 饿 2001 | 撬 2002 | 威 2003 | 晷 2004 | 搭 2005 | 芍 2006 | 锥 2007 | 笺 2008 | 蓦 2009 | 候 2010 | 琊 2011 | 档 2012 | 礁 2013 | 沼 2014 | 卵 2015 | 荠 2016 | 忑 2017 | 朝 2018 | 凹 2019 | 瑞 2020 | 头 2021 | 仪 2022 | 弧 2023 | 孵 2024 | 畏 2025 | 铆 2026 | 突 2027 | 衲 2028 | 车 2029 | 浩 2030 | 气 2031 | 茂 2032 | 悖 2033 | 厢 2034 | 枕 2035 | 酝 2036 | 戴 2037 | 湾 2038 | 邹 2039 | 飚 2040 | 攘 2041 | 锂 2042 | 写 2043 | 宵 2044 | 翁 2045 | 岷 2046 | 无 2047 | 喜 2048 | 丈 2049 | 挑 2050 | 嗟 2051 | 绛 2052 | 殉 2053 | 议 2054 | 槽 2055 | 具 2056 | 醇 2057 | 淞 2058 | 笃 2059 | 郴 2060 | 阅 2061 | 饼 2062 | 底 2063 | 壕 2064 | 砚 2065 | 弈 2066 | 询 2067 | 缕 2068 | 庹 2069 | 翟 2070 | 零 2071 | 筷 2072 | 暨 2073 | 舟 2074 | 闺 2075 | 甯 2076 | 撞 2077 | 麂 2078 | 茌 2079 | 蔼 2080 | 很 2081 | 珲 2082 | 捕 2083 | 棠 2084 | 角 2085 | 阉 2086 | 媛 2087 | 娲 2088 | 诽 2089 | 剿 2090 | 尉 2091 | 爵 2092 | 睬 2093 | 韩 2094 | 诰 2095 | 匣 2096 | 危 2097 | 糍 2098 | 镯 2099 | 立 2100 | 浏 2101 | 阳 2102 | 少 2103 | 盆 2104 | 舔 2105 | 擘 2106 | 匪 2107 | 申 2108 | 尬 2109 | 铣 2110 | 旯 2111 | 抖 2112 | 赘 2113 | 瓯 2114 | 居 2115 | ˇ 2116 | 哮 2117 | 游 2118 | 锭 2119 | 茏 2120 | 歌 2121 | 坏 2122 | 甚 2123 | 秒 2124 | 舞 2125 | 沙 2126 | 仗 2127 | 劲 2128 | 潺 2129 | 阿 2130 | 燧 2131 | 郭 2132 | 嗖 2133 | 霏 2134 | 忠 2135 | 材 2136 | 奂 2137 | 耐 2138 | 跺 2139 | 砀 2140 | 输 2141 | 岖 2142 | 媳 2143 | 氟 2144 | 极 2145 | 摆 2146 | 灿 2147 | 今 2148 | 扔 2149 | 腻 2150 | 枝 2151 | 奎 2152 | 药 2153 | 熄 2154 | 吨 2155 | 话 2156 | q 2157 | 额 2158 | 慑 2159 | 嘌 2160 | 协 2161 | 喀 2162 | 壳 2163 | 埭 2164 | 视 2165 | 著 2166 | 於 2167 | 愧 2168 | 陲 2169 | 翌 2170 | 峁 2171 | 颅 2172 | 佛 2173 | 腹 2174 | 聋 2175 | 侯 2176 | 咎 2177 | 叟 2178 | 秀 2179 | 颇 2180 | 存 2181 | 较 2182 | 罪 2183 | 哄 2184 | 岗 2185 | 扫 2186 | 栏 2187 | 钾 2188 | 羌 2189 | 己 2190 | 璨 2191 | 枭 2192 | 霉 2193 | 煌 2194 | 涸 2195 | 衿 2196 | 键 2197 | 镝 2198 | 益 2199 | 岢 2200 | 奏 2201 | 连 2202 | 夯 2203 | 睿 2204 | 冥 2205 | 均 2206 | 糖 2207 | 狞 2208 | 蹊 2209 | 稻 2210 | 爸 2211 | 刿 2212 | 胥 2213 | 煜 2214 | 丽 2215 | 肿 2216 | 璃 2217 | 掸 2218 | 跚 2219 | 灾 2220 | 垂 2221 | 樾 2222 | 濑 2223 | 乎 2224 | 莲 2225 | 窄 2226 | 犹 2227 | 撮 2228 | 战 2229 | 馄 2230 | 软 2231 | 络 2232 | 显 2233 | 鸢 2234 | 胸 2235 | 宾 2236 | 妲 2237 | 恕 2238 | 埔 2239 | 蝌 2240 | 份 2241 | 遇 2242 | 巧 2243 | 瞟 2244 | 粒 2245 | 恰 2246 | 剥 2247 | 桡 2248 | 博 2249 | 讯 2250 | 凯 2251 | 堇 2252 | 阶 2253 | 滤 2254 | 卖 2255 | 斌 2256 | 骚 2257 | 彬 2258 | 兑 2259 | 磺 2260 | 樱 2261 | 舷 2262 | 两 2263 | 娱 2264 | 福 2265 | 仃 2266 | 差 2267 | 找 2268 | 桁 2269 | ÷ 2270 | 净 2271 | 把 2272 | 阴 2273 | 污 2274 | 戬 2275 | 雷 2276 | 碓 2277 | 蕲 2278 | 楚 2279 | 罡 2280 | 焖 2281 | 抽 2282 | 妫 2283 | 咒 2284 | 仑 2285 | 闱 2286 | 尽 2287 | 邑 2288 | 菁 2289 | 爱 2290 | 贷 2291 | 沥 2292 | 鞑 2293 | 牡 2294 | 嗉 2295 | 崴 2296 | 骤 2297 | 塌 2298 | 嗦 2299 | 订 2300 | 拮 2301 | 滓 2302 | 捡 2303 | 锻 2304 | 次 2305 | 坪 2306 | 杩 2307 | 臃 2308 | 箬 2309 | 融 2310 | 珂 2311 | 鹗 2312 | 宗 2313 | 枚 2314 | 降 2315 | 鸬 2316 | 妯 2317 | 阄 2318 | 堰 2319 | 盐 2320 | 毅 2321 | 必 2322 | 杨 2323 | 崃 2324 | 俺 2325 | 甬 2326 | 状 2327 | 莘 2328 | 货 2329 | 耸 2330 | 菱 2331 | 腼 2332 | 铸 2333 | 唏 2334 | 痤 2335 | 孚 2336 | 澳 2337 | 懒 2338 | 溅 2339 | 翘 2340 | 疙 2341 | 杷 2342 | 淼 2343 | 缙 2344 | 骰 2345 | 喊 2346 | 悉 2347 | 砻 2348 | 坷 2349 | 艇 2350 | 赁 2351 | 界 2352 | 谤 2353 | 纣 2354 | 宴 2355 | 晃 2356 | 茹 2357 | 归 2358 | 饭 2359 | 梢 2360 | 铡 2361 | 街 2362 | 抄 2363 | 肼 2364 | 鬟 2365 | 苯 2366 | 颂 2367 | 撷 2368 | 戈 2369 | 炒 2370 | 咆 2371 | 茭 2372 | 瘙 2373 | 负 2374 | 仰 2375 | 客 2376 | 琉 2377 | 铢 2378 | 封 2379 | 卑 2380 | 珥 2381 | 椿 2382 | 镧 2383 | 窨 2384 | 鬲 2385 | 寿 2386 | 御 2387 | 袤 2388 | 铃 2389 | 萎 2390 | 砖 2391 | 餮 2392 | 脒 2393 | 裳 2394 | 肪 2395 | 孕 2396 | 嫣 2397 | 馗 2398 | 嵇 2399 | 恳 2400 | 氯 2401 | 江 2402 | 石 2403 | 褶 2404 | 冢 2405 | 祸 2406 | 阻 2407 | 狈 2408 | 羞 2409 | 银 2410 | 靳 2411 | 透 2412 | 咳 2413 | 叼 2414 | 敷 2415 | 芷 2416 | 啥 2417 | 它 2418 | 瓤 2419 | 兰 2420 | 痘 2421 | 懊 2422 | 逑 2423 | 肌 2424 | 往 2425 | 捺 2426 | 坊 2427 | 甩 2428 | 呻 2429 | 〃 2430 | 沦 2431 | 忘 2432 | 膻 2433 | 祟 2434 | 菅 2435 | 剧 2436 | 崆 2437 | 智 2438 | 坯 2439 | 臧 2440 | 霍 2441 | 墅 2442 | 攻 2443 | 眯 2444 | 倘 2445 | 拢 2446 | 骠 2447 | 铐 2448 | 庭 2449 | 岙 2450 | 瓠 2451 | ′ 2452 | 缺 2453 | 泥 2454 | 迢 2455 | 捶 2456 | ? 2457 | ? 2458 | 郏 2459 | 喙 2460 | 掷 2461 | 沌 2462 | 纯 2463 | 秘 2464 | 种 2465 | 听 2466 | 绘 2467 | 固 2468 | 螨 2469 | 团 2470 | 香 2471 | 盗 2472 | 妒 2473 | 埚 2474 | 蓝 2475 | 拖 2476 | 旱 2477 | 荞 2478 | 铀 2479 | 血 2480 | 遏 2481 | 汲 2482 | 辰 2483 | 叩 2484 | 拽 2485 | 幅 2486 | 硬 2487 | 惶 2488 | 桀 2489 | 漠 2490 | 措 2491 | 泼 2492 | 唑 2493 | 齐 2494 | 肾 2495 | 念 2496 | 酱 2497 | 虚 2498 | 屁 2499 | 耶 2500 | 旗 2501 | 砦 2502 | 闵 2503 | 婉 2504 | 馆 2505 | 拭 2506 | 绅 2507 | 韧 2508 | 忏 2509 | 窝 2510 | 醋 2511 | 葺 2512 | 顾 2513 | 辞 2514 | 倜 2515 | 堆 2516 | 辋 2517 | 逆 2518 | 玟 2519 | 贱 2520 | 疾 2521 | 董 2522 | 惘 2523 | 倌 2524 | 锕 2525 | 淘 2526 | 嘀 2527 | 莽 2528 | 俭 2529 | 笏 2530 | 绑 2531 | 鲷 2532 | 杈 2533 | 择 2534 | 蟀 2535 | 粥 2536 | 嗯 2537 | 驰 2538 | 逾 2539 | 案 2540 | 谪 2541 | 褓 2542 | 胫 2543 | 哩 2544 | 昕 2545 | 颚 2546 | 鲢 2547 | 绠 2548 | 躺 2549 | 鹄 2550 | 崂 2551 | 儒 2552 | 俨 2553 | 丝 2554 | 尕 2555 | 泌 2556 | 啊 2557 | 萸 2558 | 彰 2559 | 幺 2560 | 吟 2561 | 骄 2562 | 苣 2563 | 弦 2564 | 脊 2565 | 瑰 2566 | 〈 2567 | 诛 2568 | 镁 2569 | 析 2570 | 闪 2571 | 剪 2572 | 侧 2573 | 哟 2574 | 框 2575 | 螃 2576 | 守 2577 | 嬗 2578 | 燕 2579 | 狭 2580 | 铈 2581 | 缮 2582 | 概 2583 | 迳 2584 | 痧 2585 | 鲲 2586 | 俯 2587 | 售 2588 | 笼 2589 | 痣 2590 | 扉 2591 | 挖 2592 | 满 2593 | 咋 2594 | 援 2595 | 邱 2596 | 扇 2597 | 歪 2598 | 便 2599 | 玑 2600 | 绦 2601 | 峡 2602 | 蛇 2603 | 叨 2604 | 〖 2605 | 泽 2606 | 胃 2607 | 斓 2608 | 喋 2609 | 怂 2610 | 坟 2611 | 猪 2612 | 该 2613 | 蚬 2614 | 炕 2615 | 弥 2616 | 赞 2617 | 棣 2618 | 晔 2619 | 娠 2620 | 挲 2621 | 狡 2622 | 创 2623 | 疖 2624 | 铕 2625 | 镭 2626 | 稷 2627 | 挫 2628 | 弭 2629 | 啾 2630 | 翔 2631 | 粉 2632 | 履 2633 | 苘 2634 | 哦 2635 | 楼 2636 | 秕 2637 | 铂 2638 | 土 2639 | 锣 2640 | 瘟 2641 | 挣 2642 | 栉 2643 | 习 2644 | 享 2645 | 桢 2646 | 袅 2647 | 磨 2648 | 桂 2649 | 谦 2650 | 延 2651 | 坚 2652 | 蔚 2653 | 噗 2654 | 署 2655 | 谟 2656 | 猬 2657 | 钎 2658 | 恐 2659 | 嬉 2660 | 雒 2661 | 倦 2662 | 衅 2663 | 亏 2664 | 璩 2665 | 睹 2666 | 刻 2667 | 殿 2668 | 王 2669 | 算 2670 | 雕 2671 | 麻 2672 | 丘 2673 | 柯 2674 | 骆 2675 | 丸 2676 | 塍 2677 | 谚 2678 | 添 2679 | 鲈 2680 | 垓 2681 | 桎 2682 | 蚯 2683 | 芥 2684 | 予 2685 | 飕 2686 | 镦 2687 | 谌 2688 | 窗 2689 | 醚 2690 | 菀 2691 | 亮 2692 | 搪 2693 | 莺 2694 | 蒿 2695 | 羁 2696 | 足 2697 | J 2698 | 真 2699 | 轶 2700 | 悬 2701 | 衷 2702 | 靛 2703 | 翊 2704 | 掩 2705 | 哒 2706 | 炅 2707 | 掐 2708 | 冼 2709 | 妮 2710 | l 2711 | 谐 2712 | 稚 2713 | 荆 2714 | 擒 2715 | 犯 2716 | 陵 2717 | 虏 2718 | 浓 2719 | 崽 2720 | 刍 2721 | 陌 2722 | 傻 2723 | 孜 2724 | 千 2725 | 靖 2726 | 演 2727 | 矜 2728 | 钕 2729 | 煽 2730 | 杰 2731 | 酗 2732 | 渗 2733 | 伞 2734 | 栋 2735 | 俗 2736 | 泫 2737 | 戍 2738 | 罕 2739 | 沾 2740 | 疽 2741 | 灏 2742 | 煦 2743 | 芬 2744 | 磴 2745 | 叱 2746 | 阱 2747 | 榉 2748 | 湃 2749 | 蜀 2750 | 叉 2751 | 醒 2752 | 彪 2753 | 租 2754 | 郡 2755 | 篷 2756 | 屎 2757 | 良 2758 | 垢 2759 | 隗 2760 | 弱 2761 | 陨 2762 | 峪 2763 | 砷 2764 | 掴 2765 | 颁 2766 | 胎 2767 | 雯 2768 | 绵 2769 | 贬 2770 | 沐 2771 | 撵 2772 | 隘 2773 | 篙 2774 | 暖 2775 | 曹 2776 | 陡 2777 | 栓 2778 | 填 2779 | 臼 2780 | 彦 2781 | 瓶 2782 | 琪 2783 | 潼 2784 | 哪 2785 | 鸡 2786 | 摩 2787 | 啦 2788 | 俟 2789 | 锋 2790 | 域 2791 | 耻 2792 | 蔫 2793 | 疯 2794 | 纹 2795 | 撇 2796 | 毒 2797 | 绶 2798 | 痛 2799 | 酯 2800 | 忍 2801 | 爪 2802 | 赳 2803 | 歆 2804 | 嘹 2805 | 辕 2806 | 烈 2807 | 册 2808 | 朴 2809 | 钱 2810 | 吮 2811 | 毯 2812 | 癜 2813 | 娃 2814 | 谀 2815 | 邵 2816 | 厮 2817 | 炽 2818 | 璞 2819 | 邃 2820 | 丐 2821 | 追 2822 | 词 2823 | 瓒 2824 | 忆 2825 | 轧 2826 | 芫 2827 | 谯 2828 | 喷 2829 | 弟 2830 | 半 2831 | 冕 2832 | 裙 2833 | 掖 2834 | 墉 2835 | 绮 2836 | 寝 2837 | 苔 2838 | 势 2839 | 顷 2840 | 褥 2841 | 切 2842 | 衮 2843 | 君 2844 | 佳 2845 | 嫒 2846 | 蚩 2847 | 霞 2848 | 佚 2849 | 洙 2850 | 逊 2851 | 镖 2852 | 暹 2853 | 唛 2854 | & 2855 | 殒 2856 | 顶 2857 | 碗 2858 | 獗 2859 | 轭 2860 | 铺 2861 | 蛊 2862 | 废 2863 | 恹 2864 | 汨 2865 | 崩 2866 | 珍 2867 | 那 2868 | 杵 2869 | 曲 2870 | 纺 2871 | 夏 2872 | 薰 2873 | 傀 2874 | 闳 2875 | 淬 2876 | 姘 2877 | 舀 2878 | 拧 2879 | 卷 2880 | 楂 2881 | 恍 2882 | 讪 2883 | 厩 2884 | 寮 2885 | 篪 2886 | 赓 2887 | 乘 2888 | 灭 2889 | 盅 2890 | 鞣 2891 | 沟 2892 | 慎 2893 | 挂 2894 | 饺 2895 | 鼾 2896 | 杳 2897 | 树 2898 | 缨 2899 | 丛 2900 | 絮 2901 | 娌 2902 | 臻 2903 | 嗳 2904 | 篡 2905 | 侩 2906 | 述 2907 | 衰 2908 | 矛 2909 | 圈 2910 | 蚜 2911 | 匕 2912 | 筹 2913 | 匿 2914 | 濞 2915 | 晨 2916 | 叶 2917 | 骋 2918 | 郝 2919 | 挚 2920 | 蚴 2921 | 滞 2922 | 增 2923 | 侍 2924 | 描 2925 | 瓣 2926 | 吖 2927 | 嫦 2928 | 蟒 2929 | 匾 2930 | 圣 2931 | 赌 2932 | 毡 2933 | 癞 2934 | 恺 2935 | 百 2936 | 曳 2937 | 需 2938 | 篓 2939 | 肮 2940 | 庖 2941 | 帏 2942 | 卿 2943 | 驿 2944 | 遗 2945 | 蹬 2946 | 鬓 2947 | 骡 2948 | 歉 2949 | 芎 2950 | 胳 2951 | 屐 2952 | 禽 2953 | 烦 2954 | 晌 2955 | 寄 2956 | 媾 2957 | 狄 2958 | 翡 2959 | 苒 2960 | 船 2961 | 廉 2962 | 终 2963 | 痞 2964 | 殇 2965 | 々 2966 | 畦 2967 | 饶 2968 | 改 2969 | 拆 2970 | 悻 2971 | 萄 2972 | £ 2973 | 瓿 2974 | 乃 2975 | 訾 2976 | 桅 2977 | 匮 2978 | 溧 2979 | 拥 2980 | 纱 2981 | 铍 2982 | 骗 2983 | 蕃 2984 | 龋 2985 | 缬 2986 | 父 2987 | 佐 2988 | 疚 2989 | 栎 2990 | 醍 2991 | 掳 2992 | 蓄 2993 | x 2994 | 惆 2995 | 颜 2996 | 鲆 2997 | 榆 2998 | 〔 2999 | 猎 3000 | 敌 3001 | 暴 3002 | 谥 3003 | 鲫 3004 | 贾 3005 | 罗 3006 | 玻 3007 | 缄 3008 | 扦 3009 | 芪 3010 | 癣 3011 | 落 3012 | 徒 3013 | 臾 3014 | 恿 3015 | 猩 3016 | 托 3017 | 邴 3018 | 肄 3019 | 牵 3020 | 春 3021 | 陛 3022 | 耀 3023 | 刊 3024 | 拓 3025 | 蓓 3026 | 邳 3027 | 堕 3028 | 寇 3029 | 枉 3030 | 淌 3031 | 啡 3032 | 湄 3033 | 兽 3034 | 酷 3035 | 萼 3036 | 碚 3037 | 濠 3038 | 萤 3039 | 夹 3040 | 旬 3041 | 戮 3042 | 梭 3043 | 琥 3044 | 椭 3045 | 昔 3046 | 勺 3047 | 蜊 3048 | 绐 3049 | 晚 3050 | 孺 3051 | 僵 3052 | 宣 3053 | 摄 3054 | 冽 3055 | 旨 3056 | 萌 3057 | 忙 3058 | 蚤 3059 | 眉 3060 | 噼 3061 | 蟑 3062 | 付 3063 | 契 3064 | 瓜 3065 | 悼 3066 | 颡 3067 | 壁 3068 | 曾 3069 | 窕 3070 | 颢 3071 | 澎 3072 | 仿 3073 | 俑 3074 | 浑 3075 | 嵌 3076 | 浣 3077 | 乍 3078 | 碌 3079 | 褪 3080 | 乱 3081 | 蔟 3082 | 隙 3083 | 玩 3084 | 剐 3085 | 葫 3086 | 箫 3087 | 纲 3088 | 围 3089 | 伐 3090 | 决 3091 | 伙 3092 | 漩 3093 | 瑟 3094 | 刑 3095 | 肓 3096 | 镳 3097 | 缓 3098 | 蹭 3099 | 氨 3100 | 皓 3101 | 典 3102 | 畲 3103 | 坍 3104 | 铑 3105 | 檐 3106 | 塑 3107 | 洞 3108 | 倬 3109 | 储 3110 | 胴 3111 | 淳 3112 | 戾 3113 | 吐 3114 | 灼 3115 | 惺 3116 | 妙 3117 | 毕 3118 | 珐 3119 | 缈 3120 | 虱 3121 | 盖 3122 | 羰 3123 | 鸿 3124 | 磅 3125 | 谓 3126 | 髅 3127 | 娴 3128 | 苴 3129 | 唷 3130 | 蚣 3131 | 霹 3132 | 抨 3133 | 贤 3134 | 唠 3135 | 犬 3136 | 誓 3137 | 逍 3138 | 庠 3139 | 逼 3140 | 麓 3141 | 籼 3142 | 釉 3143 | 呜 3144 | 碧 3145 | 秧 3146 | 氩 3147 | 摔 3148 | 霄 3149 | 穸 3150 | 纨 3151 | 辟 3152 | 妈 3153 | 映 3154 | 完 3155 | 牛 3156 | 缴 3157 | 嗷 3158 | 炊 3159 | 恩 3160 | 荔 3161 | 茆 3162 | 掉 3163 | 紊 3164 | 慌 3165 | 莓 3166 | 羟 3167 | 阙 3168 | 萁 3169 | 磐 3170 | 另 3171 | 蕹 3172 | 辱 3173 | 鳐 3174 | 湮 3175 | 吡 3176 | 吩 3177 | 唐 3178 | 睦 3179 | 垠 3180 | 舒 3181 | 圜 3182 | 冗 3183 | 瞿 3184 | 溺 3185 | 芾 3186 | 囱 3187 | 匠 3188 | 僳 3189 | 汐 3190 | 菩 3191 | 饬 3192 | 漓 3193 | 黑 3194 | 霰 3195 | 浸 3196 | 濡 3197 | 窥 3198 | 毂 3199 | 蒡 3200 | 兢 3201 | 驻 3202 | 鹉 3203 | 芮 3204 | 诙 3205 | 迫 3206 | 雳 3207 | 厂 3208 | 忐 3209 | 臆 3210 | 猴 3211 | 鸣 3212 | 蚪 3213 | 栈 3214 | 箕 3215 | 羡 3216 | 渐 3217 | 莆 3218 | 捍 3219 | 眈 3220 | 哓 3221 | 趴 3222 | 蹼 3223 | 埕 3224 | 嚣 3225 | 骛 3226 | 宏 3227 | 淄 3228 | 斑 3229 | 噜 3230 | 严 3231 | 瑛 3232 | 垃 3233 | 椎 3234 | 诱 3235 | 压 3236 | 庾 3237 | 绞 3238 | 焘 3239 | 廿 3240 | 抡 3241 | 迄 3242 | 棘 3243 | 夫 3244 | 纬 3245 | 锹 3246 | 眨 3247 | 瞌 3248 | 侠 3249 | 脐 3250 | 竞 3251 | 瀑 3252 | 孳 3253 | 骧 3254 | 遁 3255 | 姜 3256 | 颦 3257 | 荪 3258 | 滚 3259 | 萦 3260 | 伪 3261 | 逸 3262 | 粳 3263 | 爬 3264 | 锁 3265 | 矣 3266 | 役 3267 | 趣 3268 | 洒 3269 | 颔 3270 | 诏 3271 | 逐 3272 | 奸 3273 | 甭 3274 | 惠 3275 | 攀 3276 | 蹄 3277 | 泛 3278 | 尼 3279 | 拼 3280 | 阮 3281 | 鹰 3282 | 亚 3283 | 颈 3284 | 惑 3285 | 勒 3286 | 〉 3287 | 际 3288 | 肛 3289 | 爷 3290 | 刚 3291 | 钨 3292 | 丰 3293 | 养 3294 | 冶 3295 | 鲽 3296 | 辉 3297 | 蔻 3298 | 画 3299 | 覆 3300 | 皴 3301 | 妊 3302 | 麦 3303 | 返 3304 | 醉 3305 | 皂 3306 | 擀 3307 | 〗 3308 | 酶 3309 | 凑 3310 | 粹 3311 | 悟 3312 | 诀 3313 | 硖 3314 | 港 3315 | 卜 3316 | z 3317 | 杀 3318 | 涕 3319 | ± 3320 | 舍 3321 | 铠 3322 | 抵 3323 | 弛 3324 | 段 3325 | 敝 3326 | 镐 3327 | 奠 3328 | 拂 3329 | 轴 3330 | 跛 3331 | 袱 3332 | e 3333 | t 3334 | 沉 3335 | 菇 3336 | 俎 3337 | 薪 3338 | 峦 3339 | 秭 3340 | 蟹 3341 | 历 3342 | 盟 3343 | 菠 3344 | 寡 3345 | 液 3346 | 肢 3347 | 喻 3348 | 染 3349 | 裱 3350 | 悱 3351 | 抱 3352 | 氙 3353 | 赤 3354 | 捅 3355 | 猛 3356 | 跑 3357 | 氮 3358 | 谣 3359 | 仁 3360 | 尺 3361 | 辊 3362 | 窍 3363 | 烙 3364 | 衍 3365 | 架 3366 | 擦 3367 | 倏 3368 | 璐 3369 | 瑁 3370 | 币 3371 | 楞 3372 | 胖 3373 | 夔 3374 | 趸 3375 | 邛 3376 | 惴 3377 | 饕 3378 | 虔 3379 | 蝎 3380 | § 3381 | 哉 3382 | 贝 3383 | 宽 3384 | 辫 3385 | 炮 3386 | 扩 3387 | 饲 3388 | 籽 3389 | 魏 3390 | 菟 3391 | 锰 3392 | 伍 3393 | 猝 3394 | 末 3395 | 琳 3396 | 哚 3397 | 蛎 3398 | 邂 3399 | 呀 3400 | 姿 3401 | 鄞 3402 | 却 3403 | 歧 3404 | 仙 3405 | 恸 3406 | 椐 3407 | 森 3408 | 牒 3409 | 寤 3410 | 袒 3411 | 婆 3412 | 虢 3413 | 雅 3414 | 钉 3415 | 朵 3416 | 贼 3417 | 欲 3418 | 苞 3419 | 寰 3420 | 故 3421 | 龚 3422 | 坭 3423 | 嘘 3424 | 咫 3425 | 礼 3426 | 硷 3427 | 兀 3428 | 睢 3429 | 汶 3430 | ’ 3431 | 铲 3432 | 烧 3433 | 绕 3434 | 诃 3435 | 浃 3436 | 钿 3437 | 哺 3438 | 柜 3439 | 讼 3440 | 颊 3441 | 璁 3442 | 腔 3443 | 洽 3444 | 咐 3445 | 脲 3446 | 簌 3447 | 筠 3448 | 镣 3449 | 玮 3450 | 鞠 3451 | 谁 3452 | 兼 3453 | 姆 3454 | 挥 3455 | 梯 3456 | 蝴 3457 | 谘 3458 | 漕 3459 | 刷 3460 | 躏 3461 | 宦 3462 | 弼 3463 | b 3464 | 垌 3465 | 劈 3466 | 麟 3467 | 莉 3468 | 揭 3469 | 笙 3470 | 渎 3471 | 仕 3472 | 嗤 3473 | 仓 3474 | 配 3475 | 怏 3476 | 抬 3477 | 错 3478 | 泯 3479 | 镊 3480 | 孰 3481 | 猿 3482 | 邪 3483 | 仍 3484 | 秋 3485 | 鼬 3486 | 壹 3487 | 歇 3488 | 吵 3489 | 炼 3490 | < 3491 | 尧 3492 | 射 3493 | 柬 3494 | 廷 3495 | 胧 3496 | 霾 3497 | 凳 3498 | 隋 3499 | 肚 3500 | 浮 3501 | 梦 3502 | 祥 3503 | 株 3504 | 堵 3505 | 退 3506 | L 3507 | 鹫 3508 | 跎 3509 | 凶 3510 | 毽 3511 | 荟 3512 | 炫 3513 | 栩 3514 | 玳 3515 | 甜 3516 | 沂 3517 | 鹿 3518 | 顽 3519 | 伯 3520 | 爹 3521 | 赔 3522 | 蛴 3523 | 徐 3524 | 匡 3525 | 欣 3526 | 狰 3527 | 缸 3528 | 雹 3529 | 蟆 3530 | 疤 3531 | 默 3532 | 沤 3533 | 啜 3534 | 痂 3535 | 衣 3536 | 禅 3537 | w 3538 | i 3539 | h 3540 | 辽 3541 | 葳 3542 | 黝 3543 | 钗 3544 | 停 3545 | 沽 3546 | 棒 3547 | 馨 3548 | 颌 3549 | 肉 3550 | 吴 3551 | 硫 3552 | 悯 3553 | 劾 3554 | 娈 3555 | 马 3556 | 啧 3557 | 吊 3558 | 悌 3559 | 镑 3560 | 峭 3561 | 帆 3562 | 瀣 3563 | 涉 3564 | 咸 3565 | 疸 3566 | 滋 3567 | 泣 3568 | 翦 3569 | 拙 3570 | 癸 3571 | 钥 3572 | 蜒 3573 | + 3574 | 尾 3575 | 庄 3576 | 凝 3577 | 泉 3578 | 婢 3579 | 渴 3580 | 谊 3581 | 乞 3582 | 陆 3583 | 锉 3584 | 糊 3585 | 鸦 3586 | 淮 3587 | I 3588 | B 3589 | N 3590 | 晦 3591 | 弗 3592 | 乔 3593 | 庥 3594 | 葡 3595 | 尻 3596 | 席 3597 | 橡 3598 | 傣 3599 | 渣 3600 | 拿 3601 | 惩 3602 | 麋 3603 | 斛 3604 | 缃 3605 | 矮 3606 | 蛏 3607 | 岘 3608 | 鸽 3609 | 姐 3610 | 膏 3611 | 催 3612 | 奔 3613 | 镒 3614 | 喱 3615 | 蠡 3616 | 摧 3617 | 钯 3618 | 胤 3619 | 柠 3620 | 拐 3621 | 璋 3622 | 鸥 3623 | 卢 3624 | 荡 3625 | 倾 3626 | ^ 3627 | _ 3628 | 珀 3629 | 逄 3630 | 萧 3631 | 塾 3632 | 掇 3633 | 贮 3634 | 笆 3635 | 聂 3636 | 圃 3637 | 冲 3638 | 嵬 3639 | M 3640 | 滔 3641 | 笕 3642 | 值 3643 | 炙 3644 | 偶 3645 | 蜱 3646 | 搐 3647 | 梆 3648 | 汪 3649 | 蔬 3650 | 腑 3651 | 鸯 3652 | 蹇 3653 | 敞 3654 | 绯 3655 | 仨 3656 | 祯 3657 | 谆 3658 | 梧 3659 | 糗 3660 | 鑫 3661 | 啸 3662 | 豺 3663 | 囹 3664 | 猾 3665 | 巢 3666 | 柄 3667 | 瀛 3668 | 筑 3669 | 踌 3670 | 沭 3671 | 暗 3672 | 苁 3673 | 鱿 3674 | 蹉 3675 | 脂 3676 | 蘖 3677 | 牢 3678 | 热 3679 | 木 3680 | 吸 3681 | 溃 3682 | 宠 3683 | 序 3684 | 泞 3685 | 偿 3686 | 拜 3687 | 檩 3688 | 厚 3689 | 朐 3690 | 毗 3691 | 螳 3692 | 吞 3693 | 媚 3694 | 朽 3695 | 担 3696 | 蝗 3697 | 橘 3698 | 畴 3699 | 祈 3700 | 糟 3701 | 盱 3702 | 隼 3703 | 郜 3704 | 惜 3705 | 珠 3706 | 裨 3707 | 铵 3708 | 焙 3709 | 琚 3710 | 唯 3711 | 咚 3712 | 噪 3713 | 骊 3714 | 丫 3715 | 滢 3716 | 勤 3717 | 棉 3718 | 呸 3719 | 咣 3720 | 淀 3721 | 隔 3722 | 蕾 3723 | 窈 3724 | 饨 3725 | 挨 3726 | 煅 3727 | 短 3728 | 匙 3729 | 粕 3730 | 镜 3731 | 赣 3732 | 撕 3733 | 墩 3734 | 酬 3735 | 馁 3736 | 豌 3737 | 颐 3738 | 抗 3739 | 酣 3740 | 氓 3741 | 佑 3742 | 搁 3743 | 哭 3744 | 递 3745 | 耷 3746 | 涡 3747 | 桃 3748 | 贻 3749 | 碣 3750 | 截 3751 | 瘦 3752 | 昭 3753 | 镌 3754 | 蔓 3755 | 氚 3756 | 甲 3757 | 猕 3758 | 蕴 3759 | 蓬 3760 | 散 3761 | 拾 3762 | 纛 3763 | 狼 3764 | 猷 3765 | 铎 3766 | 埋 3767 | 旖 3768 | 矾 3769 | 讳 3770 | 囊 3771 | 糜 3772 | 迈 3773 | 粟 3774 | 蚂 3775 | 紧 3776 | 鲳 3777 | 瘢 3778 | 栽 3779 | 稼 3780 | 羊 3781 | 锄 3782 | 斟 3783 | 睁 3784 | 桥 3785 | 瓮 3786 | 蹙 3787 | 祉 3788 | 醺 3789 | 鼻 3790 | 昱 3791 | 剃 3792 | 跳 3793 | 篱 3794 | 跷 3795 | 蒜 3796 | 翎 3797 | 宅 3798 | 晖 3799 | 嗑 3800 | 壑 3801 | 峻 3802 | 癫 3803 | 屏 3804 | 狠 3805 | 陋 3806 | 袜 3807 | 途 3808 | 憎 3809 | 祀 3810 | 莹 3811 | 滟 3812 | 佶 3813 | 溥 3814 | 臣 3815 | 约 3816 | 盛 3817 | 峰 3818 | 磁 3819 | 慵 3820 | 婪 3821 | 拦 3822 | 莅 3823 | 朕 3824 | 鹦 3825 | 粲 3826 | 裤 3827 | 哎 3828 | 疡 3829 | 嫖 3830 | 琵 3831 | 窟 3832 | 堪 3833 | 谛 3834 | 嘉 3835 | 儡 3836 | 鳝 3837 | 斩 3838 | 郾 3839 | 驸 3840 | 酊 3841 | 妄 3842 | 胜 3843 | 贺 3844 | 徙 3845 | 傅 3846 | 噌 3847 | 钢 3848 | 栅 3849 | 庇 3850 | 恋 3851 | 匝 3852 | 巯 3853 | 邈 3854 | 尸 3855 | 锚 3856 | 粗 3857 | 佟 3858 | 蛟 3859 | 薹 3860 | 纵 3861 | 蚊 3862 | 郅 3863 | 绢 3864 | 锐 3865 | 苗 3866 | 俞 3867 | 篆 3868 | 淆 3869 | 膀 3870 | 鲜 3871 | 煎 3872 | 诶 3873 | 秽 3874 | 寻 3875 | 涮 3876 | 刺 3877 | 怀 3878 | 噶 3879 | 巨 3880 | 褰 3881 | 魅 3882 | 灶 3883 | 灌 3884 | 桉 3885 | 藕 3886 | 谜 3887 | 舸 3888 | 薄 3889 | 搀 3890 | 恽 3891 | 借 3892 | 牯 3893 | 痉 3894 | 渥 3895 | 愿 3896 | 亓 3897 | 耘 3898 | 杠 3899 | 柩 3900 | 锔 3901 | 蚶 3902 | 钣 3903 | 珈 3904 | 喘 3905 | 蹒 3906 | 幽 3907 | 赐 3908 | 稗 3909 | 晤 3910 | 莱 3911 | 泔 3912 | 扯 3913 | 肯 3914 | 菪 3915 | 裆 3916 | 腩 3917 | 豉 3918 | 疆 3919 | 骜 3920 | 腐 3921 | 倭 3922 | 珏 3923 | 唔 3924 | 粮 3925 | 亡 3926 | 润 3927 | 慰 3928 | 伽 3929 | 橄 3930 | 玄 3931 | 誉 3932 | 醐 3933 | 胆 3934 | 龊 3935 | 粼 3936 | 塬 3937 | 陇 3938 | 彼 3939 | 削 3940 | 嗣 3941 | 绾 3942 | 芽 3943 | 妗 3944 | 垭 3945 | 瘴 3946 | 爽 3947 | 薏 3948 | 寨 3949 | 龈 3950 | 泠 3951 | 弹 3952 | 赢 3953 | 漪 3954 | 猫 3955 | 嘧 3956 | 涂 3957 | 恤 3958 | 圭 3959 | 茧 3960 | 烽 3961 | 屑 3962 | 痕 3963 | 巾 3964 | 赖 3965 | 荸 3966 | 凰 3967 | 腮 3968 | 畈 3969 | 亵 3970 | 蹲 3971 | 偃 3972 | 苇 3973 | 澜 3974 | 艮 3975 | 换 3976 | 骺 3977 | 烘 3978 | 苕 3979 | 梓 3980 | 颉 3981 | 肇 3982 | 哗 3983 | 悄 3984 | 氤 3985 | 涠 3986 | 葬 3987 | 屠 3988 | 鹭 3989 | 植 3990 | 竺 3991 | 佯 3992 | 诣 3993 | 鲇 3994 | 瘀 3995 | 鲅 3996 | 邦 3997 | 移 3998 | 滁 3999 | 冯 4000 | 耕 4001 | 癔 4002 | 戌 4003 | 茬 4004 | 沁 4005 | 巩 4006 | 悠 4007 | 湘 4008 | 洪 4009 | 痹 4010 | 锟 4011 | 循 4012 | 谋 4013 | 腕 4014 | 鳃 4015 | 钠 4016 | 捞 4017 | 焉 4018 | 迎 4019 | 碱 4020 | 伫 4021 | 急 4022 | 榷 4023 | 奈 4024 | 邝 4025 | 卯 4026 | 辄 4027 | 皲 4028 | 卟 4029 | 醛 4030 | 畹 4031 | 忧 4032 | 稳 4033 | 雄 4034 | 昼 4035 | 缩 4036 | 阈 4037 | 睑 4038 | 扌 4039 | 耗 4040 | 曦 4041 | 涅 4042 | 捏 4043 | 瞧 4044 | 邕 4045 | 淖 4046 | 漉 4047 | 铝 4048 | 耦 4049 | 禹 4050 | 湛 4051 | 喽 4052 | 莼 4053 | 琅 4054 | 诸 4055 | 苎 4056 | 纂 4057 | 硅 4058 | 始 4059 | 嗨 4060 | 傥 4061 | 燃 4062 | 臂 4063 | 赅 4064 | 嘈 4065 | 呆 4066 | 贵 4067 | 屹 4068 | 壮 4069 | 肋 4070 | 亍 4071 | 蚀 4072 | 卅 4073 | 豹 4074 | 腆 4075 | 邬 4076 | 迭 4077 | 浊 4078 | } 4079 | 童 4080 | 螂 4081 | 捐 4082 | 圩 4083 | 勐 4084 | 触 4085 | 寞 4086 | 汊 4087 | 壤 4088 | 荫 4089 | 膺 4090 | 渌 4091 | 芳 4092 | 懿 4093 | 遴 4094 | 螈 4095 | 泰 4096 | 蓼 4097 | 蛤 4098 | 茜 4099 | 舅 4100 | 枫 4101 | 朔 4102 | 膝 4103 | 眙 4104 | 避 4105 | 梅 4106 | 判 4107 | 鹜 4108 | 璜 4109 | 牍 4110 | 缅 4111 | 垫 4112 | 藻 4113 | 黔 4114 | 侥 4115 | 惚 4116 | 懂 4117 | 踩 4118 | 腰 4119 | 腈 4120 | 札 4121 | 丞 4122 | 唾 4123 | 慈 4124 | 顿 4125 | 摹 4126 | 荻 4127 | 琬 4128 | ~ 4129 | 斧 4130 | 沈 4131 | 滂 4132 | 胁 4133 | 胀 4134 | 幄 4135 | 莜 4136 | Z 4137 | 匀 4138 | 鄄 4139 | 掌 4140 | 绰 4141 | 茎 4142 | 焚 4143 | 赋 4144 | 萱 4145 | 谑 4146 | 汁 4147 | 铒 4148 | 瞎 4149 | 夺 4150 | 蜗 4151 | 野 4152 | 娆 4153 | 冀 4154 | 弯 4155 | 篁 4156 | 懵 4157 | 灞 4158 | 隽 4159 | 芡 4160 | 脘 4161 | 俐 4162 | 辩 4163 | 芯 4164 | 掺 4165 | 喏 4166 | 膈 4167 | 蝈 4168 | 觐 4169 | 悚 4170 | 踹 4171 | 蔗 4172 | 熠 4173 | 鼠 4174 | 呵 4175 | 抓 4176 | 橼 4177 | 峨 4178 | 畜 4179 | 缔 4180 | 禾 4181 | 崭 4182 | 弃 4183 | 熊 4184 | 摒 4185 | 凸 4186 | 拗 4187 | 穹 4188 | 蒙 4189 | 抒 4190 | 祛 4191 | 劝 4192 | 闫 4193 | 扳 4194 | 阵 4195 | 醌 4196 | 踪 4197 | 喵 4198 | 侣 4199 | 搬 4200 | 仅 4201 | 荧 4202 | 赎 4203 | 蝾 4204 | 琦 4205 | 买 4206 | 婧 4207 | 瞄 4208 | 寓 4209 | 皎 4210 | 冻 4211 | 赝 4212 | 箩 4213 | 莫 4214 | 瞰 4215 | 郊 4216 | 笫 4217 | 姝 4218 | 筒 4219 | 枪 4220 | 遣 4221 | 煸 4222 | 袋 4223 | 舆 4224 | 痱 4225 | 涛 4226 | 母 4227 | 〇 4228 | 启 4229 | 践 4230 | 耙 4231 | 绲 4232 | 盘 4233 | 遂 4234 | 昊 4235 | 搞 4236 | 槿 4237 | 诬 4238 | 纰 4239 | 泓 4240 | 惨 4241 | 檬 4242 | 亻 4243 | 越 4244 | C 4245 | o 4246 | 憩 4247 | 熵 4248 | 祷 4249 | 钒 4250 | 暧 4251 | 塔 4252 | 阗 4253 | 胰 4254 | 咄 4255 | 娶 4256 | 魔 4257 | 琶 4258 | 钞 4259 | 邻 4260 | 扬 4261 | 杉 4262 | 殴 4263 | 咽 4264 | 弓 4265 | 〆 4266 | 髻 4267 | 】 4268 | 吭 4269 | 揽 4270 | 霆 4271 | 拄 4272 | 殖 4273 | 脆 4274 | 彻 4275 | 岩 4276 | 芝 4277 | 勃 4278 | 辣 4279 | 剌 4280 | 钝 4281 | 嘎 4282 | 甄 4283 | 佘 4284 | 皖 4285 | 伦 4286 | 授 4287 | 徕 4288 | 憔 4289 | 挪 4290 | 皇 4291 | 庞 4292 | 稔 4293 | 芜 4294 | 踏 4295 | 溴 4296 | 兖 4297 | 卒 4298 | 擢 4299 | 饥 4300 | 鳞 4301 | 煲 4302 | ‰ 4303 | 账 4304 | 颗 4305 | 叻 4306 | 斯 4307 | 捧 4308 | 鳍 4309 | 琮 4310 | 讹 4311 | 蛙 4312 | 纽 4313 | 谭 4314 | 酸 4315 | 兔 4316 | 莒 4317 | 睇 4318 | 伟 4319 | 觑 4320 | 羲 4321 | 嗜 4322 | 宜 4323 | 褐 4324 | 旎 4325 | 辛 4326 | 卦 4327 | 诘 4328 | 筋 4329 | 鎏 4330 | 溪 4331 | 挛 4332 | 熔 4333 | 阜 4334 | 晰 4335 | 鳅 4336 | 丢 4337 | 奚 4338 | 灸 4339 | 呱 4340 | 献 4341 | 陉 4342 | 黛 4343 | 鸪 4344 | 甾 4345 | 萨 4346 | 疮 4347 | 拯 4348 | 洲 4349 | 疹 4350 | 辑 4351 | 叙 4352 | 恻 4353 | 谒 4354 | 允 4355 | 柔 4356 | 烂 4357 | 氏 4358 | 逅 4359 | 漆 4360 | 拎 4361 | 惋 4362 | 扈 4363 | 湟 4364 | 纭 4365 | 啕 4366 | 掬 4367 | 擞 4368 | 哥 4369 | 忽 4370 | 涤 4371 | 鸵 4372 | 靡 4373 | 郗 4374 | 瓷 4375 | 扁 4376 | 廊 4377 | 怨 4378 | 雏 4379 | 钮 4380 | 敦 4381 | E 4382 | 懦 4383 | 憋 4384 | 汀 4385 | 拚 4386 | 啉 4387 | 腌 4388 | 岸 4389 | f 4390 | 痼 4391 | 瞅 4392 | 尊 4393 | 咀 4394 | 眩 4395 | 飙 4396 | 忌 4397 | 仝 4398 | 迦 4399 | 熬 4400 | 毫 4401 | 胯 4402 | 篑 4403 | 茄 4404 | 腺 4405 | 凄 4406 | 舛 4407 | 碴 4408 | 锵 4409 | 诧 4410 | 羯 4411 | 後 4412 | 漏 4413 | 汤 4414 | 宓 4415 | 仞 4416 | 蚁 4417 | 壶 4418 | 谰 4419 | 皑 4420 | 铄 4421 | 棰 4422 | 罔 4423 | 辅 4424 | 晶 4425 | 苦 4426 | 牟 4427 | 闽 4428 | \ 4429 | 烃 4430 | 饮 4431 | 聿 4432 | 丙 4433 | 蛳 4434 | 朱 4435 | 煤 4436 | 涔 4437 | 鳖 4438 | 犁 4439 | 罐 4440 | 荼 4441 | 砒 4442 | 淦 4443 | 妤 4444 | 黏 4445 | 戎 4446 | 孑 4447 | 婕 4448 | 瑾 4449 | 戢 4450 | 钵 4451 | 枣 4452 | 捋 4453 | 砥 4454 | 衩 4455 | 狙 4456 | 桠 4457 | 稣 4458 | 阎 4459 | 肃 4460 | 梏 4461 | 诫 4462 | 孪 4463 | 昶 4464 | 婊 4465 | 衫 4466 | 嗔 4467 | 侃 4468 | 塞 4469 | 蜃 4470 | 樵 4471 | 峒 4472 | 貌 4473 | 屿 4474 | 欺 4475 | 缫 4476 | 阐 4477 | 栖 4478 | 诟 4479 | 珞 4480 | 荭 4481 | 吝 4482 | 萍 4483 | 嗽 4484 | 恂 4485 | 啻 4486 | 蜴 4487 | 磬 4488 | 峋 4489 | 俸 4490 | 豫 4491 | 谎 4492 | 徊 4493 | 镍 4494 | 韬 4495 | 魇 4496 | 晴 4497 | U 4498 | 囟 4499 | 猜 4500 | 蛮 4501 | 坐 4502 | 囿 4503 | 伴 4504 | 亭 4505 | 肝 4506 | 佗 4507 | 蝠 4508 | 妃 4509 | 胞 4510 | 滩 4511 | 榴 4512 | 氖 4513 | 垩 4514 | 苋 4515 | 砣 4516 | 扪 4517 | 馏 4518 | 姓 4519 | 轩 4520 | 厉 4521 | 夥 4522 | 侈 4523 | 禀 4524 | 垒 4525 | 岑 4526 | 赏 4527 | 钛 4528 | 辐 4529 | 痔 4530 | 披 4531 | 纸 4532 | 碳 4533 | “ 4534 | 坞 4535 | 蠓 4536 | 挤 4537 | 荥 4538 | 沅 4539 | 悔 4540 | 铧 4541 | 帼 4542 | 蒌 4543 | 蝇 4544 | a 4545 | p 4546 | y 4547 | n 4548 | g 4549 | 哀 4550 | 浆 4551 | 瑶 4552 | 凿 4553 | 桶 4554 | 馈 4555 | 皮 4556 | 奴 4557 | 苜 4558 | 佤 4559 | 伶 4560 | 晗 4561 | 铱 4562 | 炬 4563 | 优 4564 | 弊 4565 | 氢 4566 | 恃 4567 | 甫 4568 | 攥 4569 | 端 4570 | 锌 4571 | 灰 4572 | 稹 4573 | 炝 4574 | 曙 4575 | 邋 4576 | 亥 4577 | 眶 4578 | 碾 4579 | 拉 4580 | 萝 4581 | 绔 4582 | 捷 4583 | 浍 4584 | 腋 4585 | 姑 4586 | 菖 4587 | 凌 4588 | 涞 4589 | 麽 4590 | 锢 4591 | 桨 4592 | 潢 4593 | 绎 4594 | 镰 4595 | 殆 4596 | 锑 4597 | 渝 4598 | 铬 4599 | 困 4600 | 绽 4601 | 觎 4602 | 匈 4603 | 糙 4604 | 暑 4605 | 裹 4606 | 鸟 4607 | 盔 4608 | 肽 4609 | 迷 4610 | 綦 4611 | 『 4612 | 亳 4613 | 佝 4614 | 俘 4615 | 钴 4616 | 觇 4617 | 骥 4618 | 仆 4619 | 疝 4620 | 跪 4621 | 婶 4622 | 郯 4623 | 瀹 4624 | 唉 4625 | 脖 4626 | 踞 4627 | 针 4628 | 晾 4629 | 忒 4630 | 扼 4631 | 瞩 4632 | 叛 4633 | 椒 4634 | 疟 4635 | 嗡 4636 | 邗 4637 | 肆 4638 | 跆 4639 | 玫 4640 | 忡 4641 | 捣 4642 | 咧 4643 | 唆 4644 | 艄 4645 | 蘑 4646 | 潦 4647 | 笛 4648 | 阚 4649 | 沸 4650 | 泻 4651 | 掊 4652 | 菽 4653 | 贫 4654 | 斥 4655 | 髂 4656 | 孢 4657 | 镂 4658 | 赂 4659 | 麝 4660 | 鸾 4661 | 屡 4662 | 衬 4663 | 苷 4664 | 恪 4665 | 叠 4666 | 希 4667 | 粤 4668 | 爻 4669 | 喝 4670 | 茫 4671 | 惬 4672 | 郸 4673 | 绻 4674 | 庸 4675 | 撅 4676 | 碟 4677 | 宄 4678 | 妹 4679 | 膛 4680 | 叮 4681 | 饵 4682 | 崛 4683 | 嗲 4684 | 椅 4685 | 冤 4686 | 搅 4687 | 咕 4688 | 敛 4689 | 尹 4690 | 垦 4691 | 闷 4692 | 蝉 4693 | 霎 4694 | 勰 4695 | 败 4696 | 蓑 4697 | 泸 4698 | 肤 4699 | 鹌 4700 | 幌 4701 | 焦 4702 | 浠 4703 | 鞍 4704 | 刁 4705 | 舰 4706 | 乙 4707 | 竿 4708 | 裔 4709 | 。 4710 | 茵 4711 | 函 4712 | 伊 4713 | 兄 4714 | 丨 4715 | 娜 4716 | 匍 4717 | 謇 4718 | 莪 4719 | 宥 4720 | 似 4721 | 蝽 4722 | 翳 4723 | 酪 4724 | 翠 4725 | 粑 4726 | 薇 4727 | 祢 4728 | 骏 4729 | 赠 4730 | 叫 4731 | Q 4732 | 噤 4733 | 噻 4734 | 竖 4735 | 芗 4736 | 莠 4737 | 潭 4738 | 俊 4739 | 羿 4740 | 耜 4741 | O 4742 | 郫 4743 | 趁 4744 | 嗪 4745 | 囚 4746 | 蹶 4747 | 芒 4748 | 洁 4749 | 笋 4750 | 鹑 4751 | 敲 4752 | 硝 4753 | 啶 4754 | 堡 4755 | 渲 4756 | 揩 4757 | 』 4758 | 携 4759 | 宿 4760 | 遒 4761 | 颍 4762 | 扭 4763 | 棱 4764 | 割 4765 | 萜 4766 | 蔸 4767 | 葵 4768 | 琴 4769 | 捂 4770 | 饰 4771 | 衙 4772 | 耿 4773 | 掠 4774 | 募 4775 | 岂 4776 | 窖 4777 | 涟 4778 | 蔺 4779 | 瘤 4780 | 柞 4781 | 瞪 4782 | 怜 4783 | 匹 4784 | 距 4785 | 楔 4786 | 炜 4787 | 哆 4788 | 秦 4789 | 缎 4790 | 幼 4791 | 茁 4792 | 绪 4793 | 痨 4794 | 恨 4795 | 楸 4796 | 娅 4797 | 瓦 4798 | 桩 4799 | 雪 4800 | 嬴 4801 | 伏 4802 | 榔 4803 | 妥 4804 | 铿 4805 | 拌 4806 | 眠 4807 | 雍 4808 | 缇 4809 | ‘ 4810 | 卓 4811 | 搓 4812 | 哌 4813 | 觞 4814 | 噩 4815 | 屈 4816 | 哧 4817 | 髓 4818 | 咦 4819 | 巅 4820 | 娑 4821 | 侑 4822 | 淫 4823 | 膳 4824 | 祝 4825 | 勾 4826 | 姊 4827 | 莴 4828 | 胄 4829 | 疃 4830 | 薛 4831 | 蜷 4832 | 胛 4833 | 巷 4834 | 芙 4835 | 芋 4836 | 熙 4837 | 闰 4838 | 勿 4839 | 窃 4840 | 狱 4841 | 剩 4842 | 钏 4843 | 幢 4844 | 陟 4845 | 铛 4846 | 慧 4847 | 靴 4848 | 耍 4849 | k 4850 | 浙 4851 | 浇 4852 | 飨 4853 | 惟 4854 | 绗 4855 | 祜 4856 | 澈 4857 | 啼 4858 | 咪 4859 | 磷 4860 | 摞 4861 | 诅 4862 | 郦 4863 | 抹 4864 | 跃 4865 | 壬 4866 | 吕 4867 | 肖 4868 | 琏 4869 | 颤 4870 | 尴 4871 | 剡 4872 | 抠 4873 | 凋 4874 | 赚 4875 | 泊 4876 | 津 4877 | 宕 4878 | 殷 4879 | 倔 4880 | 氲 4881 | 漫 4882 | 邺 4883 | 涎 4884 | 怠 4885 | $ 4886 | 垮 4887 | 荬 4888 | 遵 4889 | 俏 4890 | 叹 4891 | 噢 4892 | 饽 4893 | 蜘 4894 | 孙 4895 | 筵 4896 | 疼 4897 | 鞭 4898 | 羧 4899 | 牦 4900 | 箭 4901 | 潴 4902 | c 4903 | 眸 4904 | 祭 4905 | 髯 4906 | 啖 4907 | 坳 4908 | 愁 4909 | 芩 4910 | 驮 4911 | 倡 4912 | 巽 4913 | 穰 4914 | 沃 4915 | 胚 4916 | 怒 4917 | 凤 4918 | 槛 4919 | 剂 4920 | 趵 4921 | 嫁 4922 | v 4923 | 邢 4924 | 灯 4925 | 鄢 4926 | 桐 4927 | 睽 4928 | 檗 4929 | 锯 4930 | 槟 4931 | 婷 4932 | 嵋 4933 | 圻 4934 | 诗 4935 | 蕈 4936 | 颠 4937 | 遭 4938 | 痢 4939 | 芸 4940 | 怯 4941 | 馥 4942 | 竭 4943 | 锗 4944 | 徜 4945 | 恭 4946 | 遍 4947 | 籁 4948 | 剑 4949 | 嘱 4950 | 苡 4951 | 龄 4952 | 僧 4953 | 桑 4954 | 潸 4955 | 弘 4956 | 澶 4957 | 楹 4958 | 悲 4959 | 讫 4960 | 愤 4961 | 腥 4962 | 悸 4963 | 谍 4964 | 椹 4965 | 呢 4966 | 桓 4967 | 葭 4968 | 攫 4969 | 阀 4970 | 翰 4971 | 躲 4972 | 敖 4973 | 柑 4974 | 郎 4975 | 笨 4976 | 橇 4977 | 呃 4978 | 魁 4979 | 燎 4980 | 脓 4981 | 葩 4982 | 磋 4983 | 垛 4984 | 玺 4985 | 狮 4986 | 沓 4987 | 砜 4988 | 蕊 4989 | 锺 4990 | 罹 4991 | 蕉 4992 | 翱 4993 | 虐 4994 | 闾 4995 | 巫 4996 | 旦 4997 | 茱 4998 | 嬷 4999 | 枯 5000 | 鹏 5001 | 贡 5002 | 芹 5003 | 汛 5004 | 矫 5005 | 绁 5006 | 拣 5007 | 禺 5008 | 佃 5009 | 讣 5010 | 舫 5011 | 惯 5012 | 乳 5013 | 趋 5014 | 疲 5015 | 挽 5016 | 岚 5017 | 虾 5018 | 衾 5019 | 蠹 5020 | 蹂 5021 | 飓 5022 | 氦 5023 | 铖 5024 | 孩 5025 | 稞 5026 | 瑜 5027 | 壅 5028 | 掀 5029 | 勘 5030 | 妓 5031 | 畅 5032 | 髋 5033 | W 5034 | 庐 5035 | 牲 5036 | 蓿 5037 | 榕 5038 | 练 5039 | 垣 5040 | 唱 5041 | 邸 5042 | 菲 5043 | 昆 5044 | 婺 5045 | 穿 5046 | 绡 5047 | 麒 5048 | 蚱 5049 | 掂 5050 | 愚 5051 | 泷 5052 | 涪 5053 | 漳 5054 | 妩 5055 | 娉 5056 | 榄 5057 | 讷 5058 | 觅 5059 | 旧 5060 | 藤 5061 | 煮 5062 | 呛 5063 | 柳 5064 | 腓 5065 | 叭 5066 | 庵 5067 | 烷 5068 | 阡 5069 | 罂 5070 | 蜕 5071 | 擂 5072 | 猖 5073 | 咿 5074 | 媲 5075 | 脉 5076 | 【 5077 | 沏 5078 | 貅 5079 | 黠 5080 | 熏 5081 | 哲 5082 | 烁 5083 | 坦 5084 | 酵 5085 | 兜 5086 | × 5087 | 潇 5088 | 撒 5089 | 剽 5090 | 珩 5091 | 圹 5092 | 乾 5093 | 摸 5094 | 樟 5095 | 帽 5096 | 嗒 5097 | 襄 5098 | 魂 5099 | 轿 5100 | 憬 5101 | 锡 5102 | 〕 5103 | 喃 5104 | 皆 5105 | 咖 5106 | 隅 5107 | 脸 5108 | 残 5109 | 泮 5110 | 袂 5111 | 鹂 5112 | 珊 5113 | 囤 5114 | 捆 5115 | 咤 5116 | 误 5117 | 徨 5118 | 闹 5119 | 淙 5120 | 芊 5121 | 淋 5122 | 怆 5123 | 囗 5124 | 拨 5125 | 梳 5126 | 渤 5127 | R 5128 | G 5129 | 绨 5130 | 蚓 5131 | 婀 5132 | 幡 5133 | 狩 5134 | 麾 5135 | 谢 5136 | 唢 5137 | 裸 5138 | 旌 5139 | 伉 5140 | 纶 5141 | 裂 5142 | 驳 5143 | 砼 5144 | 咛 5145 | 澄 5146 | 樨 5147 | 蹈 5148 | 宙 5149 | 澍 5150 | 倍 5151 | 貔 5152 | 操 5153 | 勇 5154 | 蟠 5155 | 摈 5156 | 砧 5157 | 虬 5158 | 够 5159 | 缁 5160 | 悦 5161 | 藿 5162 | 撸 5163 | 艹 5164 | 摁 5165 | 淹 5166 | 豇 5167 | 虎 5168 | 榭 5169 | ˉ 5170 | 吱 5171 | d 5172 | ° 5173 | 喧 5174 | 荀 5175 | 踱 5176 | 侮 5177 | 奋 5178 | 偕 5179 | 饷 5180 | 犍 5181 | 惮 5182 | 坑 5183 | 璎 5184 | 徘 5185 | 宛 5186 | 妆 5187 | 袈 5188 | 倩 5189 | 窦 5190 | 昂 5191 | 荏 5192 | 乖 5193 | K 5194 | 怅 5195 | 撰 5196 | 鳙 5197 | 牙 5198 | 袁 5199 | 酞 5200 | X 5201 | 痿 5202 | 琼 5203 | 闸 5204 | 雁 5205 | 趾 5206 | 荚 5207 | 虻 5208 | 涝 5209 | 《 5210 | 杏 5211 | 韭 5212 | 偈 5213 | 烤 5214 | 绫 5215 | 鞘 5216 | 卉 5217 | 症 5218 | 遢 5219 | 蓥 5220 | 诋 5221 | 杭 5222 | 荨 5223 | 匆 5224 | 竣 5225 | 簪 5226 | 辙 5227 | 敕 5228 | 虞 5229 | 丹 5230 | 缭 5231 | 咩 5232 | 黟 5233 | m 5234 | 淤 5235 | 瑕 5236 | 咂 5237 | 铉 5238 | 硼 5239 | 茨 5240 | 嶂 5241 | 痒 5242 | 畸 5243 | 敬 5244 | 涿 5245 | 粪 5246 | 窘 5247 | 熟 5248 | 叔 5249 | 嫔 5250 | 盾 5251 | 忱 5252 | 裘 5253 | 憾 5254 | 梵 5255 | 赡 5256 | 珙 5257 | 咯 5258 | 娘 5259 | 庙 5260 | 溯 5261 | 胺 5262 | 葱 5263 | 痪 5264 | 摊 5265 | 荷 5266 | 卞 5267 | 乒 5268 | 髦 5269 | 寐 5270 | 铭 5271 | 坩 5272 | 胗 5273 | 枷 5274 | 爆 5275 | 溟 5276 | 嚼 5277 | 羚 5278 | 砬 5279 | 轨 5280 | 惊 5281 | 挠 5282 | 罄 5283 | 竽 5284 | 菏 5285 | 氧 5286 | 浅 5287 | 楣 5288 | 盼 5289 | 枢 5290 | 炸 5291 | 阆 5292 | 杯 5293 | 谏 5294 | 噬 5295 | 淇 5296 | 渺 5297 | 俪 5298 | 秆 5299 | 墓 5300 | 泪 5301 | 跻 5302 | 砌 5303 | 痰 5304 | 垡 5305 | 渡 5306 | 耽 5307 | 釜 5308 | 讶 5309 | 鳎 5310 | 煞 5311 | 呗 5312 | 韶 5313 | 舶 5314 | 绷 5315 | 鹳 5316 | 缜 5317 | 旷 5318 | 铊 5319 | 皱 5320 | 龌 5321 | 檀 5322 | 霖 5323 | 奄 5324 | 槐 5325 | 艳 5326 | 蝶 5327 | 旋 5328 | 哝 5329 | 赶 5330 | 骞 5331 | 蚧 5332 | 腊 5333 | 盈 5334 | 丁 5335 | ` 5336 | 蜚 5337 | 矸 5338 | 蝙 5339 | 睨 5340 | 嚓 5341 | 僻 5342 | 鬼 5343 | 醴 5344 | 夜 5345 | 彝 5346 | 磊 5347 | 笔 5348 | 拔 5349 | 栀 5350 | 糕 5351 | 厦 5352 | 邰 5353 | 纫 5354 | 逭 5355 | 纤 5356 | 眦 5357 | 膊 5358 | 馍 5359 | 躇 5360 | 烯 5361 | 蘼 5362 | 冬 5363 | 诤 5364 | 暄 5365 | 骶 5366 | 哑 5367 | 瘠 5368 | 」 5369 | 臊 5370 | 丕 5371 | 愈 5372 | 咱 5373 | 螺 5374 | 擅 5375 | 跋 5376 | 搏 5377 | 硪 5378 | 谄 5379 | 笠 5380 | 淡 5381 | 嘿 5382 | 骅 5383 | 谧 5384 | 鼎 5385 | 皋 5386 | 姚 5387 | 歼 5388 | 蠢 5389 | 驼 5390 | 耳 5391 | 胬 5392 | 挝 5393 | 涯 5394 | 狗 5395 | 蒽 5396 | 孓 5397 | 犷 5398 | 凉 5399 | 芦 5400 | 箴 5401 | 铤 5402 | 孤 5403 | 嘛 5404 | 坤 5405 | V 5406 | 茴 5407 | 朦 5408 | 挞 5409 | 尖 5410 | 橙 5411 | 诞 5412 | 搴 5413 | 碇 5414 | 洵 5415 | 浚 5416 | 帚 5417 | 蜍 5418 | 漯 5419 | 柘 5420 | 嚎 5421 | 讽 5422 | 芭 5423 | 荤 5424 | 咻 5425 | 祠 5426 | 秉 5427 | 跖 5428 | 埃 5429 | 吓 5430 | 糯 5431 | 眷 5432 | 馒 5433 | 惹 5434 | 娼 5435 | 鲑 5436 | 嫩 5437 | 讴 5438 | 轮 5439 | 瞥 5440 | 靶 5441 | 褚 5442 | 乏 5443 | 缤 5444 | 宋 5445 | 帧 5446 | 删 5447 | 驱 5448 | 碎 5449 | 扑 5450 | 俩 5451 | 俄 5452 | 偏 5453 | 涣 5454 | 竹 5455 | 噱 5456 | 皙 5457 | 佰 5458 | 渚 5459 | 唧 5460 | 斡 5461 | # 5462 | 镉 5463 | 刀 5464 | 崎 5465 | 筐 5466 | 佣 5467 | 夭 5468 | 贰 5469 | 肴 5470 | 峙 5471 | 哔 5472 | 艿 5473 | 匐 5474 | 牺 5475 | 镛 5476 | 缘 5477 | 仡 5478 | 嫡 5479 | 劣 5480 | 枸 5481 | 堀 5482 | 梨 5483 | 簿 5484 | 鸭 5485 | 蒸 5486 | 亦 5487 | 稽 5488 | 浴 5489 | { 5490 | 衢 5491 | 束 5492 | 槲 5493 | j 5494 | 阁 5495 | 揍 5496 | 疥 5497 | 棋 5498 | 潋 5499 | 聪 5500 | 窜 5501 | 乓 5502 | 睛 5503 | 插 5504 | 冉 5505 | 阪 5506 | 苍 5507 | 搽 5508 | 「 5509 | 蟾 5510 | 螟 5511 | 幸 5512 | 仇 5513 | 樽 5514 | 撂 5515 | 慢 5516 | 跤 5517 | 幔 5518 | 俚 5519 | 淅 5520 | 覃 5521 | 觊 5522 | 溶 5523 | 妖 5524 | 帛 5525 | 侨 5526 | 曰 5527 | 妾 5528 | 泗 5529 | · 5530 | : 5531 | 瀘 5532 | 風 5533 | Ë 5534 | ( 5535 | ) 5536 | ∶ 5537 | 紅 5538 | 紗 5539 | 瑭 5540 | 雲 5541 | 頭 5542 | 鶏 5543 | 財 5544 | 許 5545 | • 5546 | ¥ 5547 | 樂 5548 | 焗 5549 | 麗 5550 | — 5551 | ; 5552 | 滙 5553 | 東 5554 | 榮 5555 | 繪 5556 | 興 5557 | … 5558 | 門 5559 | 業 5560 | π 5561 | 楊 5562 | 國 5563 | 顧 5564 | é 5565 | 盤 5566 | 寳 5567 | Λ 5568 | 龍 5569 | 鳳 5570 | 島 5571 | 誌 5572 | 緣 5573 | 結 5574 | 銭 5575 | 萬 5576 | 勝 5577 | 祎 5578 | 璟 5579 | 優 5580 | 歡 5581 | 臨 5582 | 時 5583 | 購 5584 | = 5585 | ★ 5586 | 藍 5587 | 昇 5588 | 鐵 5589 | 觀 5590 | 勅 5591 | 農 5592 | 聲 5593 | 畫 5594 | 兿 5595 | 術 5596 | 發 5597 | 劉 5598 | 記 5599 | 專 5600 | 耑 5601 | 園 5602 | 書 5603 | 壴 5604 | 種 5605 | Ο 5606 | ● 5607 | 褀 5608 | 號 5609 | 銀 5610 | 匯 5611 | 敟 5612 | 锘 5613 | 葉 5614 | 橪 5615 | 廣 5616 | 進 5617 | 蒄 5618 | 鑽 5619 | 阝 5620 | 祙 5621 | 貢 5622 | 鍋 5623 | 豊 5624 | 夬 5625 | 喆 5626 | 團 5627 | 閣 5628 | 開 5629 | 燁 5630 | 賓 5631 | 館 5632 | 酡 5633 | 沔 5634 | 順 5635 | + 5636 | 硚 5637 | 劵 5638 | 饸 5639 | 陽 5640 | 車 5641 | 湓 5642 | 復 5643 | 萊 5644 | 氣 5645 | 軒 5646 | 華 5647 | 堃 5648 | 迮 5649 | 纟 5650 | 戶 5651 | 馬 5652 | 學 5653 | 裡 5654 | 電 5655 | 嶽 5656 | 獨 5657 | マ 5658 | シ 5659 | サ 5660 | ジ 5661 | 燘 5662 | 袪 5663 | 環 5664 | ❤ 5665 | 臺 5666 | 灣 5667 | 専 5668 | 賣 5669 | 孖 5670 | 聖 5671 | 攝 5672 | 線 5673 | ▪ 5674 | α 5675 | 傢 5676 | 俬 5677 | 夢 5678 | 達 5679 | 莊 5680 | 喬 5681 | 貝 5682 | 薩 5683 | 劍 5684 | 羅 5685 | 壓 5686 | 棛 5687 | 饦 5688 | 尃 5689 | 璈 5690 | 囍 5691 | 醫 5692 | G 5693 | I 5694 | A 5695 | # 5696 | N 5697 | 鷄 5698 | 髙 5699 | 嬰 5700 | 啓 5701 | 約 5702 | 隹 5703 | 潔 5704 | 賴 5705 | 藝 5706 | ~ 5707 | 寶 5708 | 籣 5709 | 麺 5710 |   5711 | 嶺 5712 | √ 5713 | 義 5714 | 網 5715 | 峩 5716 | 長 5717 | ∧ 5718 | 魚 5719 | 機 5720 | 構 5721 | ② 5722 | 鳯 5723 | 偉 5724 | L 5725 | B 5726 | 㙟 5727 | 畵 5728 | 鴿 5729 | ' 5730 | 詩 5731 | 溝 5732 | 嚞 5733 | 屌 5734 | 藔 5735 | 佧 5736 | 玥 5737 | 蘭 5738 | 織 5739 | 1 5740 | 3 5741 | 9 5742 | 0 5743 | 7 5744 | 點 5745 | 砭 5746 | 鴨 5747 | 鋪 5748 | 銘 5749 | 廳 5750 | 弍 5751 | ‧ 5752 | 創 5753 | 湯 5754 | 坶 5755 | ℃ 5756 | 卩 5757 | 骝 5758 | & 5759 | 烜 5760 | 荘 5761 | 當 5762 | 潤 5763 | 扞 5764 | 係 5765 | 懷 5766 | 碶 5767 | 钅 5768 | 蚨 5769 | 讠 5770 | ☆ 5771 | 叢 5772 | 爲 5773 | 埗 5774 | 涫 5775 | 塗 5776 | → 5777 | 楽 5778 | 現 5779 | 鯨 5780 | 愛 5781 | 瑪 5782 | 鈺 5783 | 忄 5784 | 悶 5785 | 藥 5786 | 飾 5787 | 樓 5788 | 視 5789 | 孬 5790 | ㆍ 5791 | 燚 5792 | 苪 5793 | 師 5794 | ① 5795 | 丼 5796 | 锽 5797 | │ 5798 | 韓 5799 | 標 5800 | è 5801 | 兒 5802 | 閏 5803 | 匋 5804 | 張 5805 | 漢 5806 | Ü 5807 | 髪 5808 | 會 5809 | 閑 5810 | 檔 5811 | 習 5812 | 裝 5813 | の 5814 | 峯 5815 | 菘 5816 | 輝 5817 | И 5818 | 雞 5819 | 釣 5820 | 億 5821 | 浐 5822 | K 5823 | O 5824 | R 5825 | 8 5826 | H 5827 | E 5828 | P 5829 | T 5830 | W 5831 | D 5832 | S 5833 | C 5834 | M 5835 | F 5836 | 姌 5837 | 饹 5838 | » 5839 | 晞 5840 | 廰 5841 | ä 5842 | 嵯 5843 | 鷹 5844 | 負 5845 | 飲 5846 | 絲 5847 | 冚 5848 | 楗 5849 | 澤 5850 | 綫 5851 | 區 5852 | ❋ 5853 | ← 5854 | 質 5855 | 靑 5856 | 揚 5857 | ③ 5858 | 滬 5859 | 統 5860 | 産 5861 | 協 5862 | ﹑ 5863 | 乸 5864 | 畐 5865 | 經 5866 | 運 5867 | 際 5868 | 洺 5869 | 岽 5870 | 為 5871 | 粵 5872 | 諾 5873 | 崋 5874 | 豐 5875 | 碁 5876 | ɔ 5877 | V 5878 | 2 5879 | 6 5880 | 齋 5881 | 誠 5882 | 訂 5883 | ´ 5884 | 勑 5885 | 雙 5886 | 陳 5887 | 無 5888 | í 5889 | 泩 5890 | 媄 5891 | 夌 5892 | 刂 5893 | i 5894 | c 5895 | t 5896 | o 5897 | r 5898 | a 5899 | 嘢 5900 | 耄 5901 | 燴 5902 | 暃 5903 | 壽 5904 | 媽 5905 | 靈 5906 | 抻 5907 | 體 5908 | 唻 5909 | É 5910 | 冮 5911 | 甹 5912 | 鎮 5913 | 錦 5914 | ʌ 5915 | 蜛 5916 | 蠄 5917 | 尓 5918 | 駕 5919 | 戀 5920 | 飬 5921 | 逹 5922 | 倫 5923 | 貴 5924 | 極 5925 | Я 5926 | Й 5927 | 寬 5928 | 磚 5929 | 嶪 5930 | 郎 5931 | 職 5932 | | 5933 | 間 5934 | n 5935 | d 5936 | 剎 5937 | 伈 5938 | 課 5939 | 飛 5940 | 橋 5941 | 瘊 5942 | № 5943 | 譜 5944 | 骓 5945 | 圗 5946 | 滘 5947 | 縣 5948 | 粿 5949 | 咅 5950 | 養 5951 | 濤 5952 | 彳 5953 | ® 5954 | % 5955 | Ⅱ 5956 | 啰 5957 | 㴪 5958 | 見 5959 | 矞 5960 | 薬 5961 | 糁 5962 | 邨 5963 | 鲮 5964 | 顔 5965 | 罱 5966 | З 5967 | 選 5968 | 話 5969 | 贏 5970 | 氪 5971 | 俵 5972 | 競 5973 | 瑩 5974 | 繡 5975 | 枱 5976 | β 5977 | 綉 5978 | á 5979 | 獅 5980 | 爾 5981 | ™ 5982 | 麵 5983 | 戋 5984 | 淩 5985 | 徳 5986 | 個 5987 | 劇 5988 | 場 5989 | 務 5990 | 簡 5991 | 寵 5992 | h 5993 | 實 5994 | 膠 5995 | 轱 5996 | 圖 5997 | 築 5998 | 嘣 5999 | 樹 6000 | 㸃 6001 | 營 6002 | 耵 6003 | 孫 6004 | 饃 6005 | 鄺 6006 | 飯 6007 | 麯 6008 | 遠 6009 | 輸 6010 | 坫 6011 | 孃 6012 | 乚 6013 | 閃 6014 | 鏢 6015 | ㎡ 6016 | 題 6017 | 廠 6018 | 關 6019 | ↑ 6020 | 爺 6021 | 將 6022 | 軍 6023 | 連 6024 | 篦 6025 | 覌 6026 | 參 6027 | 箸 6028 | - 6029 | 窠 6030 | 棽 6031 | 寕 6032 | 夀 6033 | 爰 6034 | 歐 6035 | 呙 6036 | 閥 6037 | 頡 6038 | 熱 6039 | 雎 6040 | 垟 6041 | 裟 6042 | 凬 6043 | 勁 6044 | 帑 6045 | 馕 6046 | 夆 6047 | 疌 6048 | 枼 6049 | 馮 6050 | 貨 6051 | 蒤 6052 | 樸 6053 | 彧 6054 | 旸 6055 | 靜 6056 | 龢 6057 | 暢 6058 | 㐱 6059 | 鳥 6060 | 珺 6061 | 鏡 6062 | 灡 6063 | 爭 6064 | 堷 6065 | 廚 6066 | Ó 6067 | 騰 6068 | 診 6069 | ┅ 6070 | 蘇 6071 | 褔 6072 | 凱 6073 | 頂 6074 | 豕 6075 | 亞 6076 | 帥 6077 | 嘬 6078 | ⊥ 6079 | 仺 6080 | 桖 6081 | 複 6082 | 饣 6083 | 絡 6084 | 穂 6085 | 顏 6086 | 棟 6087 | 納 6088 | ▏ 6089 | 濟 6090 | 親 6091 | 設 6092 | 計 6093 | 攵 6094 | 埌 6095 | 烺 6096 | ò 6097 | 頤 6098 | 燦 6099 | 蓮 6100 | 撻 6101 | 節 6102 | 講 6103 | 濱 6104 | 濃 6105 | 娽 6106 | 洳 6107 | 朿 6108 | 燈 6109 | 鈴 6110 | 護 6111 | 膚 6112 | 铔 6113 | 過 6114 | 補 6115 | Z 6116 | U 6117 | 5 6118 | 4 6119 | 坋 6120 | 闿 6121 | 䖝 6122 | 餘 6123 | 缐 6124 | 铞 6125 | 貿 6126 | 铪 6127 | 桼 6128 | 趙 6129 | 鍊 6130 | [ 6131 | 㐂 6132 | 垚 6133 | 菓 6134 | 揸 6135 | 捲 6136 | 鐘 6137 | 滏 6138 | 𣇉 6139 | 爍 6140 | 輪 6141 | 燜 6142 | 鴻 6143 | 鮮 6144 | 動 6145 | 鹞 6146 | 鷗 6147 | 丄 6148 | 慶 6149 | 鉌 6150 | 翥 6151 | 飮 6152 | 腸 6153 | ⇋ 6154 | 漁 6155 | 覺 6156 | 來 6157 | 熘 6158 | 昴 6159 | 翏 6160 | 鲱 6161 | 圧 6162 | 鄉 6163 | 萭 6164 | 頔 6165 | 爐 6166 | 嫚 6167 | г 6168 | 貭 6169 | 類 6170 | 聯 6171 | 幛 6172 | 輕 6173 | 訓 6174 | 鑒 6175 | 夋 6176 | 锨 6177 | 芃 6178 | 珣 6179 | 䝉 6180 | 扙 6181 | 嵐 6182 | 銷 6183 | 處 6184 | ㄱ 6185 | 語 6186 | 誘 6187 | 苝 6188 | 歸 6189 | 儀 6190 | 燒 6191 | 楿 6192 | 內 6193 | 粢 6194 | 葒 6195 | 奧 6196 | 麥 6197 | 礻 6198 | 滿 6199 | 蠔 6200 | 穵 6201 | 瞭 6202 | 態 6203 | 鱬 6204 | 榞 6205 | 硂 6206 | 鄭 6207 | 黃 6208 | 煙 6209 | 祐 6210 | 奓 6211 | 逺 6212 | * 6213 | 瑄 6214 | 獲 6215 | 聞 6216 | 薦 6217 | 讀 6218 | 這 6219 | 樣 6220 | 決 6221 | 問 6222 | 啟 6223 | 們 6224 | 執 6225 | 説 6226 | 轉 6227 | 單 6228 | 隨 6229 | 唘 6230 | 帶 6231 | 倉 6232 | 庫 6233 | 還 6234 | 贈 6235 | 尙 6236 | 皺 6237 | ■ 6238 | 餅 6239 | 產 6240 | ○ 6241 | ∈ 6242 | 報 6243 | 狀 6244 | 楓 6245 | 賠 6246 | 琯 6247 | 嗮 6248 | 禮 6249 | ` 6250 | 傳 6251 | > 6252 | ≤ 6253 | 嗞 6254 | Φ 6255 | ≥ 6256 | 換 6257 | 咭 6258 | ∣ 6259 | ↓ 6260 | 曬 6261 | ε 6262 | 応 6263 | 寫 6264 | ″ 6265 | 終 6266 | 様 6267 | 純 6268 | 費 6269 | 療 6270 | 聨 6271 | 凍 6272 | 壐 6273 | 郵 6274 | ü 6275 | 黒 6276 | ∫ 6277 | 製 6278 | 塊 6279 | 調 6280 | 軽 6281 | 確 6282 | 撃 6283 | 級 6284 | 馴 6285 | Ⅲ 6286 | 涇 6287 | 繹 6288 | 數 6289 | 碼 6290 | 證 6291 | 狒 6292 | 処 6293 | 劑 6294 | < 6295 | 晧 6296 | 賀 6297 | 衆 6298 | ] 6299 | 櫥 6300 | 兩 6301 | 陰 6302 | 絶 6303 | 對 6304 | 鯉 6305 | 憶 6306 | ◎ 6307 | p 6308 | e 6309 | Y 6310 | 蕒 6311 | 煖 6312 | 頓 6313 | 測 6314 | 試 6315 | 鼽 6316 | 僑 6317 | 碩 6318 | 妝 6319 | 帯 6320 | ≈ 6321 | 鐡 6322 | 舖 6323 | 權 6324 | 喫 6325 | 倆 6326 | ˋ 6327 | 該 6328 | 悅 6329 | ā 6330 | 俫 6331 | . 6332 | f 6333 | s 6334 | b 6335 | m 6336 | k 6337 | g 6338 | u 6339 | j 6340 | 貼 6341 | 淨 6342 | 濕 6343 | 針 6344 | 適 6345 | 備 6346 | l 6347 | / 6348 | 給 6349 | 謢 6350 | 強 6351 | 觸 6352 | 衛 6353 | 與 6354 | ⊙ 6355 | $ 6356 | 緯 6357 | 變 6358 | ⑴ 6359 | ⑵ 6360 | ⑶ 6361 | ㎏ 6362 | 殺 6363 | ∩ 6364 | 幚 6365 | ─ 6366 | 價 6367 | ▲ 6368 | 離 6369 | ú 6370 | ó 6371 | 飄 6372 | 烏 6373 | 関 6374 | 閟 6375 | ﹝ 6376 | ﹞ 6377 | 邏 6378 | 輯 6379 | 鍵 6380 | 驗 6381 | 訣 6382 | 導 6383 | 歷 6384 | 屆 6385 | 層 6386 | ▼ 6387 | 儱 6388 | 錄 6389 | 熳 6390 | ē 6391 | 艦 6392 | 吋 6393 | 錶 6394 | 辧 6395 | 飼 6396 | 顯 6397 | ④ 6398 | 禦 6399 | 販 6400 | 気 6401 | 対 6402 | 枰 6403 | 閩 6404 | 紀 6405 | 幹 6406 | 瞓 6407 | 貊 6408 | 淚 6409 | △ 6410 | 眞 6411 | 墊 6412 | Ω 6413 | 獻 6414 | 褲 6415 | 縫 6416 | 緑 6417 | 亜 6418 | 鉅 6419 | 餠 6420 | { 6421 | } 6422 | ◆ 6423 | 蘆 6424 | 薈 6425 | █ 6426 | ◇ 6427 | 溫 6428 | 彈 6429 | 晳 6430 | 粧 6431 | 犸 6432 | 穩 6433 | 訊 6434 | 崬 6435 | 凖 6436 | 熥 6437 | П 6438 | 舊 6439 | 條 6440 | 紋 6441 | 圍 6442 | Ⅳ 6443 | 筆 6444 | 尷 6445 | 難 6446 | 雜 6447 | 錯 6448 | 綁 6449 | 識 6450 | 頰 6451 | 鎖 6452 | 艶 6453 | □ 6454 | 殁 6455 | 殼 6456 | ⑧ 6457 | ├ 6458 | ▕ 6459 | 鵬 6460 | ǐ 6461 | ō 6462 | ǒ 6463 | 糝 6464 | 綱 6465 | ▎ 6466 | μ 6467 | 盜 6468 | 饅 6469 | 醬 6470 | 籤 6471 | 蓋 6472 | 釀 6473 | 鹽 6474 | 據 6475 | à 6476 | ɡ 6477 | 辦 6478 | ◥ 6479 | 彐 6480 | ┌ 6481 | 婦 6482 | 獸 6483 | 鲩 6484 | 伱 6485 | ī 6486 | 蒟 6487 | 蒻 6488 | 齊 6489 | 袆 6490 | 腦 6491 | 寧 6492 | 凈 6493 | 妳 6494 | 煥 6495 | 詢 6496 | 偽 6497 | 謹 6498 | 啫 6499 | 鯽 6500 | 騷 6501 | 鱸 6502 | 損 6503 | 傷 6504 | 鎻 6505 | 髮 6506 | 買 6507 | 冏 6508 | 儥 6509 | 両 6510 | ﹢ 6511 | ∞ 6512 | 載 6513 | 喰 6514 | z 6515 | 羙 6516 | 悵 6517 | 燙 6518 | 曉 6519 | 員 6520 | 組 6521 | 徹 6522 | 艷 6523 | 痠 6524 | 鋼 6525 | 鼙 6526 | 縮 6527 | 細 6528 | 嚒 6529 | 爯 6530 | ≠ 6531 | 維 6532 | " 6533 | 鱻 6534 | 壇 6535 | 厍 6536 | 帰 6537 | 浥 6538 | 犇 6539 | 薡 6540 | 軎 6541 | ² 6542 | 應 6543 | 醜 6544 | 刪 6545 | 緻 6546 | 鶴 6547 | 賜 6548 | 噁 6549 | 軌 6550 | 尨 6551 | 镔 6552 | 鷺 6553 | 槗 6554 | 彌 6555 | 葚 6556 | 濛 6557 | 請 6558 | 溇 6559 | 緹 6560 | 賢 6561 | 訪 6562 | 獴 6563 | 瑅 6564 | 資 6565 | 縤 6566 | 陣 6567 | 蕟 6568 | 栢 6569 | 韻 6570 | 祼 6571 | 恁 6572 | 伢 6573 | 謝 6574 | 劃 6575 | 涑 6576 | 總 6577 | 衖 6578 | 踺 6579 | 砋 6580 | 凉 6581 | 籃 6582 | 駿 6583 | 苼 6584 | 瘋 6585 | 昽 6586 | 紡 6587 | 驊 6588 | 腎 6589 | ﹗ 6590 | 響 6591 | 杋 6592 | 剛 6593 | 嚴 6594 | 禪 6595 | 歓 6596 | 槍 6597 | 傘 6598 | 檸 6599 | 檫 6600 | 炣 6601 | 勢 6602 | 鏜 6603 | 鎢 6604 | 銑 6605 | 尐 6606 | 減 6607 | 奪 6608 | 惡 6609 | θ 6610 | 僮 6611 | 婭 6612 | 臘 6613 | ū 6614 | ì 6615 | 殻 6616 | 鉄 6617 | ∑ 6618 | 蛲 6619 | 焼 6620 | 緖 6621 | 續 6622 | 紹 6623 | 懮 -------------------------------------------------------------------------------- /data/structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvino-dev-samples/PaddleOCR_OpenVINO_CPP/ce03e959f333b78abbd6e6eb62345b28bfc09a44/data/structure.png -------------------------------------------------------------------------------- /data/table_structure_dict.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | colspan="2" 13 | colspan="3" 14 | rowspan="2" 15 | colspan="4" 16 | colspan="6" 17 | rowspan="3" 18 | colspan="9" 19 | colspan="10" 20 | colspan="7" 21 | rowspan="4" 22 | rowspan="5" 23 | rowspan="9" 24 | colspan="8" 25 | rowspan="8" 26 | rowspan="6" 27 | rowspan="7" 28 | rowspan="10" -------------------------------------------------------------------------------- /data/table_structure_dict_ch.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | colspan="2" 12 | colspan="3" 13 | colspan="4" 14 | colspan="5" 15 | colspan="6" 16 | colspan="7" 17 | colspan="8" 18 | colspan="9" 19 | colspan="10" 20 | colspan="11" 21 | colspan="12" 22 | colspan="13" 23 | colspan="14" 24 | colspan="15" 25 | colspan="16" 26 | colspan="17" 27 | colspan="18" 28 | colspan="19" 29 | colspan="20" 30 | rowspan="2" 31 | rowspan="3" 32 | rowspan="4" 33 | rowspan="5" 34 | rowspan="6" 35 | rowspan="7" 36 | rowspan="8" 37 | rowspan="9" 38 | rowspan="10" 39 | rowspan="11" 40 | rowspan="12" 41 | rowspan="13" 42 | rowspan="14" 43 | rowspan="15" 44 | rowspan="16" 45 | rowspan="17" 46 | rowspan="18" 47 | rowspan="19" 48 | rowspan="20" 49 | -------------------------------------------------------------------------------- /include/args.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | DECLARE_string(input); 6 | DECLARE_string(type); 7 | DECLARE_string(output_dir); 8 | DECLARE_string(det_model_dir); 9 | DECLARE_string(cls_model_dir); 10 | DECLARE_string(rec_model_dir); 11 | DECLARE_string(lay_model_dir); 12 | DECLARE_string(tab_model_dir); 13 | DECLARE_string(label_dir); 14 | DECLARE_string(layout_dict_dir); 15 | DECLARE_string(table_dict_dir); -------------------------------------------------------------------------------- /include/clipper.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * * 3 | * Author : Angus Johnson * 4 | * Version : 6.4.2 * 5 | * Date : 27 February 2017 * 6 | * Website : http://www.angusj.com * 7 | * Copyright : Angus Johnson 2010-2017 * 8 | * * 9 | * License: * 10 | * Use, modification & distribution is subject to Boost Software License Ver 1. * 11 | * http://www.boost.org/LICENSE_1_0.txt * 12 | * * 13 | * Attributions: * 14 | * The code in this library is an extension of Bala Vatti's clipping algorithm: * 15 | * "A generic solution to polygon clipping" * 16 | * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * 17 | * http://portal.acm.org/citation.cfm?id=129906 * 18 | * * 19 | * Computer graphics and geometric modeling: implementation and algorithms * 20 | * By Max K. Agoston * 21 | * Springer; 1 edition (January 4, 2005) * 22 | * http://books.google.com/books?q=vatti+clipping+agoston * 23 | * * 24 | * See also: * 25 | * "Polygon Offsetting by Computing Winding Numbers" * 26 | * Paper no. DETC2005-85513 pp. 565-575 * 27 | * ASME 2005 International Design Engineering Technical Conferences * 28 | * and Computers and Information in Engineering Conference (IDETC/CIE2005) * 29 | * September 24-28, 2005 , Long Beach, California, USA * 30 | * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * 31 | * * 32 | *******************************************************************************/ 33 | 34 | #pragma once 35 | 36 | #ifndef clipper_hpp 37 | #define clipper_hpp 38 | 39 | #define CLIPPER_VERSION "6.4.2" 40 | 41 | // use_int32: When enabled 32bit ints are used instead of 64bit ints. This 42 | // improve performance but coordinate values are limited to the range +/- 46340 43 | //#define use_int32 44 | 45 | // use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. 46 | //#define use_xyz 47 | 48 | // use_lines: Enables line clipping. Adds a very minor cost to performance. 49 | #define use_lines 50 | 51 | // use_deprecated: Enables temporary support for the obsolete functions 52 | //#define use_deprecated 53 | 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | namespace ClipperLib { 65 | 66 | enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; 67 | enum PolyType { ptSubject, ptClip }; 68 | // By far the most widely used winding rules for polygon filling are 69 | // EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) 70 | // Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) 71 | // see http://glprogramming.com/red/chapter11.html 72 | enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; 73 | 74 | #ifdef use_int32 75 | typedef int cInt; 76 | static cInt const loRange = 0x7FFF; 77 | static cInt const hiRange = 0x7FFF; 78 | #else 79 | typedef signed long long cInt; 80 | static cInt const loRange = 0x3FFFFFFF; 81 | static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; 82 | typedef signed long long long64; // used by Int128 class 83 | typedef unsigned long long ulong64; 84 | 85 | #endif 86 | 87 | struct IntPoint { 88 | cInt X; 89 | cInt Y; 90 | #ifdef use_xyz 91 | cInt Z; 92 | IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) : X(x), Y(y), Z(z){}; 93 | #else 94 | IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){}; 95 | #endif 96 | 97 | friend inline bool operator==(const IntPoint &a, const IntPoint &b) { 98 | return a.X == b.X && a.Y == b.Y; 99 | } 100 | friend inline bool operator!=(const IntPoint &a, const IntPoint &b) { 101 | return a.X != b.X || a.Y != b.Y; 102 | } 103 | }; 104 | //------------------------------------------------------------------------------ 105 | 106 | typedef std::vector Path; 107 | typedef std::vector Paths; 108 | 109 | inline Path &operator<<(Path &poly, const IntPoint &p) { 110 | poly.push_back(p); 111 | return poly; 112 | } 113 | inline Paths &operator<<(Paths &polys, const Path &p) { 114 | polys.push_back(p); 115 | return polys; 116 | } 117 | 118 | std::ostream &operator<<(std::ostream &s, const IntPoint &p); 119 | std::ostream &operator<<(std::ostream &s, const Path &p); 120 | std::ostream &operator<<(std::ostream &s, const Paths &p); 121 | 122 | struct DoublePoint { 123 | double X; 124 | double Y; 125 | DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} 126 | DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} 127 | }; 128 | //------------------------------------------------------------------------------ 129 | 130 | #ifdef use_xyz 131 | typedef void (*ZFillCallback)(IntPoint &e1bot, IntPoint &e1top, IntPoint &e2bot, 132 | IntPoint &e2top, IntPoint &pt); 133 | #endif 134 | 135 | enum InitOptions { 136 | ioReverseSolution = 1, 137 | ioStrictlySimple = 2, 138 | ioPreserveCollinear = 4 139 | }; 140 | enum JoinType { jtSquare, jtRound, jtMiter }; 141 | enum EndType { 142 | etClosedPolygon, 143 | etClosedLine, 144 | etOpenButt, 145 | etOpenSquare, 146 | etOpenRound 147 | }; 148 | 149 | class PolyNode; 150 | typedef std::vector PolyNodes; 151 | 152 | class PolyNode { 153 | public: 154 | PolyNode(); 155 | virtual ~PolyNode(){}; 156 | Path Contour; 157 | PolyNodes Childs; 158 | PolyNode *Parent; 159 | PolyNode *GetNext() const; 160 | bool IsHole() const; 161 | bool IsOpen() const; 162 | int ChildCount() const; 163 | 164 | private: 165 | // PolyNode& operator =(PolyNode& other); 166 | unsigned Index; // node index in Parent.Childs 167 | bool m_IsOpen; 168 | JoinType m_jointype; 169 | EndType m_endtype; 170 | PolyNode *GetNextSiblingUp() const; 171 | void AddChild(PolyNode &child); 172 | friend class Clipper; // to access Index 173 | friend class ClipperOffset; 174 | }; 175 | 176 | class PolyTree : public PolyNode { 177 | public: 178 | ~PolyTree() { Clear(); }; 179 | PolyNode *GetFirst() const; 180 | void Clear(); 181 | int Total() const; 182 | 183 | private: 184 | // PolyTree& operator =(PolyTree& other); 185 | PolyNodes AllNodes; 186 | friend class Clipper; // to access AllNodes 187 | }; 188 | 189 | bool Orientation(const Path &poly); 190 | double Area(const Path &poly); 191 | int PointInPolygon(const IntPoint &pt, const Path &path); 192 | 193 | void SimplifyPolygon(const Path &in_poly, Paths &out_polys, 194 | PolyFillType fillType = pftEvenOdd); 195 | void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, 196 | PolyFillType fillType = pftEvenOdd); 197 | void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); 198 | 199 | void CleanPolygon(const Path &in_poly, Path &out_poly, double distance = 1.415); 200 | void CleanPolygon(Path &poly, double distance = 1.415); 201 | void CleanPolygons(const Paths &in_polys, Paths &out_polys, 202 | double distance = 1.415); 203 | void CleanPolygons(Paths &polys, double distance = 1.415); 204 | 205 | void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution, 206 | bool pathIsClosed); 207 | void MinkowskiSum(const Path &pattern, const Paths &paths, Paths &solution, 208 | bool pathIsClosed); 209 | void MinkowskiDiff(const Path &poly1, const Path &poly2, Paths &solution); 210 | 211 | void PolyTreeToPaths(const PolyTree &polytree, Paths &paths); 212 | void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths); 213 | void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths); 214 | 215 | void ReversePath(Path &p); 216 | void ReversePaths(Paths &p); 217 | 218 | struct IntRect { 219 | cInt left; 220 | cInt top; 221 | cInt right; 222 | cInt bottom; 223 | }; 224 | 225 | // enums that are used internally ... 226 | enum EdgeSide { esLeft = 1, esRight = 2 }; 227 | 228 | // forward declarations (for stuff used internally) ... 229 | struct TEdge; 230 | struct IntersectNode; 231 | struct LocalMinimum; 232 | struct OutPt; 233 | struct OutRec; 234 | struct Join; 235 | 236 | typedef std::vector PolyOutList; 237 | typedef std::vector EdgeList; 238 | typedef std::vector JoinList; 239 | typedef std::vector IntersectList; 240 | 241 | //------------------------------------------------------------------------------ 242 | 243 | // ClipperBase is the ancestor to the Clipper class. It should not be 244 | // instantiated directly. This class simply abstracts the conversion of sets of 245 | // polygon coordinates into edge objects that are stored in a LocalMinima list. 246 | class ClipperBase { 247 | public: 248 | ClipperBase(); 249 | virtual ~ClipperBase(); 250 | virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); 251 | bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); 252 | virtual void Clear(); 253 | IntRect GetBounds(); 254 | bool PreserveCollinear() { return m_PreserveCollinear; }; 255 | void PreserveCollinear(bool value) { m_PreserveCollinear = value; }; 256 | 257 | protected: 258 | void DisposeLocalMinimaList(); 259 | TEdge *AddBoundsToLML(TEdge *e, bool IsClosed); 260 | virtual void Reset(); 261 | TEdge *ProcessBound(TEdge *E, bool IsClockwise); 262 | void InsertScanbeam(const cInt Y); 263 | bool PopScanbeam(cInt &Y); 264 | bool LocalMinimaPending(); 265 | bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin); 266 | OutRec *CreateOutRec(); 267 | void DisposeAllOutRecs(); 268 | void DisposeOutRec(PolyOutList::size_type index); 269 | void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); 270 | void DeleteFromAEL(TEdge *e); 271 | void UpdateEdgeIntoAEL(TEdge *&e); 272 | 273 | typedef std::vector MinimaList; 274 | MinimaList::iterator m_CurrentLM; 275 | MinimaList m_MinimaList; 276 | 277 | bool m_UseFullRange; 278 | EdgeList m_edges; 279 | bool m_PreserveCollinear; 280 | bool m_HasOpenPaths; 281 | PolyOutList m_PolyOuts; 282 | TEdge *m_ActiveEdges; 283 | 284 | typedef std::priority_queue ScanbeamList; 285 | ScanbeamList m_Scanbeam; 286 | }; 287 | //------------------------------------------------------------------------------ 288 | 289 | class Clipper : public virtual ClipperBase { 290 | public: 291 | Clipper(int initOptions = 0); 292 | bool Execute(ClipType clipType, Paths &solution, 293 | PolyFillType fillType = pftEvenOdd); 294 | bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, 295 | PolyFillType clipFillType); 296 | bool Execute(ClipType clipType, PolyTree &polytree, 297 | PolyFillType fillType = pftEvenOdd); 298 | bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType, 299 | PolyFillType clipFillType); 300 | bool ReverseSolution() { return m_ReverseOutput; }; 301 | void ReverseSolution(bool value) { m_ReverseOutput = value; }; 302 | bool StrictlySimple() { return m_StrictSimple; }; 303 | void StrictlySimple(bool value) { m_StrictSimple = value; }; 304 | // set the callback function for z value filling on intersections (otherwise Z 305 | // is 0) 306 | #ifdef use_xyz 307 | void ZFillFunction(ZFillCallback zFillFunc); 308 | #endif 309 | protected: 310 | virtual bool ExecuteInternal(); 311 | 312 | private: 313 | JoinList m_Joins; 314 | JoinList m_GhostJoins; 315 | IntersectList m_IntersectList; 316 | ClipType m_ClipType; 317 | typedef std::list MaximaList; 318 | MaximaList m_Maxima; 319 | TEdge *m_SortedEdges; 320 | bool m_ExecuteLocked; 321 | PolyFillType m_ClipFillType; 322 | PolyFillType m_SubjFillType; 323 | bool m_ReverseOutput; 324 | bool m_UsingPolyTree; 325 | bool m_StrictSimple; 326 | #ifdef use_xyz 327 | ZFillCallback m_ZFill; // custom callback 328 | #endif 329 | void SetWindingCount(TEdge &edge); 330 | bool IsEvenOddFillType(const TEdge &edge) const; 331 | bool IsEvenOddAltFillType(const TEdge &edge) const; 332 | void InsertLocalMinimaIntoAEL(const cInt botY); 333 | void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge); 334 | void AddEdgeToSEL(TEdge *edge); 335 | bool PopEdgeFromSEL(TEdge *&edge); 336 | void CopyAELToSEL(); 337 | void DeleteFromSEL(TEdge *e); 338 | void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); 339 | bool IsContributing(const TEdge &edge) const; 340 | bool IsTopHorz(const cInt XPos); 341 | void DoMaxima(TEdge *e); 342 | void ProcessHorizontals(); 343 | void ProcessHorizontal(TEdge *horzEdge); 344 | void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); 345 | OutPt *AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); 346 | OutRec *GetOutRec(int idx); 347 | void AppendPolygon(TEdge *e1, TEdge *e2); 348 | void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); 349 | OutPt *AddOutPt(TEdge *e, const IntPoint &pt); 350 | OutPt *GetLastOutPt(TEdge *e); 351 | bool ProcessIntersections(const cInt topY); 352 | void BuildIntersectList(const cInt topY); 353 | void ProcessIntersectList(); 354 | void ProcessEdgesAtTopOfScanbeam(const cInt topY); 355 | void BuildResult(Paths &polys); 356 | void BuildResult2(PolyTree &polytree); 357 | void SetHoleState(TEdge *e, OutRec *outrec); 358 | void DisposeIntersectNodes(); 359 | bool FixupIntersectionOrder(); 360 | void FixupOutPolygon(OutRec &outrec); 361 | void FixupOutPolyline(OutRec &outrec); 362 | bool IsHole(TEdge *e); 363 | bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); 364 | void FixHoleLinkage(OutRec &outrec); 365 | void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); 366 | void ClearJoins(); 367 | void ClearGhostJoins(); 368 | void AddGhostJoin(OutPt *op, const IntPoint offPt); 369 | bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2); 370 | void JoinCommonEdges(); 371 | void DoSimplePolygons(); 372 | void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec); 373 | void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec); 374 | void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec); 375 | #ifdef use_xyz 376 | void SetZ(IntPoint &pt, TEdge &e1, TEdge &e2); 377 | #endif 378 | }; 379 | //------------------------------------------------------------------------------ 380 | 381 | class ClipperOffset { 382 | public: 383 | ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); 384 | ~ClipperOffset(); 385 | void AddPath(const Path &path, JoinType joinType, EndType endType); 386 | void AddPaths(const Paths &paths, JoinType joinType, EndType endType); 387 | void Execute(Paths &solution, double delta); 388 | void Execute(PolyTree &solution, double delta); 389 | void Clear(); 390 | double MiterLimit; 391 | double ArcTolerance; 392 | 393 | private: 394 | Paths m_destPolys; 395 | Path m_srcPoly; 396 | Path m_destPoly; 397 | std::vector m_normals; 398 | double m_delta, m_sinA, m_sin, m_cos; 399 | double m_miterLim, m_StepsPerRad; 400 | IntPoint m_lowest; 401 | PolyNode m_polyNodes; 402 | 403 | void FixOrientations(); 404 | void DoOffset(double delta); 405 | void OffsetPoint(int j, int &k, JoinType jointype); 406 | void DoSquare(int j, int k); 407 | void DoMiter(int j, int k, double r); 408 | void DoRound(int j, int k); 409 | }; 410 | //------------------------------------------------------------------------------ 411 | 412 | class clipperException : public std::exception { 413 | public: 414 | clipperException(const char *description) : m_descr(description) {} 415 | virtual ~clipperException() throw() {} 416 | virtual const char *what() const throw() { return m_descr.c_str(); } 417 | 418 | private: 419 | std::string m_descr; 420 | }; 421 | //------------------------------------------------------------------------------ 422 | 423 | } // ClipperLib namespace 424 | 425 | #endif // clipper_hpp 426 | -------------------------------------------------------------------------------- /include/ocr_cls.h: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace PaddleOCR { 20 | 21 | class Classifier 22 | { 23 | public: 24 | explicit Classifier(std::string model_path); 25 | void Run(std::vector img_list, std::vector &ocr_results); 26 | 27 | double cls_thresh = 0.5; 28 | 29 | private: 30 | ov::InferRequest infer_request; 31 | std::string model_path; 32 | std::shared_ptr model; 33 | ov::CompiledModel compiled_model; 34 | 35 | double e = 1.0 / 255.0; 36 | std::vector mean_ = {0.5f, 0.5f, 0.5f}; 37 | std::vector scale_ = {0.5f, 0.5f, 0.5f}; 38 | int cls_batch_num_ = 1; 39 | std::vector cls_image_shape = {3, 48, 192}; 40 | 41 | // resize 42 | ClsResizeImg resize_op_; 43 | }; 44 | } -------------------------------------------------------------------------------- /include/ocr_det.h: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace PaddleOCR { 20 | 21 | class Detector 22 | { 23 | public: 24 | explicit Detector(std::string model_path); 25 | void Run(cv::Mat &src_img, std::vector &ocr_results); 26 | 27 | private: 28 | ov::InferRequest infer_request; 29 | std::string model_path; 30 | cv::Mat src_img; 31 | std::shared_ptr model; 32 | ov::CompiledModel compiled_model; 33 | 34 | float ratio_h{}; 35 | float ratio_w{}; 36 | cv::Mat resize_img; 37 | std::string limit_type_ = "max"; 38 | int limit_side_len_ = 960; 39 | double e = 1.0 / 255.0; 40 | std::vector mean_ = {0.485f, 0.456f, 0.406f}; 41 | std::vector scale_ = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f}; 42 | bool is_scale_ = true; 43 | double det_db_thresh_ = 0.3; 44 | double det_db_box_thresh_ = 0.5; 45 | double det_db_unclip_ratio_ = 2.0; 46 | std::string det_db_score_mode_ = "slow"; 47 | bool use_dilation_ = false; 48 | 49 | // pre-process 50 | ResizeImgType0 resize_op_; 51 | Normalize normalize_op_; 52 | Permute permute_op_; 53 | 54 | // post-process 55 | DBPostProcessor post_processor_; 56 | }; 57 | } -------------------------------------------------------------------------------- /include/ocr_rec.h: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | using namespace cv; 21 | 22 | namespace PaddleOCR { 23 | 24 | class Recognizer 25 | { 26 | public: 27 | explicit Recognizer(string model_path, const string &label_path); 28 | void Run(std::vector img_list, std::vector &ocr_results); 29 | 30 | private: 31 | ov::InferRequest infer_request; 32 | string model_path; 33 | shared_ptr model; 34 | ov::CompiledModel compiled_model; 35 | 36 | std::vector mean_ = {0.5f, 0.5f, 0.5f}; 37 | std::vector scale_ = {1 / 0.5f, 1 / 0.5f, 1 / 0.5f}; 38 | bool is_scale_ = true; 39 | std::vector label_list_; 40 | int rec_batch_num_ = 6; 41 | int rec_img_h_ = 48; 42 | int rec_img_w_ = 320; 43 | std::vector rec_image_shape_ = {3, rec_img_h_, rec_img_w_}; 44 | 45 | CrnnResizeImg resize_op_; 46 | Normalize normalize_op_; 47 | PermuteBatch permute_op_; 48 | }; 49 | } -------------------------------------------------------------------------------- /include/paddleocr.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace PaddleOCR { 22 | 23 | class PPOCR { 24 | public: 25 | explicit PPOCR(); 26 | ~PPOCR(); 27 | 28 | std::vector ocr(cv::Mat img); 29 | 30 | protected: 31 | Detector *detector_ = nullptr; 32 | Classifier *classifier_ = nullptr; 33 | Recognizer *recognizer_ = nullptr; 34 | }; 35 | 36 | } // namespace PaddleOCR 37 | -------------------------------------------------------------------------------- /include/paddlestructure.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace PaddleOCR { 22 | 23 | class PaddleStructure : public PPOCR { 24 | public: 25 | explicit PaddleStructure(); 26 | ~PaddleStructure(); 27 | 28 | std::vector structure(cv::Mat img); 29 | 30 | 31 | private: 32 | Layout *layout_model_ = nullptr; 33 | Table *table_model_ = nullptr; 34 | 35 | std::string rebuild_table(std::vector rec_html_tags, 36 | std::vector> rec_boxes, 37 | std::vector &ocr_result); 38 | 39 | float dis(std::vector &box1, std::vector &box2); 40 | 41 | static bool comparison_dis(const std::vector &dis1, 42 | const std::vector &dis2) { 43 | if (dis1[1] < dis2[1]) { 44 | return true; 45 | } else if (dis1[1] == dis2[1]) { 46 | return dis1[0] < dis2[0]; 47 | } else { 48 | return false; 49 | } 50 | } 51 | }; 52 | 53 | } // namespace PaddleOCR -------------------------------------------------------------------------------- /include/postprocess_op.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "include/clipper.h" 18 | #include "include/utility.h" 19 | #include 20 | 21 | 22 | namespace PaddleOCR { 23 | 24 | class DBPostProcessor { 25 | public: 26 | void GetContourArea(const std::vector> &box, 27 | float unclip_ratio, float &distance); 28 | 29 | cv::RotatedRect UnClip(std::vector> box, 30 | const float &unclip_ratio); 31 | 32 | float **Mat2Vec(cv::Mat mat); 33 | 34 | std::vector> 35 | OrderPointsClockwise(std::vector> pts); 36 | 37 | std::vector> GetMiniBoxes(cv::RotatedRect box, 38 | float &ssid); 39 | 40 | float BoxScoreFast(std::vector> box_array, cv::Mat pred); 41 | float PolygonScoreAcc(std::vector contour, cv::Mat pred); 42 | 43 | std::vector>> 44 | BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap, 45 | const float &box_thresh, const float &det_db_unclip_ratio, 46 | const std::string &det_db_score_mode); 47 | 48 | std::vector>> 49 | FilterTagDetRes(std::vector>> boxes, 50 | float ratio_h, float ratio_w, cv::Mat srcimg); 51 | 52 | private: 53 | static bool XsortInt(std::vector a, std::vector b); 54 | 55 | static bool XsortFp32(std::vector a, std::vector b); 56 | 57 | std::vector> Mat2Vector(cv::Mat mat); 58 | 59 | inline int _max(int a, int b) { return a >= b ? a : b; } 60 | 61 | inline int _min(int a, int b) { return a >= b ? b : a; } 62 | 63 | template inline T clamp(T x, T min, T max) { 64 | if (x > max) 65 | return max; 66 | if (x < min) 67 | return min; 68 | return x; 69 | } 70 | 71 | inline float clampf(float x, float min, float max) { 72 | if (x > max) 73 | return max; 74 | if (x < min) 75 | return min; 76 | return x; 77 | } 78 | }; 79 | 80 | class TablePostProcessor { 81 | public: 82 | void init(std::string label_path, bool merge_no_span_structure = true); 83 | void Run(std::vector &loc_preds, std::vector &structure_probs, 84 | std::vector &rec_scores, ov::Shape &loc_preds_shape, 85 | ov::Shape &structure_probs_shape, 86 | std::vector> &rec_html_tag_batch, 87 | std::vector>> &rec_boxes_batch, 88 | std::vector &width_list, std::vector &height_list); 89 | 90 | private: 91 | std::vector label_list_; 92 | std::string end = "eos"; 93 | std::string beg = "sos"; 94 | }; 95 | 96 | class PicodetPostProcessor { 97 | public: 98 | void init(std::string label_path, const double score_threshold = 0.4, 99 | const double nms_threshold = 0.5, 100 | const std::vector &fpn_stride = {8, 16, 32, 64}); 101 | void Run(std::vector &results, 102 | std::vector> outs, std::vector ori_shape, 103 | std::vector resize_shape, int eg_max); 104 | std::vector fpn_stride_ = {8, 16, 32, 64}; 105 | 106 | private: 107 | StructurePredictResult disPred2Bbox(std::vector bbox_pred, int label, 108 | float score, int x, int y, int stride, 109 | std::vector im_shape, int reg_max); 110 | void nms(std::vector &input_boxes, 111 | float nms_threshold); 112 | 113 | std::vector label_list_; 114 | double score_threshold_ = 0.4; 115 | double nms_threshold_ = 0.5; 116 | int num_class_ = 5; 117 | }; 118 | 119 | } // namespace PaddleOCR 120 | -------------------------------------------------------------------------------- /include/preprocess_op.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include "opencv2/core.hpp" 21 | #include "opencv2/imgcodecs.hpp" 22 | #include "opencv2/imgproc.hpp" 23 | 24 | namespace PaddleOCR { 25 | 26 | class Normalize { 27 | public: 28 | virtual void Run(cv::Mat *im, const std::vector &mean, 29 | const std::vector &scale, const bool is_scale = true); 30 | }; 31 | 32 | // RGB -> CHW 33 | class Permute { 34 | public: 35 | virtual void Run(const cv::Mat *im, float *data); 36 | }; 37 | 38 | class PermuteBatch { 39 | public: 40 | virtual void Run(const std::vector imgs, float *data); 41 | }; 42 | 43 | class ResizeImgType0 { 44 | public: 45 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, 46 | std::string limit_type, int limit_side_len, float &ratio_h, 47 | float &ratio_w); 48 | }; 49 | 50 | class CrnnResizeImg { 51 | public: 52 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, float wh_ratio, 53 | const std::vector &rec_image_shape = {3, 32, 320}); 54 | }; 55 | 56 | class ClsResizeImg { 57 | public: 58 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, 59 | const std::vector &rec_image_shape = {3, 48, 192}); 60 | }; 61 | 62 | class TableResizeImg { 63 | public: 64 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, 65 | const int max_len = 488); 66 | }; 67 | 68 | class TablePadImg { 69 | public: 70 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, 71 | const int max_len = 488); 72 | }; 73 | 74 | class Resize { 75 | public: 76 | virtual void Run(const cv::Mat &img, cv::Mat &resize_img, const int h, 77 | const int w); 78 | }; 79 | 80 | } // namespace PaddleOCR -------------------------------------------------------------------------------- /include/structure_layout.h: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace PaddleOCR { 21 | 22 | class Layout 23 | { 24 | public: 25 | explicit Layout(std::string model_path, std::string layout_dict_path); 26 | void Run(cv::Mat &src_img, std::vector &structure_result); 27 | 28 | private: 29 | 30 | ov::InferRequest infer_request; 31 | std::string model_path; 32 | std::shared_ptr model; 33 | ov::CompiledModel compiled_model; 34 | 35 | cv::Mat src_img; 36 | cv::Mat resize_img; 37 | double e = 1.0 / 255.0; 38 | const int layout_img_h_ = 800; 39 | const int layout_img_w_ = 608; 40 | double layout_nms_threshold = 0.5; 41 | double layout_score_threshold = 0.5; 42 | std::vector mean_ = {0.485f, 0.456f, 0.406f}; 43 | std::vector scale_ = {0.229f, 0.224f, 0.225f}; 44 | 45 | // resize 46 | Resize resize_op_; 47 | // post-process 48 | PicodetPostProcessor post_processor_; 49 | }; 50 | } -------------------------------------------------------------------------------- /include/structure_table.h: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace PaddleOCR { 20 | 21 | class Table 22 | { 23 | public: 24 | explicit Table(std::string model_path, const std::string table_char_dict_path); 25 | void Run(std::vector img_list, 26 | std::vector> &structure_html_tags, 27 | std::vector &structure_scores, 28 | std::vector>> &structure_boxes); 29 | 30 | private: 31 | 32 | ov::InferRequest infer_request; 33 | std::string model_path; 34 | std::shared_ptr model; 35 | ov::CompiledModel compiled_model; 36 | 37 | cv::Mat src_img; 38 | cv::Mat resize_img; 39 | const std::string table_char_dict_path; 40 | 41 | int table_batch_num_ = 1; 42 | int table_max_len_ = 488; 43 | std::vector mean_ = {0.485f, 0.456f, 0.406f}; 44 | std::vector scale_ = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f}; 45 | bool is_scale_ = true; 46 | 47 | // pre-process 48 | TableResizeImg resize_op_; 49 | Normalize normalize_op_; 50 | PermuteBatch permute_op_; 51 | TablePadImg pad_op_; 52 | 53 | // post-process 54 | TablePostProcessor post_processor_; 55 | }; 56 | } -------------------------------------------------------------------------------- /include/utility.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "opencv2/core.hpp" 30 | #include "opencv2/imgcodecs.hpp" 31 | #include "opencv2/imgproc.hpp" 32 | 33 | namespace PaddleOCR { 34 | 35 | struct OCRPredictResult { 36 | std::vector> box; 37 | std::string text; 38 | float score = -1.0; 39 | float cls_score; 40 | int cls_label = -1; 41 | }; 42 | 43 | struct StructurePredictResult { 44 | std::vector box; 45 | std::vector> cell_box; 46 | std::string type; 47 | std::vector text_res; 48 | std::string html; 49 | float html_score = -1; 50 | float confidence; 51 | }; 52 | 53 | class Utility { 54 | public: 55 | static std::vector ReadDict(const std::string &path); 56 | 57 | static void VisualizeBboxes(const cv::Mat &srcimg, 58 | const std::vector &ocr_result, 59 | const std::string &save_path); 60 | 61 | static void VisualizeBboxes(const cv::Mat &srcimg, 62 | const StructurePredictResult &structure_result, 63 | const std::string &save_path); 64 | 65 | template 66 | inline static size_t argmax(ForwardIterator first, ForwardIterator last) { 67 | return std::distance(first, std::max_element(first, last)); 68 | } 69 | 70 | static void GetAllFiles(const char *dir_name, 71 | std::vector &all_inputs); 72 | 73 | static cv::Mat GetRotateCropImage(const cv::Mat &srcimage, 74 | std::vector> box); 75 | 76 | static std::vector argsort(const std::vector &array); 77 | 78 | static std::string basename(const std::string &filename); 79 | 80 | static bool PathExists(const std::string &path); 81 | 82 | static void CreateDir(const std::string &path); 83 | 84 | static void print_result(const std::vector &ocr_result); 85 | 86 | static cv::Mat crop_image(cv::Mat &img, const std::vector &area); 87 | static cv::Mat crop_image(cv::Mat &img, const std::vector &area); 88 | 89 | static void sorted_boxes(std::vector &ocr_result); 90 | 91 | static std::vector xyxyxyxy2xyxy(std::vector> &box); 92 | static std::vector xyxyxyxy2xyxy(std::vector &box); 93 | 94 | static float fast_exp(float x); 95 | static std::vector 96 | activation_function_softmax(std::vector &src); 97 | static float iou(std::vector &box1, std::vector &box2); 98 | static float iou(std::vector &box1, std::vector &box2); 99 | 100 | private: 101 | static bool comparison_box(const OCRPredictResult &result1, 102 | const OCRPredictResult &result2) { 103 | if (result1.box[0][1] < result2.box[0][1]) { 104 | return true; 105 | } else if (result1.box[0][1] == result2.box[0][1]) { 106 | return result1.box[0][0] < result2.box[0][0]; 107 | } else { 108 | return false; 109 | } 110 | } 111 | }; 112 | 113 | } // namespace PaddleOCR -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "opencv2/core.hpp" 2 | #include "opencv2/imgcodecs.hpp" 3 | #include "opencv2/imgproc.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace PaddleOCR; 12 | 13 | void check_params() 14 | { 15 | if (FLAGS_type == "ocr") 16 | { 17 | if (FLAGS_det_model_dir.empty() || FLAGS_rec_model_dir.empty()) 18 | { 19 | std::cout << "Need a path to detection and recogition model" 20 | "[Usage] --det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ --rec_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ " 21 | << std::endl; 22 | exit(1); 23 | } 24 | } 25 | else if (FLAGS_type == "structure") 26 | { 27 | if (FLAGS_det_model_dir.empty() || FLAGS_rec_model_dir.empty() || FLAGS_lay_model_dir.empty() || FLAGS_tab_model_dir.empty()) 28 | { 29 | std::cout << "Need a path to detection, recogition, layout and table model" 30 | "[Usage] --det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ --rec_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ --lay_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ --tab_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ " 31 | << std::endl; 32 | exit(1); 33 | } 34 | } 35 | } 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | gflags::ParseCommandLineFlags(&argc, &argv, true); 40 | check_params(); 41 | 42 | // read image 43 | cv::Mat src_img = imread(FLAGS_input); 44 | 45 | if (FLAGS_type == "ocr") 46 | { 47 | PPOCR ppocr; 48 | std::vector ocr_result = ppocr.ocr(src_img); 49 | Utility::print_result(ocr_result); 50 | Utility::VisualizeBboxes(src_img, ocr_result, 51 | "./ocr_result.jpg"); 52 | } 53 | else if (FLAGS_type == "structure") 54 | { 55 | 56 | PaddleStructure paddlestructure; 57 | std::vector structure_results = paddlestructure.structure(src_img); 58 | for (int j = 0; j < structure_results.size(); j++) 59 | { 60 | std::cout << j << "\ttype: " << structure_results[j].type 61 | << ", region: ["; 62 | std::cout << structure_results[j].box[0] << "," 63 | << structure_results[j].box[1] << "," 64 | << structure_results[j].box[2] << "," 65 | << structure_results[j].box[3] << "], score: "; 66 | std::cout << structure_results[j].confidence << ", res: "; 67 | 68 | if (structure_results[j].type == "table") 69 | { 70 | std::cout << structure_results[j].html << std::endl; 71 | if (structure_results[j].cell_box.size() > 0) 72 | { 73 | Utility::VisualizeBboxes(src_img, structure_results[j], 74 | "./structure_result" + std::to_string(j) + ".jpg"); 75 | } 76 | } 77 | else 78 | { 79 | std::cout << "count of ocr result is : " 80 | << structure_results[j].text_res.size() << std::endl; 81 | if (structure_results[j].text_res.size() > 0) 82 | { 83 | std::cout << "********** print ocr result " 84 | << "**********" << std::endl; 85 | Utility::print_result(structure_results[j].text_res); 86 | std::cout << "********** end print ocr result " 87 | << "**********" << std::endl; 88 | } 89 | } 90 | } 91 | } 92 | else 93 | { 94 | std::cout << "only value in ['ocr','structure'] is supported" << std::endl; 95 | } 96 | } -------------------------------------------------------------------------------- /ocr_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvino-dev-samples/PaddleOCR_OpenVINO_CPP/ce03e959f333b78abbd6e6eb62345b28bfc09a44/ocr_result.jpg -------------------------------------------------------------------------------- /ov_inference.py: -------------------------------------------------------------------------------- 1 | import openvino.runtime as ov 2 | import numpy as np 3 | 4 | 5 | core = ov.Core() 6 | 7 | compiled_model = core.compile_model("/home/ethan/Downloads/PaddleOCRv3/en_ppocr_mobile_v2.0_table_structure_infer/table.onnx", "CPU") 8 | infer_request = compiled_model.create_infer_request() 9 | 10 | data = np.ones((1,3,488,488)) 11 | data = data.astype('float32') 12 | 13 | result_infer = compiled_model([data]) 14 | 15 | result_infer -------------------------------------------------------------------------------- /paddle_inference.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | from paddle.inference import Config 5 | from paddle.inference import create_predictor 6 | 7 | config = Config('/home/ethan/Downloads/PaddleOCRv3/en_ppocr_mobile_v2.0_table_structure_infer/inference.pdmodel', '/home/ethan/Downloads/PaddleOCRv3/en_ppocr_mobile_v2.0_table_structure_infer/inference.pdiparams') 8 | config.enable_memory_optim() 9 | config.set_cpu_math_library_num_threads(4) 10 | config.enable_mkldnn() 11 | 12 | predictor = create_predictor(config) 13 | 14 | def run(predictor, img): 15 | # copy img data to input tensor 16 | input_names = predictor.get_input_names() 17 | for i, name in enumerate(input_names): 18 | input_tensor = predictor.get_input_handle(name) 19 | input_tensor.reshape(img[i].shape) 20 | input_tensor.copy_from_cpu(img[i].copy()) 21 | 22 | # do the inference 23 | predictor.run() 24 | 25 | results = [] 26 | # get out data from output tensor 27 | output_names = predictor.get_output_names() 28 | for i, name in enumerate(output_names): 29 | output_tensor = predictor.get_output_handle(name) 30 | output_data = output_tensor.copy_to_cpu() 31 | results.append(output_data) 32 | return results 33 | data = np.ones((1,3,488,488)) 34 | data = data.astype('float32') 35 | #data = np.ones((1,3,488,488), dtype=float) 36 | result = run(predictor, [data]) 37 | result -------------------------------------------------------------------------------- /src/args.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | DEFINE_string(input, "", "Required. Path to image file"); 4 | DEFINE_string(type, "", "Required. Task type ('ocr' or 'structure')"); 5 | DEFINE_string(output_dir, "./", "Path to output results."); 6 | DEFINE_string(det_model_dir, "", "Path to detection model file"); 7 | DEFINE_string(cls_model_dir, "", "Path to classification model file"); 8 | DEFINE_string(rec_model_dir, "", "Path to recognition model file"); 9 | DEFINE_string(lay_model_dir, "", "Path to layout model file"); 10 | DEFINE_string(tab_model_dir, "", "Path to table model file"); 11 | DEFINE_string(label_dir, "", "Required. Path to label file"); 12 | DEFINE_string(layout_dict_dir, 13 | "/home/ethan/PaddleOCR_OpenVINO_CPP/data/layout_publaynet_dict.txt", 14 | "Path of dictionary."); 15 | DEFINE_string(table_dict_dir, 16 | "/home/ethan/PaddleOCR_OpenVINO_CPP/data/table_structure_dict.txt", 17 | "Path of dictionary."); -------------------------------------------------------------------------------- /src/ocr_cls.cpp: -------------------------------------------------------------------------------- 1 | #include "include/ocr_cls.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Classifier::Classifier(std::string model_path) 6 | { 7 | this->model_path = model_path; 8 | ov::Core core; 9 | this->model = core.read_model(this->model_path); 10 | // dimension of batch size is dynamic 11 | this->model->reshape({{ov::Dimension(1, 6), cls_image_shape[0], cls_image_shape[1], cls_image_shape[2]}}); 12 | 13 | // preprocessing API 14 | ov::preprocess::PrePostProcessor prep(this->model); 15 | // declare section of desired application's input format 16 | prep.input().tensor() 17 | .set_layout("NHWC") 18 | .set_color_format(ov::preprocess::ColorFormat::BGR); 19 | // specify actual model layout 20 | prep.input().model() 21 | .set_layout("NCHW"); 22 | prep.input().preprocess() 23 | .mean(this->mean_) 24 | .scale(this->scale_); 25 | // dump preprocessor 26 | std::cout << "Preprocessor: " << prep << std::endl; 27 | this->model = prep.build(); 28 | this->compiled_model = core.compile_model(this->model, "CPU"); 29 | this->infer_request = compiled_model.create_infer_request(); 30 | } 31 | 32 | void Classifier::Run(std::vector img_list, std::vector &ocr_results) 33 | { 34 | std::vector cls_labels(img_list.size(), 0); 35 | std::vector cls_scores(img_list.size(), 0); 36 | std::vector cls_times; 37 | 38 | auto input_port = this->compiled_model.input(); 39 | int img_num = img_list.size(); 40 | for (int beg_img_no = 0; beg_img_no < img_num; beg_img_no += this->cls_batch_num_) { 41 | int end_img_no = std::min(img_num, beg_img_no + this->cls_batch_num_); 42 | int batch_num = end_img_no - beg_img_no; 43 | 44 | std::vector batch_tensors; 45 | ov::Shape intput_shape = {batch_num, cls_image_shape[1], cls_image_shape[2],3}; 46 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 47 | cv::Mat srcimg; 48 | img_list[ino].copyTo(srcimg); 49 | cv::Mat resize_img; 50 | // preprocess 51 | this->resize_op_.Run(srcimg, resize_img, this->cls_image_shape); 52 | resize_img.convertTo(resize_img, CV_32FC3, e); 53 | if (resize_img.cols < cls_image_shape[2]) { 54 | cv::copyMakeBorder(resize_img, resize_img, 0, 0, 0, 55 | cls_image_shape[2] - resize_img.cols, 56 | cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0)); 57 | } 58 | // prepare input tensor 59 | ov::Tensor input_tensor(input_port.get_element_type(), intput_shape, (float*)resize_img.data); 60 | batch_tensors.push_back(input_tensor); 61 | } 62 | 63 | // set batched input tensors 64 | this->infer_request.set_input_tensors(batch_tensors); 65 | // start inference 66 | this->infer_request.infer(); 67 | 68 | // get output tensor 69 | auto output = this->infer_request.get_output_tensor(); 70 | const float *out_data = output.data(); 71 | for (size_t batch_idx = 0; batch_idx < output.get_size() / 2; batch_idx++){ 72 | int label = int( 73 | Utility::argmax(&out_data[batch_idx * 2], 74 | &out_data[(batch_idx + 1) * 2])); 75 | float score = float(*std::max_element( 76 | &out_data[batch_idx * 2], 77 | &out_data[(batch_idx + 1) * 2])); 78 | cls_labels[beg_img_no + batch_idx] = label; 79 | cls_scores[beg_img_no + batch_idx] = score; 80 | } 81 | } 82 | 83 | for (int i = 0; i < cls_labels.size(); i++) { 84 | ocr_results[i].cls_label = cls_labels[i]; 85 | ocr_results[i].cls_score = cls_scores[i]; 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/ocr_det.cpp: -------------------------------------------------------------------------------- 1 | #include "include/ocr_det.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Detector::Detector(std::string model_path) 6 | { 7 | ov::Core core; 8 | this->model_path = model_path; 9 | this->model = core.read_model(this->model_path); 10 | this->model->reshape({1, 3, ov::Dimension(32, this->limit_side_len_), ov::Dimension(1, this->limit_side_len_)}); 11 | this->compiled_model = core.compile_model(this->model, "CPU"); 12 | this->infer_request = this->compiled_model.create_infer_request(); 13 | } 14 | 15 | void Detector::Run(cv::Mat &src_img, std::vector &ocr_results) 16 | { 17 | this->src_img = src_img; 18 | this->resize_op_.Run(this->src_img, this->resize_img, this->limit_type_, 19 | this->limit_side_len_, this->ratio_h, this->ratio_w); 20 | 21 | this->normalize_op_.Run(&resize_img, this->mean_, this->scale_, 22 | this->is_scale_); 23 | 24 | std::vector input(1 * 3 * resize_img.rows * resize_img.cols, 0.0f); 25 | ov::Shape intput_shape = {1, 3, resize_img.rows, resize_img.cols}; 26 | this->permute_op_.Run(&resize_img, input.data()); 27 | 28 | std::vector>> boxes; 29 | auto input_port = this->compiled_model.input(); 30 | 31 | // -------- set input -------- 32 | ov::Tensor input_tensor(input_port.get_element_type(), intput_shape, input.data()); 33 | this->infer_request.set_input_tensor(input_tensor); 34 | // -------- start inference -------- 35 | 36 | this->infer_request.infer(); 37 | 38 | auto output = this->infer_request.get_output_tensor(0); 39 | const float *out_data = output.data(); 40 | 41 | ov::Shape output_shape = output.get_shape(); 42 | const size_t n2 = output_shape[2]; 43 | const size_t n3 = output_shape[3]; 44 | const int n = n2 * n3; 45 | 46 | std::vector pred(n, 0.0); 47 | std::vector cbuf(n, ' '); 48 | 49 | for (int i = 0; i < n; i++) { 50 | pred[i] = float(out_data[i]); 51 | cbuf[i] = (unsigned char)((out_data[i]) * 255); 52 | } 53 | 54 | cv::Mat cbuf_map(n2, n3, CV_8UC1, (unsigned char *)cbuf.data()); 55 | cv::Mat pred_map(n2, n3, CV_32F, (float *)pred.data()); 56 | 57 | const double threshold = this->det_db_thresh_ * 255; 58 | const double maxvalue = 255; 59 | cv::Mat bit_map; 60 | cv::threshold(cbuf_map, bit_map, threshold, maxvalue, cv::THRESH_BINARY); 61 | if (this->use_dilation_) { 62 | cv::Mat dila_ele = 63 | cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2, 2)); 64 | cv::dilate(bit_map, bit_map, dila_ele); 65 | } 66 | 67 | boxes = post_processor_.BoxesFromBitmap( 68 | pred_map, bit_map, this->det_db_box_thresh_, this->det_db_unclip_ratio_, 69 | this->det_db_score_mode_); 70 | 71 | boxes = post_processor_.FilterTagDetRes(boxes, this->ratio_h, this->ratio_w, this->src_img); 72 | for (int i = 0; i < boxes.size(); i++) { 73 | OCRPredictResult res; 74 | res.box = boxes[i]; 75 | ocr_results.push_back(res); 76 | } 77 | // sort boex from top to bottom, from left to right 78 | Utility::sorted_boxes(ocr_results); 79 | } 80 | } -------------------------------------------------------------------------------- /src/ocr_rec.cpp: -------------------------------------------------------------------------------- 1 | #include "include/ocr_rec.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Recognizer::Recognizer(string model_path, const string &label_path) { 6 | ov::Core core; 7 | this->model_path = model_path; 8 | this->model = core.read_model(this->model_path); 9 | // reshape the model for dynamic batch size and sentence width 10 | this->model->reshape({{ov::Dimension(1, 6), this->rec_image_shape_[0], this->rec_image_shape_[1], -1}}); 11 | this->compiled_model = core.compile_model(this->model, "CPU"); 12 | this->infer_request = this->compiled_model.create_infer_request(); 13 | this->label_list_ = Utility::ReadDict(label_path); 14 | this->label_list_.insert(this->label_list_.begin(), 15 | "#"); // blank char for ctc 16 | this->label_list_.push_back(" "); 17 | } 18 | 19 | void Recognizer::Run(std::vector img_list, std::vector &ocr_results) { 20 | std::vector rec_texts(img_list.size(), ""); 21 | std::vector rec_text_scores(img_list.size(), 0); 22 | int img_num = img_list.size(); 23 | std::vector width_list; 24 | for (int i = 0; i < img_num; i++) { 25 | width_list.push_back(float(img_list[i].cols) / img_list[i].rows); 26 | } 27 | std::vector indices = Utility::argsort(width_list); 28 | 29 | for (int beg_img_no = 0; beg_img_no < img_num; 30 | beg_img_no += this->rec_batch_num_) { 31 | int end_img_no = std::min(img_num, beg_img_no + this->rec_batch_num_); 32 | int batch_num = end_img_no - beg_img_no; 33 | int imgH = this->rec_image_shape_[1]; 34 | int imgW = this->rec_image_shape_[2]; 35 | float max_wh_ratio = imgW * 1.0 / imgH; 36 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 37 | int h = img_list[indices[ino]].rows; 38 | int w = img_list[indices[ino]].cols; 39 | float wh_ratio = w * 1.0 / h; 40 | max_wh_ratio = std::max(max_wh_ratio, wh_ratio); 41 | } 42 | 43 | int batch_width = imgW; 44 | std::vector norm_img_batch; 45 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 46 | cv::Mat srcimg; 47 | img_list[indices[ino]].copyTo(srcimg); 48 | cv::Mat resize_img; 49 | // preprocess 50 | this->resize_op_.Run(srcimg, resize_img, max_wh_ratio, this->rec_image_shape_); 51 | this->normalize_op_.Run(&resize_img, this->mean_, this->scale_, 52 | this->is_scale_); 53 | norm_img_batch.push_back(resize_img); 54 | batch_width = max(resize_img.cols, batch_width); 55 | } 56 | // prepare input tensor 57 | std::vector input(batch_num * 3 * imgH * batch_width, 0.0f); 58 | ov::Shape intput_shape = {batch_num, 3, imgH, batch_width}; 59 | this->permute_op_.Run(norm_img_batch, input.data()); 60 | auto input_port = this->compiled_model.input(); 61 | ov::Tensor input_tensor(input_port.get_element_type(), intput_shape, input.data()); 62 | this->infer_request.set_input_tensor(input_tensor); 63 | // start inference 64 | this->infer_request.infer(); 65 | 66 | auto output = this->infer_request.get_output_tensor(); 67 | const float *out_data = output.data(); 68 | auto predict_shape = output.get_shape(); 69 | 70 | // predict_batch is the result of Last FC with softmax 71 | for (int m = 0; m < predict_shape[0]; m++) { 72 | std::string str_res; 73 | int argmax_idx; 74 | int last_index = 0; 75 | float score = 0.f; 76 | int count = 0; 77 | float max_value = 0.0f; 78 | 79 | for (int n = 0; n < predict_shape[1]; n++) { 80 | // get idx 81 | argmax_idx = int(Utility::argmax( 82 | &out_data[(m * predict_shape[1] + n) * predict_shape[2]], 83 | &out_data[(m * predict_shape[1] + n + 1) * predict_shape[2]])); 84 | // get score 85 | max_value = float(*std::max_element( 86 | &out_data[(m * predict_shape[1] + n) * predict_shape[2]], 87 | &out_data[(m * predict_shape[1] + n + 1) * predict_shape[2]])); 88 | 89 | if (argmax_idx > 0 && (!(n > 0 && argmax_idx == last_index))) { 90 | score += max_value; 91 | count += 1; 92 | str_res += this->label_list_[argmax_idx]; 93 | } 94 | last_index = argmax_idx; 95 | } 96 | score /= count; 97 | if (std::isnan(score)) { 98 | continue; 99 | } 100 | rec_texts[indices[beg_img_no + m]] = str_res; 101 | rec_text_scores[indices[beg_img_no + m]] = score; 102 | } 103 | } 104 | // sort boex from top to bottom, from left to right 105 | for (int i = 0; i < rec_texts.size(); i++) { 106 | ocr_results[i].text = rec_texts[i]; 107 | ocr_results[i].score = rec_text_scores[i]; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /src/paddleocr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace PaddleOCR { 19 | 20 | PPOCR::PPOCR() { 21 | this->detector_ = new Detector(FLAGS_det_model_dir); 22 | if (!FLAGS_cls_model_dir.empty()) { 23 | this->classifier_ = new Classifier(FLAGS_cls_model_dir); 24 | } 25 | this->recognizer_ = new Recognizer(FLAGS_rec_model_dir, FLAGS_label_dir); 26 | }; 27 | 28 | std::vector PPOCR::ocr(cv::Mat img) { 29 | std::vector ocr_result; 30 | 31 | // detect the sentence in input image 32 | this->detector_->Run(img, ocr_result); 33 | // crop image 34 | std::vector img_list; 35 | for (int j = 0; j < ocr_result.size(); j++) { 36 | cv::Mat crop_img; 37 | crop_img = Utility::GetRotateCropImage(img, ocr_result[j].box); 38 | img_list.push_back(crop_img); 39 | } 40 | 41 | if (this->classifier_ != nullptr) { 42 | // find the reversed sentence and flip it 43 | this->classifier_->Run(img_list, ocr_result); 44 | for (int i = 0; i < img_list.size(); i++) { 45 | if (ocr_result[i].cls_label % 2 == 1 && 46 | ocr_result[i].cls_score > classifier_->cls_thresh) { 47 | cv::rotate(img_list[i], img_list[i], 1); 48 | } 49 | } 50 | } 51 | 52 | // recognize the words in sentence and print them 53 | this->recognizer_->Run(img_list, ocr_result); 54 | 55 | return ocr_result; 56 | } 57 | 58 | PPOCR::~PPOCR() { 59 | if (this->detector_ != nullptr) { 60 | delete this->detector_; 61 | } 62 | if (this->classifier_ != nullptr) { 63 | delete this->classifier_; 64 | } 65 | if (this->recognizer_ != nullptr) { 66 | delete this->recognizer_; 67 | } 68 | } 69 | } // namespace PaddleOCR 70 | -------------------------------------------------------------------------------- /src/paddlestructure.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace PaddleOCR { 19 | 20 | PaddleStructure::PaddleStructure() { 21 | this->layout_model_ = new Layout(FLAGS_lay_model_dir, FLAGS_layout_dict_dir); 22 | this->table_model_ = new Table(FLAGS_tab_model_dir, FLAGS_table_dict_dir); 23 | }; 24 | 25 | std::vector PaddleStructure::structure(cv::Mat src_img) { 26 | std::vector structure_results; 27 | 28 | this->layout_model_->Run(src_img, structure_results); 29 | cv::Mat roi_img; 30 | for (int i = 0; i < structure_results.size(); i++) { 31 | // crop image 32 | roi_img = Utility::crop_image(src_img, structure_results[i].box); 33 | if (structure_results[i].type == "table"){ 34 | std::vector> structure_html_tags; 35 | std::vector structure_scores(1, 0); 36 | std::vector>> structure_boxes; 37 | std::vector img_list; 38 | 39 | img_list.push_back(roi_img); 40 | this->table_model_->Run(img_list, structure_html_tags, structure_scores, structure_boxes); 41 | std::vector ocr_result; 42 | std::string html; 43 | int expand_pixel = 3; 44 | 45 | for (int j = 0; j < img_list.size(); j++) { 46 | this->detector_->Run(img_list[j], ocr_result); 47 | // crop image 48 | std::vector rec_img_list; 49 | std::vector ocr_box; 50 | for (int k = 0; k < ocr_result.size(); k++) { 51 | ocr_box = Utility::xyxyxyxy2xyxy(ocr_result[k].box); 52 | ocr_box[0] = std::max(0, ocr_box[0] - expand_pixel); 53 | ocr_box[1] = std::max(0, ocr_box[1] - expand_pixel), 54 | ocr_box[2] = std::min(img_list[j].cols, ocr_box[2] + expand_pixel); 55 | ocr_box[3] = std::min(img_list[j].rows, ocr_box[3] + expand_pixel); 56 | 57 | cv::Mat crop_img = Utility::crop_image(img_list[j], ocr_box); 58 | rec_img_list.push_back(crop_img); 59 | } 60 | // rec 61 | this->recognizer_->Run(rec_img_list, ocr_result); 62 | // rebuild table 63 | html = this->rebuild_table(structure_html_tags[j], structure_boxes[j], 64 | ocr_result); 65 | structure_results[i].html = html; 66 | structure_results[i].cell_box = structure_boxes[j]; 67 | structure_results[i].html_score = structure_scores[j]; 68 | } 69 | } 70 | else { 71 | structure_results[i].text_res = ocr(roi_img); 72 | } 73 | } 74 | return structure_results; 75 | }; 76 | 77 | std::string 78 | PaddleStructure::rebuild_table(std::vector structure_html_tags, 79 | std::vector> structure_boxes, 80 | std::vector &ocr_result) { 81 | // match text in same cell 82 | std::vector> matched(structure_boxes.size(), 83 | std::vector()); 84 | 85 | std::vector ocr_box; 86 | std::vector structure_box; 87 | for (int i = 0; i < ocr_result.size(); i++) { 88 | ocr_box = Utility::xyxyxyxy2xyxy(ocr_result[i].box); 89 | ocr_box[0] -= 1; 90 | ocr_box[1] -= 1; 91 | ocr_box[2] += 1; 92 | ocr_box[3] += 1; 93 | std::vector> dis_list(structure_boxes.size(), 94 | std::vector(3, 100000.0)); 95 | for (int j = 0; j < structure_boxes.size(); j++) { 96 | if (structure_boxes[i].size() == 8) { 97 | structure_box = Utility::xyxyxyxy2xyxy(structure_boxes[j]); 98 | } else { 99 | structure_box = structure_boxes[j]; 100 | } 101 | dis_list[j][0] = this->dis(ocr_box, structure_box); 102 | dis_list[j][1] = 1 - Utility::iou(ocr_box, structure_box); 103 | dis_list[j][2] = j; 104 | } 105 | // find min dis idx 106 | std::sort(dis_list.begin(), dis_list.end(), 107 | PaddleStructure::comparison_dis); 108 | matched[dis_list[0][2]].push_back(ocr_result[i].text); 109 | } 110 | 111 | // get pred html 112 | std::string html_str = ""; 113 | int td_tag_idx = 0; 114 | for (int i = 0; i < structure_html_tags.size(); i++) { 115 | if (structure_html_tags[i].find("") != std::string::npos) { 116 | if (structure_html_tags[i].find("") != std::string::npos) { 117 | html_str += ""; 118 | } 119 | if (matched[td_tag_idx].size() > 0) { 120 | bool b_with = false; 121 | if (matched[td_tag_idx][0].find("") != std::string::npos && 122 | matched[td_tag_idx].size() > 1) { 123 | b_with = true; 124 | html_str += ""; 125 | } 126 | for (int j = 0; j < matched[td_tag_idx].size(); j++) { 127 | std::string content = matched[td_tag_idx][j]; 128 | if (matched[td_tag_idx].size() > 1) { 129 | // remove blank, and 130 | if (content.length() > 0 && content.at(0) == ' ') { 131 | content = content.substr(0); 132 | } 133 | if (content.length() > 2 && content.substr(0, 3) == "") { 134 | content = content.substr(3); 135 | } 136 | if (content.length() > 4 && 137 | content.substr(content.length() - 4) == "") { 138 | content = content.substr(0, content.length() - 4); 139 | } 140 | if (content.empty()) { 141 | continue; 142 | } 143 | // add blank 144 | if (j != matched[td_tag_idx].size() - 1 && 145 | content.at(content.length() - 1) != ' ') { 146 | content += ' '; 147 | } 148 | } 149 | html_str += content; 150 | } 151 | if (b_with) { 152 | html_str += ""; 153 | } 154 | } 155 | if (structure_html_tags[i].find("") != std::string::npos) { 156 | html_str += ""; 157 | } else { 158 | html_str += structure_html_tags[i]; 159 | } 160 | td_tag_idx += 1; 161 | } else { 162 | html_str += structure_html_tags[i]; 163 | } 164 | } 165 | return html_str; 166 | } 167 | 168 | float PaddleStructure::dis(std::vector &box1, std::vector &box2) { 169 | int x1_1 = box1[0]; 170 | int y1_1 = box1[1]; 171 | int x2_1 = box1[2]; 172 | int y2_1 = box1[3]; 173 | 174 | int x1_2 = box2[0]; 175 | int y1_2 = box2[1]; 176 | int x2_2 = box2[2]; 177 | int y2_2 = box2[3]; 178 | 179 | float dis = 180 | abs(x1_2 - x1_1) + abs(y1_2 - y1_1) + abs(x2_2 - x2_1) + abs(y2_2 - y2_1); 181 | float dis_2 = abs(x1_2 - x1_1) + abs(y1_2 - y1_1); 182 | float dis_3 = abs(x2_2 - x2_1) + abs(y2_2 - y2_1); 183 | return dis + std::min(dis_2, dis_3); 184 | } 185 | 186 | PaddleStructure::~PaddleStructure() { 187 | if (this->layout_model_ != nullptr) { 188 | delete this->layout_model_; 189 | } 190 | if (this->table_model_ != nullptr) { 191 | delete this->table_model_; 192 | } 193 | }; 194 | } // namespace PaddleOCR -------------------------------------------------------------------------------- /src/postprocess_op.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace PaddleOCR { 18 | 19 | void DBPostProcessor::GetContourArea(const std::vector> &box, 20 | float unclip_ratio, float &distance) { 21 | int pts_num = 4; 22 | float area = 0.0f; 23 | float dist = 0.0f; 24 | for (int i = 0; i < pts_num; i++) { 25 | area += box[i][0] * box[(i + 1) % pts_num][1] - 26 | box[i][1] * box[(i + 1) % pts_num][0]; 27 | dist += sqrtf((box[i][0] - box[(i + 1) % pts_num][0]) * 28 | (box[i][0] - box[(i + 1) % pts_num][0]) + 29 | (box[i][1] - box[(i + 1) % pts_num][1]) * 30 | (box[i][1] - box[(i + 1) % pts_num][1])); 31 | } 32 | area = fabs(float(area / 2.0)); 33 | 34 | distance = area * unclip_ratio / dist; 35 | } 36 | 37 | cv::RotatedRect DBPostProcessor::UnClip(std::vector> box, 38 | const float &unclip_ratio) { 39 | float distance = 1.0; 40 | 41 | GetContourArea(box, unclip_ratio, distance); 42 | 43 | ClipperLib::ClipperOffset offset; 44 | ClipperLib::Path p; 45 | p << ClipperLib::IntPoint(int(box[0][0]), int(box[0][1])) 46 | << ClipperLib::IntPoint(int(box[1][0]), int(box[1][1])) 47 | << ClipperLib::IntPoint(int(box[2][0]), int(box[2][1])) 48 | << ClipperLib::IntPoint(int(box[3][0]), int(box[3][1])); 49 | offset.AddPath(p, ClipperLib::jtRound, ClipperLib::etClosedPolygon); 50 | 51 | ClipperLib::Paths soln; 52 | offset.Execute(soln, distance); 53 | std::vector points; 54 | 55 | for (int j = 0; j < soln.size(); j++) { 56 | for (int i = 0; i < soln[soln.size() - 1].size(); i++) { 57 | points.emplace_back(soln[j][i].X, soln[j][i].Y); 58 | } 59 | } 60 | cv::RotatedRect res; 61 | if (points.size() <= 0) { 62 | res = cv::RotatedRect(cv::Point2f(0, 0), cv::Size2f(1, 1), 0); 63 | } else { 64 | res = cv::minAreaRect(points); 65 | } 66 | return res; 67 | } 68 | 69 | float **DBPostProcessor::Mat2Vec(cv::Mat mat) { 70 | auto **array = new float *[mat.rows]; 71 | for (int i = 0; i < mat.rows; ++i) 72 | array[i] = new float[mat.cols]; 73 | for (int i = 0; i < mat.rows; ++i) { 74 | for (int j = 0; j < mat.cols; ++j) { 75 | array[i][j] = mat.at(i, j); 76 | } 77 | } 78 | 79 | return array; 80 | } 81 | 82 | std::vector> 83 | DBPostProcessor::OrderPointsClockwise(std::vector> pts) { 84 | std::vector> box = pts; 85 | std::sort(box.begin(), box.end(), XsortInt); 86 | 87 | std::vector> leftmost = {box[0], box[1]}; 88 | std::vector> rightmost = {box[2], box[3]}; 89 | 90 | if (leftmost[0][1] > leftmost[1][1]) 91 | std::swap(leftmost[0], leftmost[1]); 92 | 93 | if (rightmost[0][1] > rightmost[1][1]) 94 | std::swap(rightmost[0], rightmost[1]); 95 | 96 | std::vector> rect = {leftmost[0], rightmost[0], rightmost[1], 97 | leftmost[1]}; 98 | return rect; 99 | } 100 | 101 | std::vector> DBPostProcessor::Mat2Vector(cv::Mat mat) { 102 | std::vector> img_vec; 103 | std::vector tmp; 104 | 105 | for (int i = 0; i < mat.rows; ++i) { 106 | tmp.clear(); 107 | for (int j = 0; j < mat.cols; ++j) { 108 | tmp.push_back(mat.at(i, j)); 109 | } 110 | img_vec.push_back(tmp); 111 | } 112 | return img_vec; 113 | } 114 | 115 | bool DBPostProcessor::XsortFp32(std::vector a, std::vector b) { 116 | if (a[0] != b[0]) 117 | return a[0] < b[0]; 118 | return false; 119 | } 120 | 121 | bool DBPostProcessor::XsortInt(std::vector a, std::vector b) { 122 | if (a[0] != b[0]) 123 | return a[0] < b[0]; 124 | return false; 125 | } 126 | 127 | std::vector> 128 | DBPostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) { 129 | ssid = std::max(box.size.width, box.size.height); 130 | 131 | cv::Mat points; 132 | cv::boxPoints(box, points); 133 | 134 | auto array = Mat2Vector(points); 135 | std::sort(array.begin(), array.end(), XsortFp32); 136 | 137 | std::vector idx1 = array[0], idx2 = array[1], idx3 = array[2], 138 | idx4 = array[3]; 139 | if (array[3][1] <= array[2][1]) { 140 | idx2 = array[3]; 141 | idx3 = array[2]; 142 | } else { 143 | idx2 = array[2]; 144 | idx3 = array[3]; 145 | } 146 | if (array[1][1] <= array[0][1]) { 147 | idx1 = array[1]; 148 | idx4 = array[0]; 149 | } else { 150 | idx1 = array[0]; 151 | idx4 = array[1]; 152 | } 153 | 154 | array[0] = idx1; 155 | array[1] = idx2; 156 | array[2] = idx3; 157 | array[3] = idx4; 158 | 159 | return array; 160 | } 161 | 162 | float DBPostProcessor::PolygonScoreAcc(std::vector contour, 163 | cv::Mat pred) { 164 | int width = pred.cols; 165 | int height = pred.rows; 166 | std::vector box_x; 167 | std::vector box_y; 168 | for (int i = 0; i < contour.size(); ++i) { 169 | box_x.push_back(contour[i].x); 170 | box_y.push_back(contour[i].y); 171 | } 172 | 173 | int xmin = 174 | clamp(int(std::floor(*(std::min_element(box_x.begin(), box_x.end())))), 0, 175 | width - 1); 176 | int xmax = 177 | clamp(int(std::ceil(*(std::max_element(box_x.begin(), box_x.end())))), 0, 178 | width - 1); 179 | int ymin = 180 | clamp(int(std::floor(*(std::min_element(box_y.begin(), box_y.end())))), 0, 181 | height - 1); 182 | int ymax = 183 | clamp(int(std::ceil(*(std::max_element(box_y.begin(), box_y.end())))), 0, 184 | height - 1); 185 | 186 | cv::Mat mask; 187 | mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1); 188 | 189 | cv::Point *rook_point = new cv::Point[contour.size()]; 190 | 191 | for (int i = 0; i < contour.size(); ++i) { 192 | rook_point[i] = cv::Point(int(box_x[i]) - xmin, int(box_y[i]) - ymin); 193 | } 194 | const cv::Point *ppt[1] = {rook_point}; 195 | int npt[] = {int(contour.size())}; 196 | 197 | cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1)); 198 | 199 | cv::Mat croppedImg; 200 | pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) 201 | .copyTo(croppedImg); 202 | float score = cv::mean(croppedImg, mask)[0]; 203 | 204 | delete[] rook_point; 205 | return score; 206 | } 207 | 208 | float DBPostProcessor::BoxScoreFast(std::vector> box_array, 209 | cv::Mat pred) { 210 | auto array = box_array; 211 | int width = pred.cols; 212 | int height = pred.rows; 213 | 214 | float box_x[4] = {array[0][0], array[1][0], array[2][0], array[3][0]}; 215 | float box_y[4] = {array[0][1], array[1][1], array[2][1], array[3][1]}; 216 | 217 | int xmin = clamp(int(std::floor(*(std::min_element(box_x, box_x + 4)))), 0, 218 | width - 1); 219 | int xmax = clamp(int(std::ceil(*(std::max_element(box_x, box_x + 4)))), 0, 220 | width - 1); 221 | int ymin = clamp(int(std::floor(*(std::min_element(box_y, box_y + 4)))), 0, 222 | height - 1); 223 | int ymax = clamp(int(std::ceil(*(std::max_element(box_y, box_y + 4)))), 0, 224 | height - 1); 225 | 226 | cv::Mat mask; 227 | mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1); 228 | 229 | cv::Point root_point[4]; 230 | root_point[0] = cv::Point(int(array[0][0]) - xmin, int(array[0][1]) - ymin); 231 | root_point[1] = cv::Point(int(array[1][0]) - xmin, int(array[1][1]) - ymin); 232 | root_point[2] = cv::Point(int(array[2][0]) - xmin, int(array[2][1]) - ymin); 233 | root_point[3] = cv::Point(int(array[3][0]) - xmin, int(array[3][1]) - ymin); 234 | const cv::Point *ppt[1] = {root_point}; 235 | int npt[] = {4}; 236 | cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1)); 237 | 238 | cv::Mat croppedImg; 239 | pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) 240 | .copyTo(croppedImg); 241 | 242 | auto score = cv::mean(croppedImg, mask)[0]; 243 | return score; 244 | } 245 | 246 | std::vector>> DBPostProcessor::BoxesFromBitmap( 247 | const cv::Mat pred, const cv::Mat bitmap, const float &box_thresh, 248 | const float &det_db_unclip_ratio, const std::string &det_db_score_mode) { 249 | const int min_size = 3; 250 | const int max_candidates = 1000; 251 | 252 | int width = bitmap.cols; 253 | int height = bitmap.rows; 254 | 255 | std::vector> contours; 256 | std::vector hierarchy; 257 | 258 | cv::findContours(bitmap, contours, hierarchy, cv::RETR_LIST, 259 | cv::CHAIN_APPROX_SIMPLE); 260 | 261 | int num_contours = 262 | contours.size() >= max_candidates ? max_candidates : contours.size(); 263 | 264 | std::vector>> boxes; 265 | 266 | for (int _i = 0; _i < num_contours; _i++) { 267 | if (contours[_i].size() <= 2) { 268 | continue; 269 | } 270 | float ssid; 271 | cv::RotatedRect box = cv::minAreaRect(contours[_i]); 272 | auto array = GetMiniBoxes(box, ssid); 273 | 274 | auto box_for_unclip = array; 275 | // end get_mini_box 276 | 277 | if (ssid < min_size) { 278 | continue; 279 | } 280 | 281 | float score; 282 | if (det_db_score_mode == "slow") 283 | /* compute using polygon*/ 284 | score = PolygonScoreAcc(contours[_i], pred); 285 | else 286 | score = BoxScoreFast(array, pred); 287 | 288 | if (score < box_thresh) 289 | continue; 290 | 291 | // start for unclip 292 | cv::RotatedRect points = UnClip(box_for_unclip, det_db_unclip_ratio); 293 | if (points.size.height < 1.001 && points.size.width < 1.001) { 294 | continue; 295 | } 296 | // end for unclip 297 | 298 | cv::RotatedRect clipbox = points; 299 | auto cliparray = GetMiniBoxes(clipbox, ssid); 300 | 301 | if (ssid < min_size + 2) 302 | continue; 303 | 304 | int dest_width = pred.cols; 305 | int dest_height = pred.rows; 306 | std::vector> intcliparray; 307 | 308 | for (int num_pt = 0; num_pt < 4; num_pt++) { 309 | std::vector a{int(clampf(roundf(cliparray[num_pt][0] / float(width) * 310 | float(dest_width)), 311 | 0, float(dest_width))), 312 | int(clampf(roundf(cliparray[num_pt][1] / 313 | float(height) * float(dest_height)), 314 | 0, float(dest_height)))}; 315 | intcliparray.push_back(a); 316 | } 317 | boxes.push_back(intcliparray); 318 | 319 | } // end for 320 | return boxes; 321 | } 322 | 323 | std::vector>> DBPostProcessor::FilterTagDetRes( 324 | std::vector>> boxes, float ratio_h, 325 | float ratio_w, cv::Mat srcimg) { 326 | int oriimg_h = srcimg.rows; 327 | int oriimg_w = srcimg.cols; 328 | 329 | std::vector>> root_points; 330 | for (int n = 0; n < boxes.size(); n++) { 331 | boxes[n] = OrderPointsClockwise(boxes[n]); 332 | for (int m = 0; m < boxes[0].size(); m++) { 333 | boxes[n][m][0] /= ratio_w; 334 | boxes[n][m][1] /= ratio_h; 335 | 336 | boxes[n][m][0] = int(_min(_max(boxes[n][m][0], 0), oriimg_w - 1)); 337 | boxes[n][m][1] = int(_min(_max(boxes[n][m][1], 0), oriimg_h - 1)); 338 | } 339 | } 340 | 341 | for (int n = 0; n < boxes.size(); n++) { 342 | int rect_width, rect_height; 343 | rect_width = int(sqrt(pow(boxes[n][0][0] - boxes[n][1][0], 2) + 344 | pow(boxes[n][0][1] - boxes[n][1][1], 2))); 345 | rect_height = int(sqrt(pow(boxes[n][0][0] - boxes[n][3][0], 2) + 346 | pow(boxes[n][0][1] - boxes[n][3][1], 2))); 347 | if (rect_width <= 4 || rect_height <= 4) 348 | continue; 349 | root_points.push_back(boxes[n]); 350 | } 351 | return root_points; 352 | } 353 | 354 | void TablePostProcessor::init(std::string label_path, 355 | bool merge_no_span_structure) { 356 | this->label_list_ = Utility::ReadDict(label_path); 357 | if (merge_no_span_structure) { 358 | this->label_list_.push_back(""); 359 | std::vector::iterator it; 360 | for (it = this->label_list_.begin(); it != this->label_list_.end();) { 361 | if (*it == "") { 362 | it = this->label_list_.erase(it); 363 | } else { 364 | ++it; 365 | } 366 | } 367 | } 368 | // add_special_char 369 | this->label_list_.insert(this->label_list_.begin(), this->beg); 370 | this->label_list_.push_back(this->end); 371 | } 372 | 373 | void TablePostProcessor::Run( 374 | std::vector &loc_preds, std::vector &structure_probs, 375 | std::vector &rec_scores, ov::Shape &loc_preds_shape, 376 | ov::Shape &structure_probs_shape, 377 | std::vector> &rec_html_tag_batch, 378 | std::vector>> &rec_boxes_batch, 379 | std::vector &width_list, std::vector &height_list) { 380 | for (int batch_idx = 0; batch_idx < structure_probs_shape[0]; batch_idx++) { 381 | // image tags and boxs 382 | std::vector rec_html_tags; 383 | std::vector> rec_boxes; 384 | 385 | float score = 0.f; 386 | int count = 0; 387 | float char_score = 0.f; 388 | int char_idx = 0; 389 | 390 | // step 391 | for (int step_idx = 0; step_idx < structure_probs_shape[1]; step_idx++) { 392 | std::string html_tag; 393 | std::vector rec_box; 394 | // html tag 395 | int step_start_idx = (batch_idx * structure_probs_shape[1] + step_idx) * 396 | structure_probs_shape[2]; 397 | char_idx = int(Utility::argmax( 398 | &structure_probs[step_start_idx], 399 | &structure_probs[step_start_idx + structure_probs_shape[2]])); 400 | char_score = float(*std::max_element( 401 | &structure_probs[step_start_idx], 402 | &structure_probs[step_start_idx + structure_probs_shape[2]])); 403 | html_tag = this->label_list_[char_idx]; 404 | 405 | if (step_idx > 0 && html_tag == this->end) { 406 | break; 407 | } 408 | if (html_tag == this->beg) { 409 | continue; 410 | } 411 | count += 1; 412 | score += char_score; 413 | rec_html_tags.push_back(html_tag); 414 | 415 | // box 416 | if (html_tag == "" || html_tag == "") { 417 | for (int point_idx = 0; point_idx < loc_preds_shape[2]; point_idx++) { 418 | step_start_idx = (batch_idx * structure_probs_shape[1] + step_idx) * 419 | loc_preds_shape[2] + 420 | point_idx; 421 | float point = loc_preds[step_start_idx]; 422 | if (point_idx % 2 == 0) { 423 | point = int(point * width_list[batch_idx]); 424 | } else { 425 | point = int(point * height_list[batch_idx]); 426 | } 427 | rec_box.push_back(point); 428 | } 429 | rec_boxes.push_back(rec_box); 430 | } 431 | } 432 | score /= count; 433 | if (std::isnan(score) || rec_boxes.size() == 0) { 434 | score = -1; 435 | } 436 | rec_scores.push_back(score); 437 | rec_boxes_batch.push_back(rec_boxes); 438 | rec_html_tag_batch.push_back(rec_html_tags); 439 | } 440 | } 441 | 442 | void PicodetPostProcessor::init(std::string label_path, 443 | const double score_threshold, 444 | const double nms_threshold, 445 | const std::vector &fpn_stride) { 446 | this->label_list_ = Utility::ReadDict(label_path); 447 | this->score_threshold_ = score_threshold; 448 | this->nms_threshold_ = nms_threshold; 449 | this->num_class_ = label_list_.size(); 450 | this->fpn_stride_ = fpn_stride; 451 | } 452 | 453 | void PicodetPostProcessor::Run(std::vector &results, 454 | std::vector> outs, 455 | std::vector ori_shape, 456 | std::vector resize_shape, int reg_max) { 457 | int in_h = resize_shape[0]; 458 | int in_w = resize_shape[1]; 459 | float scale_factor_h = resize_shape[0] / float(ori_shape[0]); 460 | float scale_factor_w = resize_shape[1] / float(ori_shape[1]); 461 | 462 | std::vector> bbox_results; 463 | bbox_results.resize(this->num_class_); 464 | for (int i = 0; i < this->fpn_stride_.size(); ++i) { 465 | int feature_h = std::ceil((float)in_h / this->fpn_stride_[i]); 466 | int feature_w = std::ceil((float)in_w / this->fpn_stride_[i]); 467 | for (int idx = 0; idx < feature_h * feature_w; idx++) { 468 | // score and label 469 | float score = 0; 470 | int cur_label = 0; 471 | for (int label = 0; label < this->num_class_; label++) { 472 | if (outs[i][idx * this->num_class_ + label] > score) { 473 | score = outs[i][idx * this->num_class_ + label]; 474 | cur_label = label; 475 | } 476 | } 477 | // bbox 478 | if (score > this->score_threshold_) { 479 | int row = idx / feature_w; 480 | int col = idx % feature_w; 481 | std::vector bbox_pred( 482 | outs[i + this->fpn_stride_.size()].begin() + idx * 4 * reg_max, 483 | outs[i + this->fpn_stride_.size()].begin() + 484 | (idx + 1) * 4 * reg_max); 485 | bbox_results[cur_label].push_back( 486 | this->disPred2Bbox(bbox_pred, cur_label, score, col, row, 487 | this->fpn_stride_[i], resize_shape, reg_max)); 488 | } 489 | } 490 | } 491 | for (int i = 0; i < bbox_results.size(); i++) { 492 | bool flag = bbox_results[i].size() <= 0; 493 | } 494 | for (int i = 0; i < bbox_results.size(); i++) { 495 | bool flag = bbox_results[i].size() <= 0; 496 | if (bbox_results[i].size() <= 0) { 497 | continue; 498 | } 499 | this->nms(bbox_results[i], this->nms_threshold_); 500 | for (auto box : bbox_results[i]) { 501 | box.box[0] = box.box[0] / scale_factor_w; 502 | box.box[2] = box.box[2] / scale_factor_w; 503 | box.box[1] = box.box[1] / scale_factor_h; 504 | box.box[3] = box.box[3] / scale_factor_h; 505 | results.push_back(box); 506 | } 507 | } 508 | } 509 | 510 | StructurePredictResult 511 | PicodetPostProcessor::disPred2Bbox(std::vector bbox_pred, int label, 512 | float score, int x, int y, int stride, 513 | std::vector im_shape, int reg_max) { 514 | float ct_x = (x + 0.5) * stride; 515 | float ct_y = (y + 0.5) * stride; 516 | std::vector dis_pred; 517 | dis_pred.resize(4); 518 | for (int i = 0; i < 4; i++) { 519 | float dis = 0; 520 | std::vector bbox_pred_i(bbox_pred.begin() + i * reg_max, 521 | bbox_pred.begin() + (i + 1) * reg_max); 522 | std::vector dis_after_sm = 523 | Utility::activation_function_softmax(bbox_pred_i); 524 | for (int j = 0; j < reg_max; j++) { 525 | dis += j * dis_after_sm[j]; 526 | } 527 | dis *= stride; 528 | dis_pred[i] = dis; 529 | } 530 | 531 | float xmin = (std::max)(ct_x - dis_pred[0], .0f); 532 | float ymin = (std::max)(ct_y - dis_pred[1], .0f); 533 | float xmax = (std::min)(ct_x + dis_pred[2], (float)im_shape[1]); 534 | float ymax = (std::min)(ct_y + dis_pred[3], (float)im_shape[0]); 535 | 536 | StructurePredictResult result_item; 537 | result_item.box = {xmin, ymin, xmax, ymax}; 538 | result_item.type = this->label_list_[label]; 539 | result_item.confidence = score; 540 | 541 | return result_item; 542 | } 543 | 544 | void PicodetPostProcessor::nms(std::vector &input_boxes, 545 | float nms_threshold) { 546 | std::sort(input_boxes.begin(), input_boxes.end(), 547 | [](StructurePredictResult a, StructurePredictResult b) { 548 | return a.confidence > b.confidence; 549 | }); 550 | std::vector picked(input_boxes.size(), 1); 551 | 552 | for (int i = 0; i < input_boxes.size(); ++i) { 553 | if (picked[i] == 0) { 554 | continue; 555 | } 556 | for (int j = i + 1; j < input_boxes.size(); ++j) { 557 | if (picked[j] == 0) { 558 | continue; 559 | } 560 | float iou = Utility::iou(input_boxes[i].box, input_boxes[j].box); 561 | if (iou > nms_threshold) { 562 | picked[j] = 0; 563 | } 564 | } 565 | } 566 | std::vector input_boxes_nms; 567 | for (int i = 0; i < input_boxes.size(); ++i) { 568 | if (picked[i] == 1) { 569 | input_boxes_nms.push_back(input_boxes[i]); 570 | } 571 | } 572 | input_boxes = input_boxes_nms; 573 | } 574 | 575 | } // namespace PaddleOCR 576 | -------------------------------------------------------------------------------- /src/preprocess_op.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace PaddleOCR { 18 | 19 | void Permute::Run(const cv::Mat *im, float *data) { 20 | int rh = im->rows; 21 | int rw = im->cols; 22 | int rc = im->channels(); 23 | for (int i = 0; i < rc; ++i) { 24 | cv::extractChannel(*im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i); 25 | } 26 | } 27 | 28 | void PermuteBatch::Run(const std::vector imgs, float *data) { 29 | for (int j = 0; j < imgs.size(); j++) { 30 | int rh = imgs[j].rows; 31 | int rw = imgs[j].cols; 32 | int rc = imgs[j].channels(); 33 | for (int i = 0; i < rc; ++i) { 34 | cv::extractChannel( 35 | imgs[j], cv::Mat(rh, rw, CV_32FC1, data + (j * rc + i) * rh * rw), i); 36 | } 37 | } 38 | } 39 | 40 | void Normalize::Run(cv::Mat *im, const std::vector &mean, 41 | const std::vector &scale, const bool is_scale) { 42 | double e = 1.0; 43 | if (is_scale) { 44 | e /= 255.0; 45 | } 46 | (*im).convertTo(*im, CV_32FC3, e); 47 | std::vector bgr_channels(3); 48 | cv::split(*im, bgr_channels); 49 | for (auto i = 0; i < bgr_channels.size(); i++) { 50 | bgr_channels[i].convertTo(bgr_channels[i], CV_32FC1, 1.0 * scale[i], 51 | (0.0 - mean[i]) * scale[i]); 52 | } 53 | cv::merge(bgr_channels, *im); 54 | } 55 | 56 | void ResizeImgType0::Run(const cv::Mat &img, cv::Mat &resize_img, 57 | std::string limit_type, int limit_side_len, 58 | float &ratio_h, float &ratio_w) { 59 | int w = img.cols; 60 | int h = img.rows; 61 | float ratio = 1.f; 62 | if (limit_type == "min") { 63 | int min_wh = std::min(h, w); 64 | if (min_wh < limit_side_len) { 65 | if (h < w) { 66 | ratio = float(limit_side_len) / float(h); 67 | } else { 68 | ratio = float(limit_side_len) / float(w); 69 | } 70 | } 71 | } else { 72 | int max_wh = std::max(h, w); 73 | if (max_wh > limit_side_len) { 74 | if (h > w) { 75 | ratio = float(limit_side_len) / float(h); 76 | } else { 77 | ratio = float(limit_side_len) / float(w); 78 | } 79 | } 80 | } 81 | 82 | int resize_h = int(float(h) * ratio); 83 | int resize_w = int(float(w) * ratio); 84 | 85 | resize_h = std::max(int(round(float(resize_h) / 32) * 32), 32); 86 | resize_w = std::max(int(round(float(resize_w) / 32) * 32), 32); 87 | 88 | cv::resize(img, resize_img, cv::Size(resize_w, resize_h)); 89 | ratio_h = float(resize_h) / float(h); 90 | ratio_w = float(resize_w) / float(w); 91 | } 92 | 93 | void CrnnResizeImg::Run(const cv::Mat &img, cv::Mat &resize_img, float wh_ratio, 94 | const std::vector &rec_image_shape) { 95 | int imgC, imgH, imgW; 96 | imgC = rec_image_shape[0]; 97 | imgH = rec_image_shape[1]; 98 | imgW = rec_image_shape[2]; 99 | 100 | imgW = int(imgH * wh_ratio); 101 | 102 | float ratio = float(img.cols) / float(img.rows); 103 | int resize_w, resize_h; 104 | 105 | if (ceilf(imgH * ratio) > imgW) 106 | resize_w = imgW; 107 | else 108 | resize_w = int(ceilf(imgH * ratio)); 109 | 110 | cv::resize(img, resize_img, cv::Size(resize_w, imgH), 0.f, 0.f, 111 | cv::INTER_LINEAR); 112 | cv::copyMakeBorder(resize_img, resize_img, 0, 0, 0, 113 | int(imgW - resize_img.cols), cv::BORDER_CONSTANT, 114 | {127, 127, 127}); 115 | } 116 | 117 | void ClsResizeImg::Run(const cv::Mat &img, cv::Mat &resize_img, 118 | const std::vector &rec_image_shape) { 119 | int imgC, imgH, imgW; 120 | imgC = rec_image_shape[0]; 121 | imgH = rec_image_shape[1]; 122 | imgW = rec_image_shape[2]; 123 | 124 | float ratio = float(img.cols) / float(img.rows); 125 | int resize_w, resize_h; 126 | if (ceilf(imgH * ratio) > imgW) 127 | resize_w = imgW; 128 | else 129 | resize_w = int(ceilf(imgH * ratio)); 130 | 131 | cv::resize(img, resize_img, cv::Size(resize_w, imgH), 0.f, 0.f, 132 | cv::INTER_LINEAR); 133 | } 134 | 135 | void TableResizeImg::Run(const cv::Mat &img, cv::Mat &resize_img, 136 | const int max_len) { 137 | int w = img.cols; 138 | int h = img.rows; 139 | 140 | int max_wh = w >= h ? w : h; 141 | float ratio = w >= h ? float(max_len) / float(w) : float(max_len) / float(h); 142 | 143 | int resize_h = int(float(h) * ratio); 144 | int resize_w = int(float(w) * ratio); 145 | 146 | cv::resize(img, resize_img, cv::Size(resize_w, resize_h)); 147 | } 148 | 149 | void TablePadImg::Run(const cv::Mat &img, cv::Mat &resize_img, 150 | const int max_len) { 151 | int w = img.cols; 152 | int h = img.rows; 153 | cv::copyMakeBorder(img, resize_img, 0, max_len - h, 0, max_len - w, 154 | cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0)); 155 | } 156 | 157 | void Resize::Run(const cv::Mat &img, cv::Mat &resize_img, const int h, 158 | const int w) { 159 | cv::resize(img, resize_img, cv::Size(w, h)); 160 | } 161 | 162 | } // namespace PaddleOCR 163 | -------------------------------------------------------------------------------- /src/rec.bak: -------------------------------------------------------------------------------- 1 | #include "include/rec.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Rec::Rec() {} 6 | 7 | Rec::~Rec() {} 8 | 9 | bool Rec::init(string model_path, const string &label_path) 10 | { 11 | this->model_path = model_path; 12 | this->model = this->core.read_model(this->model_path); 13 | // -------- Step 3. Preprocessing API-------- 14 | ov::preprocess::PrePostProcessor prep(this->model); 15 | // Declare section of desired application's input format 16 | prep.input().tensor() 17 | .set_layout("NHWC") 18 | .set_color_format(ov::preprocess::ColorFormat::BGR); 19 | // Specify actual model layout 20 | prep.input().model() 21 | .set_layout("NCHW"); 22 | prep.input().preprocess() 23 | .mean({0.5f, 0.5f, 0.5f}) 24 | .scale({0.5f, 0.5f, 0.5f}); 25 | // Dump preprocessor 26 | std::cout << "Preprocessor: " << prep << std::endl; 27 | this->model = prep.build(); 28 | this->label_list_ = Utility::ReadDict(label_path); 29 | this->label_list_.insert(this->label_list_.begin(), 30 | "#"); // blank char for ctc 31 | this->label_list_.push_back(" "); 32 | 33 | return true; 34 | } 35 | 36 | bool Rec::run(std::vector img_list, std::vector &ocr_results) 37 | { 38 | std::vector rec_texts(img_list.size(), ""); 39 | std::vector rec_text_scores(img_list.size(), 0); 40 | 41 | int img_num = img_list.size(); 42 | std::vector width_list; 43 | for (int i = 0; i < img_num; i++) { 44 | width_list.push_back(float(img_list[i].cols) / img_list[i].rows); 45 | } 46 | std::vector indices = Utility::argsort(width_list); 47 | 48 | 49 | 50 | for (int beg_img_no = 0; beg_img_no < img_num; 51 | beg_img_no += this->rec_batch_num_) { 52 | int end_img_no = std::min(img_num, beg_img_no + this->rec_batch_num_); 53 | int batch_num = end_img_no - beg_img_no; 54 | int imgH = this->rec_image_shape_[1]; 55 | int imgW = this->rec_image_shape_[2]; 56 | float max_wh_ratio = imgW * 1.0 / imgH; 57 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 58 | int h = img_list[indices[ino]].rows; 59 | int w = img_list[indices[ino]].cols; 60 | float wh_ratio = w * 1.0 / h; 61 | max_wh_ratio = std::max(max_wh_ratio, wh_ratio); 62 | } 63 | 64 | std::vector img_batch; 65 | std::vector batch_tensors; 66 | 67 | int batch_width = imgW; 68 | std::vector norm_img_batch; 69 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 70 | cv::Mat srcimg; 71 | img_list[indices[ino]].copyTo(srcimg); 72 | cv::Mat resize_img; 73 | this->resize_op_.Run(srcimg, resize_img, max_wh_ratio, this->rec_image_shape_); 74 | double e = 1.0; 75 | e /= 255.0; 76 | resize_img.convertTo(resize_img, CV_32FC3, e); 77 | 78 | norm_img_batch.push_back(resize_img); 79 | 80 | // auto input_tensor = ov::Tensor(this->model->input().get_element_type(), {1, imgH, resize_img.cols, 3}); 81 | // auto input_data = input_tensor.data(); 82 | // input_data = (float*)resize_img.data; 83 | // batch_tensors.push_back(input_tensor); 84 | batch_width = max(resize_img.cols, batch_width); 85 | } 86 | 87 | 88 | 89 | // for (int batch = 0; batch < batch_num; batch++) 90 | // { 91 | // for (int h = 0; h < imgH; h++) 92 | // { 93 | // for (int w = 0; w < batch_width; w++) 94 | // { 95 | // for (int c = 0; c < 3; c++) 96 | // { 97 | // int index = c + 3*w + 3*batch_width*h + 3*batch_width*imgH*batch; 98 | // data[index] = float(norm_img_batch[batch].at(h, w)[c]); 99 | // } 100 | // } 101 | // } 102 | // } 103 | this->model->reshape({batch_num, imgH, batch_width,3}); 104 | // float data[batch_num * 3 * imgH * batch_width]; 105 | 106 | 107 | 108 | this->rec_model = this->core.compile_model(this->model, "CPU"); 109 | this->infer_request = this->rec_model.create_infer_request(); 110 | auto input_port = this->rec_model.input(); 111 | ov::Tensor input_tensor = this->infer_request.get_input_tensor(); 112 | 113 | const size_t batch_size = norm_img_batch.size(); 114 | 115 | for (size_t image_id = 0; image_id < norm_img_batch.size(); ++image_id) { 116 | const size_t image_size = ov::shape_size(this->model->input().get_shape()) / batch_size; 117 | std::memcpy(input_tensor.data() + image_id * image_size, (float*)norm_img_batch[image_id].data, image_size*sizeof(float)); 118 | } 119 | // ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), data); 120 | // this->infer_request.set_input_tensor(input_tensor); 121 | // -------- Step 7. Start inference -------- 122 | this->infer_request.infer(); 123 | 124 | auto output = this->infer_request.get_output_tensor(); 125 | const float *out_data = output.data(); 126 | 127 | auto predict_shape = output.get_shape(); 128 | 129 | 130 | // predict_batch is the result of Last FC with softmax 131 | for (int m = 0; m < predict_shape[0]; m++) { 132 | std::string str_res; 133 | int argmax_idx; 134 | int last_index = 0; 135 | float score = 0.f; 136 | int count = 0; 137 | float max_value = 0.0f; 138 | 139 | for (int n = 0; n < predict_shape[1]; n++) { 140 | // get idx 141 | argmax_idx = int(Utility::argmax( 142 | &out_data[(m * predict_shape[1] + n) * predict_shape[2]], 143 | &out_data[(m * predict_shape[1] + n + 1) * predict_shape[2]])); 144 | // get score 145 | max_value = float(*std::max_element( 146 | &out_data[(m * predict_shape[1] + n) * predict_shape[2]], 147 | &out_data[(m * predict_shape[1] + n + 1) * predict_shape[2]])); 148 | 149 | if (argmax_idx > 0 && (!(n > 0 && argmax_idx == last_index))) { 150 | score += max_value; 151 | count += 1; 152 | str_res += this->label_list_[argmax_idx]; 153 | } 154 | last_index = argmax_idx; 155 | } 156 | score /= count; 157 | if (std::isnan(score)) { 158 | continue; 159 | } 160 | rec_texts[indices[beg_img_no + m]] = str_res; 161 | rec_text_scores[indices[beg_img_no + m]] = score; 162 | } 163 | } 164 | // sort boex from top to bottom, from left to right 165 | for (int i = 0; i < rec_texts.size(); i++) { 166 | ocr_results[i].text = rec_texts[i]; 167 | ocr_results[i].score = rec_text_scores[i]; 168 | } 169 | return true; 170 | } 171 | 172 | } -------------------------------------------------------------------------------- /src/structure_layout.cpp: -------------------------------------------------------------------------------- 1 | #include "include/structure_layout.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Layout::Layout(std::string model_path, std::string layout_dict_path) { 6 | ov::Core core; 7 | this->model_path = model_path; 8 | this->model = core.read_model(this->model_path); 9 | this->model->reshape({1, 3, this->layout_img_h_, this->layout_img_w_}); 10 | 11 | // preprocessing API 12 | ov::preprocess::PrePostProcessor prep(this->model); 13 | // declare section of desired application's input format 14 | prep.input().tensor().set_layout("NHWC").set_color_format(ov::preprocess::ColorFormat::BGR); 15 | // specify actual model layout 16 | prep.input().model().set_layout("NCHW"); 17 | prep.input().preprocess().mean(this->mean_).scale(this->scale_); 18 | // dump preprocessor 19 | std::cout << "Preprocessor: " << prep << std::endl; 20 | this->model = prep.build(); 21 | this->compiled_model = core.compile_model(this->model, "CPU"); 22 | this->infer_request = this->compiled_model.create_infer_request(); 23 | 24 | this->post_processor_.init(layout_dict_path, this->layout_score_threshold, 25 | this->layout_nms_threshold); 26 | } 27 | 28 | void Layout::Run(cv::Mat &src_img, std::vector &structure_result) { 29 | this->src_img = src_img; 30 | this->resize_op_.Run(this->src_img, this->resize_img, this->layout_img_h_, this->layout_img_w_); 31 | std::vector>> boxes; 32 | auto input_port = this->compiled_model.input(); 33 | 34 | // -------- set input -------- 35 | this->resize_img.convertTo(this->resize_img, CV_32FC3, e); 36 | ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), (float *)this->resize_img.data); 37 | this->infer_request.set_input_tensor(input_tensor); 38 | // -------- start inference -------- 39 | this->infer_request.infer(); 40 | 41 | std::vector> out_tensor_list; 42 | std::vector output_shape_list; 43 | for (int j = 0; j < (this->model->outputs()).size(); j++) { 44 | auto output = this->infer_request.get_output_tensor(j); 45 | auto output_shape = output.get_shape(); 46 | int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1, 47 | std::multiplies()); 48 | output_shape_list.push_back(output_shape); 49 | 50 | const float *out_data = output.data(); 51 | std::vector out_tensor(out_data, out_data + out_num); 52 | out_tensor_list.push_back(out_tensor); 53 | } 54 | 55 | std::vector bbox_num; 56 | int reg_max = 0; 57 | for (int i = 0; i < out_tensor_list.size(); i++) { 58 | if (i == this->post_processor_.fpn_stride_.size()) { 59 | reg_max = output_shape_list[i][2] / 4; 60 | break; 61 | } 62 | } 63 | std::vector ori_shape = {this->src_img.rows, this->src_img.cols}; 64 | std::vector resize_shape = {this->resize_img.rows, this->resize_img.cols}; 65 | this->post_processor_.Run(structure_result, out_tensor_list, ori_shape, resize_shape, 66 | reg_max); 67 | bbox_num.push_back(structure_result.size()); 68 | } 69 | } -------------------------------------------------------------------------------- /src/structure_table.cpp: -------------------------------------------------------------------------------- 1 | #include "include/structure_table.h" 2 | 3 | namespace PaddleOCR { 4 | 5 | Table::Table(std::string model_path, const std::string table_char_dict_path) { 6 | ov::Core core; 7 | this->model_path = model_path; 8 | this->model = core.read_model(this->model_path); 9 | // reshape the model for dynamic batch size and sentence width 10 | this->model->reshape({{ov::Dimension(1, this->table_batch_num_), 3, this->table_max_len_, this->table_max_len_}}); 11 | this->compiled_model = core.compile_model(this->model, "CPU"); 12 | this->infer_request = this->compiled_model.create_infer_request(); 13 | this->post_processor_.init(table_char_dict_path, false); 14 | } 15 | 16 | void Table::Run(std::vector img_list, 17 | std::vector> &structure_html_tags, 18 | std::vector &structure_scores, 19 | std::vector>> &structure_boxes) { 20 | int img_num = img_list.size(); 21 | for (int beg_img_no = 0; beg_img_no < img_num; 22 | beg_img_no += this->table_batch_num_) { 23 | // preprocess 24 | auto preprocess_start = std::chrono::steady_clock::now(); 25 | int end_img_no = std::min(img_num, beg_img_no + this->table_batch_num_); 26 | int batch_num = end_img_no - beg_img_no; 27 | std::vector norm_img_batch; 28 | std::vector width_list; 29 | std::vector height_list; 30 | for (int ino = beg_img_no; ino < end_img_no; ino++) { 31 | cv::Mat srcimg; 32 | img_list[ino].copyTo(srcimg); 33 | cv::Mat resize_img; 34 | cv::Mat pad_img; 35 | this->resize_op_.Run(srcimg, resize_img, this->table_max_len_); 36 | this->normalize_op_.Run(&resize_img, this->mean_, this->scale_, 37 | this->is_scale_); 38 | this->pad_op_.Run(resize_img, pad_img, this->table_max_len_); 39 | norm_img_batch.push_back(pad_img); 40 | width_list.push_back(srcimg.cols); 41 | height_list.push_back(srcimg.rows); 42 | } 43 | 44 | std::vector input( 45 | batch_num * 3 * this->table_max_len_ * this->table_max_len_, 0.0f); 46 | ov::Shape intput_shape = {batch_num, 3, this->table_max_len_, this->table_max_len_}; 47 | this->permute_op_.Run(norm_img_batch, input.data()); 48 | // inference. 49 | auto input_port = this->compiled_model.input(); 50 | ov::Tensor input_tensor(input_port.get_element_type(), intput_shape, input.data()); 51 | this->infer_request.set_input_tensor(input_tensor); 52 | // start inference 53 | this->infer_request.infer(); 54 | 55 | auto output0 = this->infer_request.get_output_tensor(0); 56 | const float *out_data0 = output0.data(); 57 | auto predict_shape0 = output0.get_shape(); 58 | auto output1 = this->infer_request.get_output_tensor(1); 59 | const float *out_data1 = output1.data(); 60 | auto predict_shape1 = output1.get_shape(); 61 | 62 | int out_num0 = std::accumulate(predict_shape0.begin(), predict_shape0.end(), 63 | 1, std::multiplies()); 64 | int out_num1 = std::accumulate(predict_shape1.begin(), predict_shape1.end(), 65 | 1, std::multiplies()); 66 | 67 | std::vector loc_preds(out_data0, out_data0 + out_num0); 68 | std::vector structure_probs(out_data1, out_data1 + out_num1); 69 | 70 | // postprocess 71 | std::vector> structure_html_tag_batch; 72 | std::vector structure_score_batch; 73 | std::vector>> structure_boxes_batch; 74 | this->post_processor_.Run(loc_preds, structure_probs, structure_score_batch, 75 | predict_shape0, predict_shape1, 76 | structure_html_tag_batch, structure_boxes_batch, 77 | width_list, height_list); 78 | for (int m = 0; m < predict_shape0[0]; m++) { 79 | 80 | structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(), 81 | ""); 82 | structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(), 83 | ""); 84 | structure_html_tag_batch[m].insert(structure_html_tag_batch[m].begin(), 85 | ""); 86 | structure_html_tag_batch[m].push_back("
"); 87 | structure_html_tag_batch[m].push_back(""); 88 | structure_html_tag_batch[m].push_back(""); 89 | structure_html_tags.push_back(structure_html_tag_batch[m]); 90 | structure_scores.push_back(structure_score_batch[m]); 91 | structure_boxes.push_back(structure_boxes_batch[m]); 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /src/utility.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #ifdef _WIN32 23 | #include 24 | #else 25 | #include 26 | #endif 27 | 28 | namespace PaddleOCR { 29 | 30 | std::vector Utility::ReadDict(const std::string &path) { 31 | std::ifstream in(path); 32 | std::string line; 33 | std::vector m_vec; 34 | if (in) { 35 | while (getline(in, line)) { 36 | m_vec.push_back(line); 37 | } 38 | } else { 39 | std::cout << "no such label file: " << path << ", exit the program..." 40 | << std::endl; 41 | exit(1); 42 | } 43 | return m_vec; 44 | } 45 | 46 | void Utility::VisualizeBboxes(const cv::Mat &srcimg, 47 | const std::vector &ocr_result, 48 | const std::string &save_path) { 49 | cv::Mat img_vis; 50 | srcimg.copyTo(img_vis); 51 | for (int n = 0; n < ocr_result.size(); n++) { 52 | cv::Point rook_points[4]; 53 | for (int m = 0; m < ocr_result[n].box.size(); m++) { 54 | rook_points[m] = 55 | cv::Point(int(ocr_result[n].box[m][0]), int(ocr_result[n].box[m][1])); 56 | } 57 | 58 | const cv::Point *ppt[1] = {rook_points}; 59 | int npt[] = {4}; 60 | cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0); 61 | } 62 | 63 | cv::imwrite(save_path, img_vis); 64 | std::cout << "The detection visualized image saved in " + save_path 65 | << std::endl; 66 | } 67 | 68 | void Utility::VisualizeBboxes(const cv::Mat &srcimg, 69 | const StructurePredictResult &structure_result, 70 | const std::string &save_path) { 71 | cv::Mat img_vis; 72 | srcimg.copyTo(img_vis); 73 | img_vis = crop_image(img_vis, structure_result.box); 74 | for (int n = 0; n < structure_result.cell_box.size(); n++) { 75 | if (structure_result.cell_box[n].size() == 8) { 76 | cv::Point rook_points[4]; 77 | for (int m = 0; m < structure_result.cell_box[n].size(); m += 2) { 78 | rook_points[m / 2] = 79 | cv::Point(int(structure_result.cell_box[n][m]), 80 | int(structure_result.cell_box[n][m + 1])); 81 | } 82 | const cv::Point *ppt[1] = {rook_points}; 83 | int npt[] = {4}; 84 | cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0); 85 | } else if (structure_result.cell_box[n].size() == 4) { 86 | cv::Point rook_points[2]; 87 | rook_points[0] = cv::Point(int(structure_result.cell_box[n][0]), 88 | int(structure_result.cell_box[n][1])); 89 | rook_points[1] = cv::Point(int(structure_result.cell_box[n][2]), 90 | int(structure_result.cell_box[n][3])); 91 | cv::rectangle(img_vis, rook_points[0], rook_points[1], CV_RGB(0, 255, 0), 92 | 2, 8, 0); 93 | } 94 | } 95 | 96 | cv::imwrite(save_path, img_vis); 97 | std::cout << "The table visualized image saved in " + save_path << std::endl; 98 | } 99 | 100 | // list all files under a directory 101 | void Utility::GetAllFiles(const char *dir_name, 102 | std::vector &all_inputs) { 103 | if (NULL == dir_name) { 104 | std::cout << " dir_name is null ! " << std::endl; 105 | return; 106 | } 107 | struct stat s; 108 | stat(dir_name, &s); 109 | if (!S_ISDIR(s.st_mode)) { 110 | std::cout << "dir_name is not a valid directory !" << std::endl; 111 | all_inputs.push_back(dir_name); 112 | return; 113 | } else { 114 | struct dirent *filename; // return value for readdir() 115 | DIR *dir; // return value for opendir() 116 | dir = opendir(dir_name); 117 | if (NULL == dir) { 118 | std::cout << "Can not open dir " << dir_name << std::endl; 119 | return; 120 | } 121 | std::cout << "Successfully opened the dir !" << std::endl; 122 | while ((filename = readdir(dir)) != NULL) { 123 | if (strcmp(filename->d_name, ".") == 0 || 124 | strcmp(filename->d_name, "..") == 0) 125 | continue; 126 | // img_dir + std::string("/") + all_inputs[0]; 127 | all_inputs.push_back(dir_name + std::string("/") + 128 | std::string(filename->d_name)); 129 | } 130 | } 131 | } 132 | 133 | cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage, 134 | std::vector> box) { 135 | cv::Mat image; 136 | srcimage.copyTo(image); 137 | std::vector> points = box; 138 | 139 | int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]}; 140 | int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]}; 141 | int left = int(*std::min_element(x_collect, x_collect + 4)); 142 | int right = int(*std::max_element(x_collect, x_collect + 4)); 143 | int top = int(*std::min_element(y_collect, y_collect + 4)); 144 | int bottom = int(*std::max_element(y_collect, y_collect + 4)); 145 | 146 | cv::Mat img_crop; 147 | image(cv::Rect(left, top, right - left, bottom - top)).copyTo(img_crop); 148 | 149 | for (int i = 0; i < points.size(); i++) { 150 | points[i][0] -= left; 151 | points[i][1] -= top; 152 | } 153 | 154 | int img_crop_width = int(sqrt(pow(points[0][0] - points[1][0], 2) + 155 | pow(points[0][1] - points[1][1], 2))); 156 | int img_crop_height = int(sqrt(pow(points[0][0] - points[3][0], 2) + 157 | pow(points[0][1] - points[3][1], 2))); 158 | 159 | cv::Point2f pts_std[4]; 160 | pts_std[0] = cv::Point2f(0., 0.); 161 | pts_std[1] = cv::Point2f(img_crop_width, 0.); 162 | pts_std[2] = cv::Point2f(img_crop_width, img_crop_height); 163 | pts_std[3] = cv::Point2f(0.f, img_crop_height); 164 | 165 | cv::Point2f pointsf[4]; 166 | pointsf[0] = cv::Point2f(points[0][0], points[0][1]); 167 | pointsf[1] = cv::Point2f(points[1][0], points[1][1]); 168 | pointsf[2] = cv::Point2f(points[2][0], points[2][1]); 169 | pointsf[3] = cv::Point2f(points[3][0], points[3][1]); 170 | 171 | cv::Mat M = cv::getPerspectiveTransform(pointsf, pts_std); 172 | 173 | cv::Mat dst_img; 174 | cv::warpPerspective(img_crop, dst_img, M, 175 | cv::Size(img_crop_width, img_crop_height), 176 | cv::BORDER_REPLICATE); 177 | 178 | if (float(dst_img.rows) >= float(dst_img.cols) * 1.5) { 179 | cv::Mat srcCopy = cv::Mat(dst_img.rows, dst_img.cols, dst_img.depth()); 180 | cv::transpose(dst_img, srcCopy); 181 | cv::flip(srcCopy, srcCopy, 0); 182 | return srcCopy; 183 | } else { 184 | return dst_img; 185 | } 186 | } 187 | 188 | std::vector Utility::argsort(const std::vector &array) { 189 | const int array_len(array.size()); 190 | std::vector array_index(array_len, 0); 191 | for (int i = 0; i < array_len; ++i) 192 | array_index[i] = i; 193 | 194 | std::sort( 195 | array_index.begin(), array_index.end(), 196 | [&array](int pos1, int pos2) { return (array[pos1] < array[pos2]); }); 197 | 198 | return array_index; 199 | } 200 | 201 | std::string Utility::basename(const std::string &filename) { 202 | if (filename.empty()) { 203 | return ""; 204 | } 205 | 206 | auto len = filename.length(); 207 | auto index = filename.find_last_of("/\\"); 208 | 209 | if (index == std::string::npos) { 210 | return filename; 211 | } 212 | 213 | if (index + 1 >= len) { 214 | 215 | len--; 216 | index = filename.substr(0, len).find_last_of("/\\"); 217 | 218 | if (len == 0) { 219 | return filename; 220 | } 221 | 222 | if (index == 0) { 223 | return filename.substr(1, len - 1); 224 | } 225 | 226 | if (index == std::string::npos) { 227 | return filename.substr(0, len); 228 | } 229 | 230 | return filename.substr(index + 1, len - index - 1); 231 | } 232 | 233 | return filename.substr(index + 1, len - index); 234 | } 235 | 236 | bool Utility::PathExists(const std::string &path) { 237 | #ifdef _WIN32 238 | struct _stat buffer; 239 | return (_stat(path.c_str(), &buffer) == 0); 240 | #else 241 | struct stat buffer; 242 | return (stat(path.c_str(), &buffer) == 0); 243 | #endif // !_WIN32 244 | } 245 | 246 | void Utility::CreateDir(const std::string &path) { 247 | #ifdef _WIN32 248 | _mkdir(path.c_str()); 249 | #else 250 | mkdir(path.c_str(), 0777); 251 | #endif // !_WIN32 252 | } 253 | 254 | void Utility::print_result(const std::vector &ocr_result) { 255 | for (int i = 0; i < ocr_result.size(); i++) { 256 | std::cout << i << "\t"; 257 | // det 258 | std::vector> boxes = ocr_result[i].box; 259 | if (boxes.size() > 0) { 260 | std::cout << "det boxes: ["; 261 | for (int n = 0; n < boxes.size(); n++) { 262 | std::cout << '[' << boxes[n][0] << ',' << boxes[n][1] << "]"; 263 | if (n != boxes.size() - 1) { 264 | std::cout << ','; 265 | } 266 | } 267 | std::cout << "] "; 268 | } 269 | // rec 270 | if (ocr_result[i].score != -1.0) { 271 | std::cout << "rec text: " << ocr_result[i].text 272 | << " rec score: " << ocr_result[i].score << " "; 273 | } 274 | 275 | // cls 276 | if (ocr_result[i].cls_label != -1) { 277 | std::cout << "cls label: " << ocr_result[i].cls_label 278 | << " cls score: " << ocr_result[i].cls_score; 279 | } 280 | std::cout << std::endl; 281 | } 282 | } 283 | 284 | cv::Mat Utility::crop_image(cv::Mat &img, const std::vector &box) { 285 | cv::Mat crop_im; 286 | int crop_x1 = std::max(0, box[0]); 287 | int crop_y1 = std::max(0, box[1]); 288 | int crop_x2 = std::min(img.cols - 1, box[2] - 1); 289 | int crop_y2 = std::min(img.rows - 1, box[3] - 1); 290 | 291 | crop_im = cv::Mat::zeros(box[3] - box[1], box[2] - box[0], 16); 292 | cv::Mat crop_im_window = 293 | crop_im(cv::Range(crop_y1 - box[1], crop_y2 + 1 - box[1]), 294 | cv::Range(crop_x1 - box[0], crop_x2 + 1 - box[0])); 295 | cv::Mat roi_img = 296 | img(cv::Range(crop_y1, crop_y2 + 1), cv::Range(crop_x1, crop_x2 + 1)); 297 | crop_im_window += roi_img; 298 | return crop_im; 299 | } 300 | 301 | cv::Mat Utility::crop_image(cv::Mat &img, const std::vector &box) { 302 | std::vector box_int = {(int)box[0], (int)box[1], (int)box[2], 303 | (int)box[3]}; 304 | return crop_image(img, box_int); 305 | } 306 | 307 | void Utility::sorted_boxes(std::vector &ocr_result) { 308 | std::sort(ocr_result.begin(), ocr_result.end(), Utility::comparison_box); 309 | if (ocr_result.size() > 0) { 310 | for (int i = 0; i < ocr_result.size() - 1; i++) { 311 | for (int j = i; j > 0; j--) { 312 | if (abs(ocr_result[j + 1].box[0][1] - ocr_result[j].box[0][1]) < 10 && 313 | (ocr_result[j + 1].box[0][0] < ocr_result[j].box[0][0])) { 314 | std::swap(ocr_result[i], ocr_result[i + 1]); 315 | } 316 | } 317 | } 318 | } 319 | } 320 | 321 | std::vector Utility::xyxyxyxy2xyxy(std::vector> &box) { 322 | int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]}; 323 | int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]}; 324 | int left = int(*std::min_element(x_collect, x_collect + 4)); 325 | int right = int(*std::max_element(x_collect, x_collect + 4)); 326 | int top = int(*std::min_element(y_collect, y_collect + 4)); 327 | int bottom = int(*std::max_element(y_collect, y_collect + 4)); 328 | std::vector box1(4, 0); 329 | box1[0] = left; 330 | box1[1] = top; 331 | box1[2] = right; 332 | box1[3] = bottom; 333 | return box1; 334 | } 335 | 336 | std::vector Utility::xyxyxyxy2xyxy(std::vector &box) { 337 | int x_collect[4] = {box[0], box[2], box[4], box[6]}; 338 | int y_collect[4] = {box[1], box[3], box[5], box[7]}; 339 | int left = int(*std::min_element(x_collect, x_collect + 4)); 340 | int right = int(*std::max_element(x_collect, x_collect + 4)); 341 | int top = int(*std::min_element(y_collect, y_collect + 4)); 342 | int bottom = int(*std::max_element(y_collect, y_collect + 4)); 343 | std::vector box1(4, 0); 344 | box1[0] = left; 345 | box1[1] = top; 346 | box1[2] = right; 347 | box1[3] = bottom; 348 | return box1; 349 | } 350 | 351 | float Utility::fast_exp(float x) { 352 | union { 353 | uint32_t i; 354 | float f; 355 | } v{}; 356 | v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f); 357 | return v.f; 358 | } 359 | 360 | std::vector 361 | Utility::activation_function_softmax(std::vector &src) { 362 | int length = src.size(); 363 | std::vector dst; 364 | dst.resize(length); 365 | const float alpha = float(*std::max_element(&src[0], &src[0 + length])); 366 | float denominator{0}; 367 | 368 | for (int i = 0; i < length; ++i) { 369 | dst[i] = fast_exp(src[i] - alpha); 370 | denominator += dst[i]; 371 | } 372 | 373 | for (int i = 0; i < length; ++i) { 374 | dst[i] /= denominator; 375 | } 376 | return dst; 377 | } 378 | 379 | float Utility::iou(std::vector &box1, std::vector &box2) { 380 | int area1 = std::max(0, box1[2] - box1[0]) * std::max(0, box1[3] - box1[1]); 381 | int area2 = std::max(0, box2[2] - box2[0]) * std::max(0, box2[3] - box2[1]); 382 | 383 | // computing the sum_area 384 | int sum_area = area1 + area2; 385 | 386 | // find the each point of intersect rectangle 387 | int x1 = std::max(box1[0], box2[0]); 388 | int y1 = std::max(box1[1], box2[1]); 389 | int x2 = std::min(box1[2], box2[2]); 390 | int y2 = std::min(box1[3], box2[3]); 391 | 392 | // judge if there is an intersect 393 | if (y1 >= y2 || x1 >= x2) { 394 | return 0.0; 395 | } else { 396 | int intersect = (x2 - x1) * (y2 - y1); 397 | return intersect / (sum_area - intersect + 0.00000001); 398 | } 399 | } 400 | 401 | float Utility::iou(std::vector &box1, std::vector &box2) { 402 | float area1 = std::max((float)0.0, box1[2] - box1[0]) * 403 | std::max((float)0.0, box1[3] - box1[1]); 404 | float area2 = std::max((float)0.0, box2[2] - box2[0]) * 405 | std::max((float)0.0, box2[3] - box2[1]); 406 | 407 | // computing the sum_area 408 | float sum_area = area1 + area2; 409 | 410 | // find the each point of intersect rectangle 411 | float x1 = std::max(box1[0], box2[0]); 412 | float y1 = std::max(box1[1], box2[1]); 413 | float x2 = std::min(box1[2], box2[2]); 414 | float y2 = std::min(box1[3], box2[3]); 415 | 416 | // judge if there is an intersect 417 | if (y1 >= y2 || x1 >= x2) { 418 | return 0.0; 419 | } else { 420 | float intersect = (x2 - x1) * (y2 - y1); 421 | return intersect / (sum_area - intersect + 0.00000001); 422 | } 423 | } 424 | 425 | } // namespace PaddleOCR -------------------------------------------------------------------------------- /structure_result6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvino-dev-samples/PaddleOCR_OpenVINO_CPP/ce03e959f333b78abbd6e6eb62345b28bfc09a44/structure_result6.jpg -------------------------------------------------------------------------------- /structure_result7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvino-dev-samples/PaddleOCR_OpenVINO_CPP/ce03e959f333b78abbd6e6eb62345b28bfc09a44/structure_result7.jpg --------------------------------------------------------------------------------