pyxllib 0.3.96__py3-none-any.whl → 0.3.200__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. pyxllib/__init__.py +21 -21
  2. pyxllib/algo/__init__.py +8 -8
  3. pyxllib/algo/disjoint.py +54 -54
  4. pyxllib/algo/geo.py +541 -529
  5. pyxllib/algo/intervals.py +964 -964
  6. pyxllib/algo/matcher.py +389 -311
  7. pyxllib/algo/newbie.py +166 -166
  8. pyxllib/algo/pupil.py +629 -461
  9. pyxllib/algo/shapelylib.py +67 -67
  10. pyxllib/algo/specialist.py +241 -240
  11. pyxllib/algo/stat.py +494 -458
  12. pyxllib/algo/treelib.py +149 -149
  13. pyxllib/algo/unitlib.py +66 -66
  14. {pyxlpr → pyxllib/autogui}/__init__.py +5 -5
  15. pyxllib/autogui/activewin.py +246 -0
  16. pyxllib/autogui/all.py +9 -0
  17. pyxllib/{ext/autogui → autogui}/autogui.py +852 -823
  18. pyxllib/autogui/uiautolib.py +362 -0
  19. pyxllib/{ext/autogui → autogui}/virtualkey.py +102 -102
  20. pyxllib/autogui/wechat.py +827 -0
  21. pyxllib/autogui/wechat_msg.py +421 -0
  22. pyxllib/autogui/wxautolib.py +84 -0
  23. pyxllib/cv/__init__.py +5 -5
  24. pyxllib/cv/expert.py +267 -267
  25. pyxllib/cv/imfile.py +159 -159
  26. pyxllib/cv/imhash.py +39 -39
  27. pyxllib/cv/pupil.py +9 -9
  28. pyxllib/cv/rgbfmt.py +1525 -1525
  29. pyxllib/cv/slidercaptcha.py +137 -0
  30. pyxllib/cv/trackbartools.py +251 -251
  31. pyxllib/cv/xlcvlib.py +1040 -1040
  32. pyxllib/cv/xlpillib.py +423 -423
  33. pyxllib/data/echarts.py +240 -129
  34. pyxllib/data/jsonlib.py +89 -0
  35. pyxllib/data/oss.py +72 -72
  36. pyxllib/data/pglib.py +1127 -643
  37. pyxllib/data/sqlite.py +568 -341
  38. pyxllib/data/sqllib.py +297 -297
  39. pyxllib/ext/JLineViewer.py +505 -492
  40. pyxllib/ext/__init__.py +6 -6
  41. pyxllib/ext/demolib.py +246 -246
  42. pyxllib/ext/drissionlib.py +277 -0
  43. pyxllib/ext/kq5034lib.py +12 -1606
  44. pyxllib/ext/old.py +663 -663
  45. pyxllib/ext/qt.py +449 -449
  46. pyxllib/ext/robustprocfile.py +497 -0
  47. pyxllib/ext/seleniumlib.py +76 -76
  48. pyxllib/ext/tk.py +173 -173
  49. pyxllib/ext/unixlib.py +827 -826
  50. pyxllib/ext/utools.py +351 -338
  51. pyxllib/ext/webhook.py +124 -101
  52. pyxllib/ext/win32lib.py +40 -40
  53. pyxllib/ext/wjxlib.py +88 -0
  54. pyxllib/ext/wpsapi.py +124 -0
  55. pyxllib/ext/xlwork.py +9 -0
  56. pyxllib/ext/yuquelib.py +1105 -173
  57. pyxllib/file/__init__.py +17 -17
  58. pyxllib/file/docxlib.py +761 -761
  59. pyxllib/file/gitlib.py +309 -309
  60. pyxllib/file/libreoffice.py +165 -0
  61. pyxllib/file/movielib.py +148 -139
  62. pyxllib/file/newbie.py +10 -10
  63. pyxllib/file/onenotelib.py +1469 -1469
  64. pyxllib/file/packlib/__init__.py +330 -293
  65. pyxllib/file/packlib/zipfile.py +2441 -2441
  66. pyxllib/file/pdflib.py +426 -426
  67. pyxllib/file/pupil.py +185 -185
  68. pyxllib/file/specialist/__init__.py +685 -685
  69. pyxllib/file/specialist/dirlib.py +799 -799
  70. pyxllib/file/specialist/download.py +193 -186
  71. pyxllib/file/specialist/filelib.py +2829 -2618
  72. pyxllib/file/xlsxlib.py +3131 -2976
  73. pyxllib/file/xlsyncfile.py +341 -0
  74. pyxllib/prog/__init__.py +5 -5
  75. pyxllib/prog/cachetools.py +64 -0
  76. pyxllib/prog/deprecatedlib.py +233 -233
  77. pyxllib/prog/filelock.py +42 -0
  78. pyxllib/prog/ipyexec.py +253 -253
  79. pyxllib/prog/multiprogs.py +940 -0
  80. pyxllib/prog/newbie.py +451 -444
  81. pyxllib/prog/pupil.py +1197 -1128
  82. pyxllib/prog/sitepackages.py +33 -33
  83. pyxllib/prog/specialist/__init__.py +391 -217
  84. pyxllib/prog/specialist/bc.py +203 -200
  85. pyxllib/prog/specialist/browser.py +497 -488
  86. pyxllib/prog/specialist/common.py +347 -347
  87. pyxllib/prog/specialist/datetime.py +199 -131
  88. pyxllib/prog/specialist/tictoc.py +240 -241
  89. pyxllib/prog/specialist/xllog.py +180 -180
  90. pyxllib/prog/xlosenv.py +108 -101
  91. pyxllib/stdlib/__init__.py +17 -17
  92. pyxllib/stdlib/tablepyxl/__init__.py +10 -10
  93. pyxllib/stdlib/tablepyxl/style.py +303 -303
  94. pyxllib/stdlib/tablepyxl/tablepyxl.py +130 -130
  95. pyxllib/text/__init__.py +8 -8
  96. pyxllib/text/ahocorasick.py +39 -39
  97. pyxllib/text/airscript.js +744 -0
  98. pyxllib/text/charclasslib.py +121 -109
  99. pyxllib/text/jiebalib.py +267 -264
  100. pyxllib/text/jinjalib.py +32 -0
  101. pyxllib/text/jsa_ai_prompt.md +271 -0
  102. pyxllib/text/jscode.py +922 -767
  103. pyxllib/text/latex/__init__.py +158 -158
  104. pyxllib/text/levenshtein.py +303 -303
  105. pyxllib/text/nestenv.py +1215 -1215
  106. pyxllib/text/newbie.py +300 -288
  107. pyxllib/text/pupil/__init__.py +8 -8
  108. pyxllib/text/pupil/common.py +1121 -1095
  109. pyxllib/text/pupil/xlalign.py +326 -326
  110. pyxllib/text/pycode.py +47 -47
  111. pyxllib/text/specialist/__init__.py +8 -8
  112. pyxllib/text/specialist/common.py +112 -112
  113. pyxllib/text/specialist/ptag.py +186 -186
  114. pyxllib/text/spellchecker.py +172 -172
  115. pyxllib/text/templates/echart_base.html +11 -0
  116. pyxllib/text/templates/highlight_code.html +17 -0
  117. pyxllib/text/templates/latex_editor.html +103 -0
  118. pyxllib/text/vbacode.py +17 -17
  119. pyxllib/text/xmllib.py +747 -685
  120. pyxllib/xl.py +42 -38
  121. pyxllib/xlcv.py +17 -17
  122. pyxllib-0.3.200.dist-info/METADATA +48 -0
  123. pyxllib-0.3.200.dist-info/RECORD +126 -0
  124. {pyxllib-0.3.96.dist-info → pyxllib-0.3.200.dist-info}/WHEEL +1 -2
  125. {pyxllib-0.3.96.dist-info → pyxllib-0.3.200.dist-info/licenses}/LICENSE +190 -190
  126. pyxllib/ext/autogui/__init__.py +0 -8
  127. pyxllib-0.3.96.dist-info/METADATA +0 -51
  128. pyxllib-0.3.96.dist-info/RECORD +0 -333
  129. pyxllib-0.3.96.dist-info/top_level.txt +0 -2
  130. pyxlpr/ai/__init__.py +0 -5
  131. pyxlpr/ai/clientlib.py +0 -1281
  132. pyxlpr/ai/specialist.py +0 -286
  133. pyxlpr/ai/torch_app.py +0 -172
  134. pyxlpr/ai/xlpaddle.py +0 -655
  135. pyxlpr/ai/xltorch.py +0 -705
  136. pyxlpr/data/__init__.py +0 -11
  137. pyxlpr/data/coco.py +0 -1325
  138. pyxlpr/data/datacls.py +0 -365
  139. pyxlpr/data/datasets.py +0 -200
  140. pyxlpr/data/gptlib.py +0 -1291
  141. pyxlpr/data/icdar/__init__.py +0 -96
  142. pyxlpr/data/icdar/deteval.py +0 -377
  143. pyxlpr/data/icdar/icdar2013.py +0 -341
  144. pyxlpr/data/icdar/iou.py +0 -340
  145. pyxlpr/data/icdar/rrc_evaluation_funcs_1_1.py +0 -463
  146. pyxlpr/data/imtextline.py +0 -473
  147. pyxlpr/data/labelme.py +0 -866
  148. pyxlpr/data/removeline.py +0 -179
  149. pyxlpr/data/specialist.py +0 -57
  150. pyxlpr/eval/__init__.py +0 -85
  151. pyxlpr/paddleocr.py +0 -776
  152. pyxlpr/ppocr/__init__.py +0 -15
  153. pyxlpr/ppocr/configs/rec/multi_language/generate_multi_language_configs.py +0 -226
  154. pyxlpr/ppocr/data/__init__.py +0 -135
  155. pyxlpr/ppocr/data/imaug/ColorJitter.py +0 -26
  156. pyxlpr/ppocr/data/imaug/__init__.py +0 -67
  157. pyxlpr/ppocr/data/imaug/copy_paste.py +0 -170
  158. pyxlpr/ppocr/data/imaug/east_process.py +0 -437
  159. pyxlpr/ppocr/data/imaug/gen_table_mask.py +0 -244
  160. pyxlpr/ppocr/data/imaug/iaa_augment.py +0 -114
  161. pyxlpr/ppocr/data/imaug/label_ops.py +0 -789
  162. pyxlpr/ppocr/data/imaug/make_border_map.py +0 -184
  163. pyxlpr/ppocr/data/imaug/make_pse_gt.py +0 -106
  164. pyxlpr/ppocr/data/imaug/make_shrink_map.py +0 -126
  165. pyxlpr/ppocr/data/imaug/operators.py +0 -433
  166. pyxlpr/ppocr/data/imaug/pg_process.py +0 -906
  167. pyxlpr/ppocr/data/imaug/randaugment.py +0 -143
  168. pyxlpr/ppocr/data/imaug/random_crop_data.py +0 -239
  169. pyxlpr/ppocr/data/imaug/rec_img_aug.py +0 -533
  170. pyxlpr/ppocr/data/imaug/sast_process.py +0 -777
  171. pyxlpr/ppocr/data/imaug/text_image_aug/__init__.py +0 -17
  172. pyxlpr/ppocr/data/imaug/text_image_aug/augment.py +0 -120
  173. pyxlpr/ppocr/data/imaug/text_image_aug/warp_mls.py +0 -168
  174. pyxlpr/ppocr/data/lmdb_dataset.py +0 -115
  175. pyxlpr/ppocr/data/pgnet_dataset.py +0 -104
  176. pyxlpr/ppocr/data/pubtab_dataset.py +0 -107
  177. pyxlpr/ppocr/data/simple_dataset.py +0 -372
  178. pyxlpr/ppocr/losses/__init__.py +0 -61
  179. pyxlpr/ppocr/losses/ace_loss.py +0 -52
  180. pyxlpr/ppocr/losses/basic_loss.py +0 -135
  181. pyxlpr/ppocr/losses/center_loss.py +0 -88
  182. pyxlpr/ppocr/losses/cls_loss.py +0 -30
  183. pyxlpr/ppocr/losses/combined_loss.py +0 -67
  184. pyxlpr/ppocr/losses/det_basic_loss.py +0 -208
  185. pyxlpr/ppocr/losses/det_db_loss.py +0 -80
  186. pyxlpr/ppocr/losses/det_east_loss.py +0 -63
  187. pyxlpr/ppocr/losses/det_pse_loss.py +0 -149
  188. pyxlpr/ppocr/losses/det_sast_loss.py +0 -121
  189. pyxlpr/ppocr/losses/distillation_loss.py +0 -272
  190. pyxlpr/ppocr/losses/e2e_pg_loss.py +0 -140
  191. pyxlpr/ppocr/losses/kie_sdmgr_loss.py +0 -113
  192. pyxlpr/ppocr/losses/rec_aster_loss.py +0 -99
  193. pyxlpr/ppocr/losses/rec_att_loss.py +0 -39
  194. pyxlpr/ppocr/losses/rec_ctc_loss.py +0 -44
  195. pyxlpr/ppocr/losses/rec_enhanced_ctc_loss.py +0 -70
  196. pyxlpr/ppocr/losses/rec_nrtr_loss.py +0 -30
  197. pyxlpr/ppocr/losses/rec_sar_loss.py +0 -28
  198. pyxlpr/ppocr/losses/rec_srn_loss.py +0 -47
  199. pyxlpr/ppocr/losses/table_att_loss.py +0 -109
  200. pyxlpr/ppocr/metrics/__init__.py +0 -44
  201. pyxlpr/ppocr/metrics/cls_metric.py +0 -45
  202. pyxlpr/ppocr/metrics/det_metric.py +0 -82
  203. pyxlpr/ppocr/metrics/distillation_metric.py +0 -73
  204. pyxlpr/ppocr/metrics/e2e_metric.py +0 -86
  205. pyxlpr/ppocr/metrics/eval_det_iou.py +0 -274
  206. pyxlpr/ppocr/metrics/kie_metric.py +0 -70
  207. pyxlpr/ppocr/metrics/rec_metric.py +0 -75
  208. pyxlpr/ppocr/metrics/table_metric.py +0 -50
  209. pyxlpr/ppocr/modeling/architectures/__init__.py +0 -32
  210. pyxlpr/ppocr/modeling/architectures/base_model.py +0 -88
  211. pyxlpr/ppocr/modeling/architectures/distillation_model.py +0 -60
  212. pyxlpr/ppocr/modeling/backbones/__init__.py +0 -54
  213. pyxlpr/ppocr/modeling/backbones/det_mobilenet_v3.py +0 -268
  214. pyxlpr/ppocr/modeling/backbones/det_resnet_vd.py +0 -246
  215. pyxlpr/ppocr/modeling/backbones/det_resnet_vd_sast.py +0 -285
  216. pyxlpr/ppocr/modeling/backbones/e2e_resnet_vd_pg.py +0 -265
  217. pyxlpr/ppocr/modeling/backbones/kie_unet_sdmgr.py +0 -186
  218. pyxlpr/ppocr/modeling/backbones/rec_mobilenet_v3.py +0 -138
  219. pyxlpr/ppocr/modeling/backbones/rec_mv1_enhance.py +0 -258
  220. pyxlpr/ppocr/modeling/backbones/rec_nrtr_mtb.py +0 -48
  221. pyxlpr/ppocr/modeling/backbones/rec_resnet_31.py +0 -210
  222. pyxlpr/ppocr/modeling/backbones/rec_resnet_aster.py +0 -143
  223. pyxlpr/ppocr/modeling/backbones/rec_resnet_fpn.py +0 -307
  224. pyxlpr/ppocr/modeling/backbones/rec_resnet_vd.py +0 -286
  225. pyxlpr/ppocr/modeling/heads/__init__.py +0 -54
  226. pyxlpr/ppocr/modeling/heads/cls_head.py +0 -52
  227. pyxlpr/ppocr/modeling/heads/det_db_head.py +0 -118
  228. pyxlpr/ppocr/modeling/heads/det_east_head.py +0 -121
  229. pyxlpr/ppocr/modeling/heads/det_pse_head.py +0 -37
  230. pyxlpr/ppocr/modeling/heads/det_sast_head.py +0 -128
  231. pyxlpr/ppocr/modeling/heads/e2e_pg_head.py +0 -253
  232. pyxlpr/ppocr/modeling/heads/kie_sdmgr_head.py +0 -206
  233. pyxlpr/ppocr/modeling/heads/multiheadAttention.py +0 -163
  234. pyxlpr/ppocr/modeling/heads/rec_aster_head.py +0 -393
  235. pyxlpr/ppocr/modeling/heads/rec_att_head.py +0 -202
  236. pyxlpr/ppocr/modeling/heads/rec_ctc_head.py +0 -88
  237. pyxlpr/ppocr/modeling/heads/rec_nrtr_head.py +0 -826
  238. pyxlpr/ppocr/modeling/heads/rec_sar_head.py +0 -402
  239. pyxlpr/ppocr/modeling/heads/rec_srn_head.py +0 -280
  240. pyxlpr/ppocr/modeling/heads/self_attention.py +0 -406
  241. pyxlpr/ppocr/modeling/heads/table_att_head.py +0 -246
  242. pyxlpr/ppocr/modeling/necks/__init__.py +0 -32
  243. pyxlpr/ppocr/modeling/necks/db_fpn.py +0 -111
  244. pyxlpr/ppocr/modeling/necks/east_fpn.py +0 -188
  245. pyxlpr/ppocr/modeling/necks/fpn.py +0 -138
  246. pyxlpr/ppocr/modeling/necks/pg_fpn.py +0 -314
  247. pyxlpr/ppocr/modeling/necks/rnn.py +0 -92
  248. pyxlpr/ppocr/modeling/necks/sast_fpn.py +0 -284
  249. pyxlpr/ppocr/modeling/necks/table_fpn.py +0 -110
  250. pyxlpr/ppocr/modeling/transforms/__init__.py +0 -28
  251. pyxlpr/ppocr/modeling/transforms/stn.py +0 -135
  252. pyxlpr/ppocr/modeling/transforms/tps.py +0 -308
  253. pyxlpr/ppocr/modeling/transforms/tps_spatial_transformer.py +0 -156
  254. pyxlpr/ppocr/optimizer/__init__.py +0 -61
  255. pyxlpr/ppocr/optimizer/learning_rate.py +0 -228
  256. pyxlpr/ppocr/optimizer/lr_scheduler.py +0 -49
  257. pyxlpr/ppocr/optimizer/optimizer.py +0 -160
  258. pyxlpr/ppocr/optimizer/regularizer.py +0 -52
  259. pyxlpr/ppocr/postprocess/__init__.py +0 -55
  260. pyxlpr/ppocr/postprocess/cls_postprocess.py +0 -33
  261. pyxlpr/ppocr/postprocess/db_postprocess.py +0 -234
  262. pyxlpr/ppocr/postprocess/east_postprocess.py +0 -143
  263. pyxlpr/ppocr/postprocess/locality_aware_nms.py +0 -200
  264. pyxlpr/ppocr/postprocess/pg_postprocess.py +0 -52
  265. pyxlpr/ppocr/postprocess/pse_postprocess/__init__.py +0 -15
  266. pyxlpr/ppocr/postprocess/pse_postprocess/pse/__init__.py +0 -29
  267. pyxlpr/ppocr/postprocess/pse_postprocess/pse/setup.py +0 -14
  268. pyxlpr/ppocr/postprocess/pse_postprocess/pse_postprocess.py +0 -118
  269. pyxlpr/ppocr/postprocess/rec_postprocess.py +0 -654
  270. pyxlpr/ppocr/postprocess/sast_postprocess.py +0 -355
  271. pyxlpr/ppocr/tools/__init__.py +0 -14
  272. pyxlpr/ppocr/tools/eval.py +0 -83
  273. pyxlpr/ppocr/tools/export_center.py +0 -77
  274. pyxlpr/ppocr/tools/export_model.py +0 -129
  275. pyxlpr/ppocr/tools/infer/predict_cls.py +0 -151
  276. pyxlpr/ppocr/tools/infer/predict_det.py +0 -300
  277. pyxlpr/ppocr/tools/infer/predict_e2e.py +0 -169
  278. pyxlpr/ppocr/tools/infer/predict_rec.py +0 -414
  279. pyxlpr/ppocr/tools/infer/predict_system.py +0 -204
  280. pyxlpr/ppocr/tools/infer/utility.py +0 -629
  281. pyxlpr/ppocr/tools/infer_cls.py +0 -83
  282. pyxlpr/ppocr/tools/infer_det.py +0 -134
  283. pyxlpr/ppocr/tools/infer_e2e.py +0 -122
  284. pyxlpr/ppocr/tools/infer_kie.py +0 -153
  285. pyxlpr/ppocr/tools/infer_rec.py +0 -146
  286. pyxlpr/ppocr/tools/infer_table.py +0 -107
  287. pyxlpr/ppocr/tools/program.py +0 -596
  288. pyxlpr/ppocr/tools/test_hubserving.py +0 -117
  289. pyxlpr/ppocr/tools/train.py +0 -163
  290. pyxlpr/ppocr/tools/xlprog.py +0 -748
  291. pyxlpr/ppocr/utils/EN_symbol_dict.txt +0 -94
  292. pyxlpr/ppocr/utils/__init__.py +0 -24
  293. pyxlpr/ppocr/utils/dict/ar_dict.txt +0 -117
  294. pyxlpr/ppocr/utils/dict/arabic_dict.txt +0 -162
  295. pyxlpr/ppocr/utils/dict/be_dict.txt +0 -145
  296. pyxlpr/ppocr/utils/dict/bg_dict.txt +0 -140
  297. pyxlpr/ppocr/utils/dict/chinese_cht_dict.txt +0 -8421
  298. pyxlpr/ppocr/utils/dict/cyrillic_dict.txt +0 -163
  299. pyxlpr/ppocr/utils/dict/devanagari_dict.txt +0 -167
  300. pyxlpr/ppocr/utils/dict/en_dict.txt +0 -63
  301. pyxlpr/ppocr/utils/dict/fa_dict.txt +0 -136
  302. pyxlpr/ppocr/utils/dict/french_dict.txt +0 -136
  303. pyxlpr/ppocr/utils/dict/german_dict.txt +0 -143
  304. pyxlpr/ppocr/utils/dict/hi_dict.txt +0 -162
  305. pyxlpr/ppocr/utils/dict/it_dict.txt +0 -118
  306. pyxlpr/ppocr/utils/dict/japan_dict.txt +0 -4399
  307. pyxlpr/ppocr/utils/dict/ka_dict.txt +0 -153
  308. pyxlpr/ppocr/utils/dict/korean_dict.txt +0 -3688
  309. pyxlpr/ppocr/utils/dict/latin_dict.txt +0 -185
  310. pyxlpr/ppocr/utils/dict/mr_dict.txt +0 -153
  311. pyxlpr/ppocr/utils/dict/ne_dict.txt +0 -153
  312. pyxlpr/ppocr/utils/dict/oc_dict.txt +0 -96
  313. pyxlpr/ppocr/utils/dict/pu_dict.txt +0 -130
  314. pyxlpr/ppocr/utils/dict/rs_dict.txt +0 -91
  315. pyxlpr/ppocr/utils/dict/rsc_dict.txt +0 -134
  316. pyxlpr/ppocr/utils/dict/ru_dict.txt +0 -125
  317. pyxlpr/ppocr/utils/dict/ta_dict.txt +0 -128
  318. pyxlpr/ppocr/utils/dict/table_dict.txt +0 -277
  319. pyxlpr/ppocr/utils/dict/table_structure_dict.txt +0 -2759
  320. pyxlpr/ppocr/utils/dict/te_dict.txt +0 -151
  321. pyxlpr/ppocr/utils/dict/ug_dict.txt +0 -114
  322. pyxlpr/ppocr/utils/dict/uk_dict.txt +0 -142
  323. pyxlpr/ppocr/utils/dict/ur_dict.txt +0 -137
  324. pyxlpr/ppocr/utils/dict/xi_dict.txt +0 -110
  325. pyxlpr/ppocr/utils/dict90.txt +0 -90
  326. pyxlpr/ppocr/utils/e2e_metric/Deteval.py +0 -574
  327. pyxlpr/ppocr/utils/e2e_metric/polygon_fast.py +0 -83
  328. pyxlpr/ppocr/utils/e2e_utils/extract_batchsize.py +0 -87
  329. pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_fast.py +0 -457
  330. pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_slow.py +0 -592
  331. pyxlpr/ppocr/utils/e2e_utils/pgnet_pp_utils.py +0 -162
  332. pyxlpr/ppocr/utils/e2e_utils/visual.py +0 -162
  333. pyxlpr/ppocr/utils/en_dict.txt +0 -95
  334. pyxlpr/ppocr/utils/gen_label.py +0 -81
  335. pyxlpr/ppocr/utils/ic15_dict.txt +0 -36
  336. pyxlpr/ppocr/utils/iou.py +0 -54
  337. pyxlpr/ppocr/utils/logging.py +0 -69
  338. pyxlpr/ppocr/utils/network.py +0 -84
  339. pyxlpr/ppocr/utils/ppocr_keys_v1.txt +0 -6623
  340. pyxlpr/ppocr/utils/profiler.py +0 -110
  341. pyxlpr/ppocr/utils/save_load.py +0 -150
  342. pyxlpr/ppocr/utils/stats.py +0 -72
  343. pyxlpr/ppocr/utils/utility.py +0 -80
  344. pyxlpr/ppstructure/__init__.py +0 -13
  345. pyxlpr/ppstructure/predict_system.py +0 -187
  346. pyxlpr/ppstructure/table/__init__.py +0 -13
  347. pyxlpr/ppstructure/table/eval_table.py +0 -72
  348. pyxlpr/ppstructure/table/matcher.py +0 -192
  349. pyxlpr/ppstructure/table/predict_structure.py +0 -136
  350. pyxlpr/ppstructure/table/predict_table.py +0 -221
  351. pyxlpr/ppstructure/table/table_metric/__init__.py +0 -16
  352. pyxlpr/ppstructure/table/table_metric/parallel.py +0 -51
  353. pyxlpr/ppstructure/table/table_metric/table_metric.py +0 -247
  354. pyxlpr/ppstructure/table/tablepyxl/__init__.py +0 -13
  355. pyxlpr/ppstructure/table/tablepyxl/style.py +0 -283
  356. pyxlpr/ppstructure/table/tablepyxl/tablepyxl.py +0 -118
  357. pyxlpr/ppstructure/utility.py +0 -71
  358. pyxlpr/xlai.py +0 -10
@@ -1,906 +0,0 @@
1
- # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
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
- import math
16
- import cv2
17
- import numpy as np
18
-
19
- __all__ = ['PGProcessTrain']
20
-
21
-
22
- class PGProcessTrain(object):
23
- def __init__(self,
24
- character_dict_path,
25
- max_text_length,
26
- max_text_nums,
27
- tcl_len,
28
- batch_size=14,
29
- min_crop_size=24,
30
- min_text_size=4,
31
- max_text_size=512,
32
- **kwargs):
33
- self.tcl_len = tcl_len
34
- self.max_text_length = max_text_length
35
- self.max_text_nums = max_text_nums
36
- self.batch_size = batch_size
37
- self.min_crop_size = min_crop_size
38
- self.min_text_size = min_text_size
39
- self.max_text_size = max_text_size
40
- self.Lexicon_Table = self.get_dict(character_dict_path)
41
- self.pad_num = len(self.Lexicon_Table)
42
- self.img_id = 0
43
-
44
- def get_dict(self, character_dict_path):
45
- character_str = ""
46
- with open(character_dict_path, "rb") as fin:
47
- lines = fin.readlines()
48
- for line in lines:
49
- line = line.decode('utf-8').strip("\n").strip("\r\n")
50
- character_str += line
51
- dict_character = list(character_str)
52
- return dict_character
53
-
54
- def quad_area(self, poly):
55
- """
56
- compute area of a polygon
57
- :param poly:
58
- :return:
59
- """
60
- edge = [(poly[1][0] - poly[0][0]) * (poly[1][1] + poly[0][1]),
61
- (poly[2][0] - poly[1][0]) * (poly[2][1] + poly[1][1]),
62
- (poly[3][0] - poly[2][0]) * (poly[3][1] + poly[2][1]),
63
- (poly[0][0] - poly[3][0]) * (poly[0][1] + poly[3][1])]
64
- return np.sum(edge) / 2.
65
-
66
- def gen_quad_from_poly(self, poly):
67
- """
68
- Generate min area quad from poly.
69
- """
70
- point_num = poly.shape[0]
71
- min_area_quad = np.zeros((4, 2), dtype=np.float32)
72
- rect = cv2.minAreaRect(poly.astype(
73
- np.int32)) # (center (x,y), (width, height), angle of rotation)
74
- box = np.array(cv2.boxPoints(rect))
75
-
76
- first_point_idx = 0
77
- min_dist = 1e4
78
- for i in range(4):
79
- dist = np.linalg.norm(box[(i + 0) % 4] - poly[0]) + \
80
- np.linalg.norm(box[(i + 1) % 4] - poly[point_num // 2 - 1]) + \
81
- np.linalg.norm(box[(i + 2) % 4] - poly[point_num // 2]) + \
82
- np.linalg.norm(box[(i + 3) % 4] - poly[-1])
83
- if dist < min_dist:
84
- min_dist = dist
85
- first_point_idx = i
86
- for i in range(4):
87
- min_area_quad[i] = box[(first_point_idx + i) % 4]
88
-
89
- return min_area_quad
90
-
91
- def check_and_validate_polys(self, polys, tags, im_size):
92
- """
93
- check so that the text poly is in the same direction,
94
- and also filter some invalid polygons
95
- :param polys:
96
- :param tags:
97
- :return:
98
- """
99
- (h, w) = im_size
100
- if polys.shape[0] == 0:
101
- return polys, np.array([]), np.array([])
102
- polys[:, :, 0] = np.clip(polys[:, :, 0], 0, w - 1)
103
- polys[:, :, 1] = np.clip(polys[:, :, 1], 0, h - 1)
104
-
105
- validated_polys = []
106
- validated_tags = []
107
- hv_tags = []
108
- for poly, tag in zip(polys, tags):
109
- quad = self.gen_quad_from_poly(poly)
110
- p_area = self.quad_area(quad)
111
- if abs(p_area) < 1:
112
- print('invalid poly')
113
- continue
114
- if p_area > 0:
115
- if tag == False:
116
- print('poly in wrong direction')
117
- tag = True # reversed cases should be ignore
118
- poly = poly[(0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
119
- 1), :]
120
- quad = quad[(0, 3, 2, 1), :]
121
-
122
- len_w = np.linalg.norm(quad[0] - quad[1]) + np.linalg.norm(quad[3] -
123
- quad[2])
124
- len_h = np.linalg.norm(quad[0] - quad[3]) + np.linalg.norm(quad[1] -
125
- quad[2])
126
- hv_tag = 1
127
-
128
- if len_w * 2.0 < len_h:
129
- hv_tag = 0
130
-
131
- validated_polys.append(poly)
132
- validated_tags.append(tag)
133
- hv_tags.append(hv_tag)
134
- return np.array(validated_polys), np.array(validated_tags), np.array(
135
- hv_tags)
136
-
137
- def crop_area(self,
138
- im,
139
- polys,
140
- tags,
141
- hv_tags,
142
- txts,
143
- crop_background=False,
144
- max_tries=25):
145
- """
146
- make random crop from the input image
147
- :param im:
148
- :param polys: [b,4,2]
149
- :param tags:
150
- :param crop_background:
151
- :param max_tries: 50 -> 25
152
- :return:
153
- """
154
- h, w, _ = im.shape
155
- pad_h = h // 10
156
- pad_w = w // 10
157
- h_array = np.zeros((h + pad_h * 2), dtype=np.int32)
158
- w_array = np.zeros((w + pad_w * 2), dtype=np.int32)
159
- for poly in polys:
160
- poly = np.round(poly, decimals=0).astype(np.int32)
161
- minx = np.min(poly[:, 0])
162
- maxx = np.max(poly[:, 0])
163
- w_array[minx + pad_w:maxx + pad_w] = 1
164
- miny = np.min(poly[:, 1])
165
- maxy = np.max(poly[:, 1])
166
- h_array[miny + pad_h:maxy + pad_h] = 1
167
- # ensure the cropped area not across a text
168
- h_axis = np.where(h_array == 0)[0]
169
- w_axis = np.where(w_array == 0)[0]
170
- if len(h_axis) == 0 or len(w_axis) == 0:
171
- return im, polys, tags, hv_tags, txts
172
- for i in range(max_tries):
173
- xx = np.random.choice(w_axis, size=2)
174
- xmin = np.min(xx) - pad_w
175
- xmax = np.max(xx) - pad_w
176
- xmin = np.clip(xmin, 0, w - 1)
177
- xmax = np.clip(xmax, 0, w - 1)
178
- yy = np.random.choice(h_axis, size=2)
179
- ymin = np.min(yy) - pad_h
180
- ymax = np.max(yy) - pad_h
181
- ymin = np.clip(ymin, 0, h - 1)
182
- ymax = np.clip(ymax, 0, h - 1)
183
- if xmax - xmin < self.min_crop_size or \
184
- ymax - ymin < self.min_crop_size:
185
- continue
186
- if polys.shape[0] != 0:
187
- poly_axis_in_area = (polys[:, :, 0] >= xmin) & (polys[:, :, 0] <= xmax) \
188
- & (polys[:, :, 1] >= ymin) & (polys[:, :, 1] <= ymax)
189
- selected_polys = np.where(
190
- np.sum(poly_axis_in_area, axis=1) == 4)[0]
191
- else:
192
- selected_polys = []
193
- if len(selected_polys) == 0:
194
- # no text in this area
195
- if crop_background:
196
- txts_tmp = []
197
- for selected_poly in selected_polys:
198
- txts_tmp.append(txts[selected_poly])
199
- txts = txts_tmp
200
- return im[ymin: ymax + 1, xmin: xmax + 1, :], \
201
- polys[selected_polys], tags[selected_polys], hv_tags[selected_polys], txts
202
- else:
203
- continue
204
- im = im[ymin:ymax + 1, xmin:xmax + 1, :]
205
- polys = polys[selected_polys]
206
- tags = tags[selected_polys]
207
- hv_tags = hv_tags[selected_polys]
208
- txts_tmp = []
209
- for selected_poly in selected_polys:
210
- txts_tmp.append(txts[selected_poly])
211
- txts = txts_tmp
212
- polys[:, :, 0] -= xmin
213
- polys[:, :, 1] -= ymin
214
- return im, polys, tags, hv_tags, txts
215
-
216
- return im, polys, tags, hv_tags, txts
217
-
218
- def fit_and_gather_tcl_points_v2(self,
219
- min_area_quad,
220
- poly,
221
- max_h,
222
- max_w,
223
- fixed_point_num=64,
224
- img_id=0,
225
- reference_height=3):
226
- """
227
- Find the center point of poly as key_points, then fit and gather.
228
- """
229
- key_point_xys = []
230
- point_num = poly.shape[0]
231
- for idx in range(point_num // 2):
232
- center_point = (poly[idx] + poly[point_num - 1 - idx]) / 2.0
233
- key_point_xys.append(center_point)
234
-
235
- tmp_image = np.zeros(
236
- shape=(
237
- max_h,
238
- max_w, ), dtype='float32')
239
- cv2.polylines(tmp_image, [np.array(key_point_xys).astype('int32')],
240
- False, 1.0)
241
- ys, xs = np.where(tmp_image > 0)
242
- xy_text = np.array(list(zip(xs, ys)), dtype='float32')
243
-
244
- left_center_pt = (
245
- (min_area_quad[0] - min_area_quad[1]) / 2.0).reshape(1, 2)
246
- right_center_pt = (
247
- (min_area_quad[1] - min_area_quad[2]) / 2.0).reshape(1, 2)
248
- proj_unit_vec = (right_center_pt - left_center_pt) / (
249
- np.linalg.norm(right_center_pt - left_center_pt) + 1e-6)
250
- proj_unit_vec_tile = np.tile(proj_unit_vec,
251
- (xy_text.shape[0], 1)) # (n, 2)
252
- left_center_pt_tile = np.tile(left_center_pt,
253
- (xy_text.shape[0], 1)) # (n, 2)
254
- xy_text_to_left_center = xy_text - left_center_pt_tile
255
- proj_value = np.sum(xy_text_to_left_center * proj_unit_vec_tile, axis=1)
256
- xy_text = xy_text[np.argsort(proj_value)]
257
-
258
- # convert to np and keep the num of point not greater then fixed_point_num
259
- pos_info = np.array(xy_text).reshape(-1, 2)[:, ::-1] # xy-> yx
260
- point_num = len(pos_info)
261
- if point_num > fixed_point_num:
262
- keep_ids = [
263
- int((point_num * 1.0 / fixed_point_num) * x)
264
- for x in range(fixed_point_num)
265
- ]
266
- pos_info = pos_info[keep_ids, :]
267
-
268
- keep = int(min(len(pos_info), fixed_point_num))
269
- if np.random.rand() < 0.2 and reference_height >= 3:
270
- dl = (np.random.rand(keep) - 0.5) * reference_height * 0.3
271
- random_float = np.array([1, 0]).reshape([1, 2]) * dl.reshape(
272
- [keep, 1])
273
- pos_info += random_float
274
- pos_info[:, 0] = np.clip(pos_info[:, 0], 0, max_h - 1)
275
- pos_info[:, 1] = np.clip(pos_info[:, 1], 0, max_w - 1)
276
-
277
- # padding to fixed length
278
- pos_l = np.zeros((self.tcl_len, 3), dtype=np.int32)
279
- pos_l[:, 0] = np.ones((self.tcl_len, )) * img_id
280
- pos_m = np.zeros((self.tcl_len, 1), dtype=np.float32)
281
- pos_l[:keep, 1:] = np.round(pos_info).astype(np.int32)
282
- pos_m[:keep] = 1.0
283
- return pos_l, pos_m
284
-
285
- def generate_direction_map(self, poly_quads, n_char, direction_map):
286
- """
287
- """
288
- width_list = []
289
- height_list = []
290
- for quad in poly_quads:
291
- quad_w = (np.linalg.norm(quad[0] - quad[1]) +
292
- np.linalg.norm(quad[2] - quad[3])) / 2.0
293
- quad_h = (np.linalg.norm(quad[0] - quad[3]) +
294
- np.linalg.norm(quad[2] - quad[1])) / 2.0
295
- width_list.append(quad_w)
296
- height_list.append(quad_h)
297
- norm_width = max(sum(width_list) / n_char, 1.0)
298
- average_height = max(sum(height_list) / len(height_list), 1.0)
299
- k = 1
300
- for quad in poly_quads:
301
- direct_vector_full = (
302
- (quad[1] + quad[2]) - (quad[0] + quad[3])) / 2.0
303
- direct_vector = direct_vector_full / (
304
- np.linalg.norm(direct_vector_full) + 1e-6) * norm_width
305
- direction_label = tuple(
306
- map(float,
307
- [direct_vector[0], direct_vector[1], 1.0 / average_height]))
308
- cv2.fillPoly(direction_map,
309
- quad.round().astype(np.int32)[np.newaxis, :, :],
310
- direction_label)
311
- k += 1
312
- return direction_map
313
-
314
- def calculate_average_height(self, poly_quads):
315
- """
316
- """
317
- height_list = []
318
- for quad in poly_quads:
319
- quad_h = (np.linalg.norm(quad[0] - quad[3]) +
320
- np.linalg.norm(quad[2] - quad[1])) / 2.0
321
- height_list.append(quad_h)
322
- average_height = max(sum(height_list) / len(height_list), 1.0)
323
- return average_height
324
-
325
- def generate_tcl_ctc_label(self,
326
- h,
327
- w,
328
- polys,
329
- tags,
330
- text_strs,
331
- ds_ratio,
332
- tcl_ratio=0.3,
333
- shrink_ratio_of_width=0.15):
334
- """
335
- Generate polygon.
336
- """
337
- score_map_big = np.zeros(
338
- (
339
- h,
340
- w, ), dtype=np.float32)
341
- h, w = int(h * ds_ratio), int(w * ds_ratio)
342
- polys = polys * ds_ratio
343
-
344
- score_map = np.zeros(
345
- (
346
- h,
347
- w, ), dtype=np.float32)
348
- score_label_map = np.zeros(
349
- (
350
- h,
351
- w, ), dtype=np.float32)
352
- tbo_map = np.zeros((h, w, 5), dtype=np.float32)
353
- training_mask = np.ones(
354
- (
355
- h,
356
- w, ), dtype=np.float32)
357
- direction_map = np.ones((h, w, 3)) * np.array([0, 0, 1]).reshape(
358
- [1, 1, 3]).astype(np.float32)
359
-
360
- label_idx = 0
361
- score_label_map_text_label_list = []
362
- pos_list, pos_mask, label_list = [], [], []
363
- for poly_idx, poly_tag in enumerate(zip(polys, tags)):
364
- poly = poly_tag[0]
365
- tag = poly_tag[1]
366
-
367
- # generate min_area_quad
368
- min_area_quad, center_point = self.gen_min_area_quad_from_poly(poly)
369
- min_area_quad_h = 0.5 * (
370
- np.linalg.norm(min_area_quad[0] - min_area_quad[3]) +
371
- np.linalg.norm(min_area_quad[1] - min_area_quad[2]))
372
- min_area_quad_w = 0.5 * (
373
- np.linalg.norm(min_area_quad[0] - min_area_quad[1]) +
374
- np.linalg.norm(min_area_quad[2] - min_area_quad[3]))
375
-
376
- if min(min_area_quad_h, min_area_quad_w) < self.min_text_size * ds_ratio \
377
- or min(min_area_quad_h, min_area_quad_w) > self.max_text_size * ds_ratio:
378
- continue
379
-
380
- if tag:
381
- cv2.fillPoly(training_mask,
382
- poly.astype(np.int32)[np.newaxis, :, :], 0.15)
383
- else:
384
- text_label = text_strs[poly_idx]
385
- text_label = self.prepare_text_label(text_label,
386
- self.Lexicon_Table)
387
-
388
- text_label_index_list = [[self.Lexicon_Table.index(c_)]
389
- for c_ in text_label
390
- if c_ in self.Lexicon_Table]
391
- if len(text_label_index_list) < 1:
392
- continue
393
-
394
- tcl_poly = self.poly2tcl(poly, tcl_ratio)
395
- tcl_quads = self.poly2quads(tcl_poly)
396
- poly_quads = self.poly2quads(poly)
397
-
398
- stcl_quads, quad_index = self.shrink_poly_along_width(
399
- tcl_quads,
400
- shrink_ratio_of_width=shrink_ratio_of_width,
401
- expand_height_ratio=1.0 / tcl_ratio)
402
-
403
- cv2.fillPoly(score_map,
404
- np.round(stcl_quads).astype(np.int32), 1.0)
405
- cv2.fillPoly(score_map_big,
406
- np.round(stcl_quads / ds_ratio).astype(np.int32),
407
- 1.0)
408
-
409
- for idx, quad in enumerate(stcl_quads):
410
- quad_mask = np.zeros((h, w), dtype=np.float32)
411
- quad_mask = cv2.fillPoly(
412
- quad_mask,
413
- np.round(quad[np.newaxis, :, :]).astype(np.int32), 1.0)
414
- tbo_map = self.gen_quad_tbo(poly_quads[quad_index[idx]],
415
- quad_mask, tbo_map)
416
-
417
- # score label map and score_label_map_text_label_list for refine
418
- if label_idx == 0:
419
- text_pos_list_ = [[len(self.Lexicon_Table)], ]
420
- score_label_map_text_label_list.append(text_pos_list_)
421
-
422
- label_idx += 1
423
- cv2.fillPoly(score_label_map,
424
- np.round(poly_quads).astype(np.int32), label_idx)
425
- score_label_map_text_label_list.append(text_label_index_list)
426
-
427
- # direction info, fix-me
428
- n_char = len(text_label_index_list)
429
- direction_map = self.generate_direction_map(poly_quads, n_char,
430
- direction_map)
431
-
432
- # pos info
433
- average_shrink_height = self.calculate_average_height(
434
- stcl_quads)
435
- pos_l, pos_m = self.fit_and_gather_tcl_points_v2(
436
- min_area_quad,
437
- poly,
438
- max_h=h,
439
- max_w=w,
440
- fixed_point_num=64,
441
- img_id=self.img_id,
442
- reference_height=average_shrink_height)
443
-
444
- label_l = text_label_index_list
445
- if len(text_label_index_list) < 2:
446
- continue
447
-
448
- pos_list.append(pos_l)
449
- pos_mask.append(pos_m)
450
- label_list.append(label_l)
451
-
452
- # use big score_map for smooth tcl lines
453
- score_map_big_resized = cv2.resize(
454
- score_map_big, dsize=None, fx=ds_ratio, fy=ds_ratio)
455
- score_map = np.array(score_map_big_resized > 1e-3, dtype='float32')
456
-
457
- return score_map, score_label_map, tbo_map, direction_map, training_mask, \
458
- pos_list, pos_mask, label_list, score_label_map_text_label_list
459
-
460
- def adjust_point(self, poly):
461
- """
462
- adjust point order.
463
- """
464
- point_num = poly.shape[0]
465
- if point_num == 4:
466
- len_1 = np.linalg.norm(poly[0] - poly[1])
467
- len_2 = np.linalg.norm(poly[1] - poly[2])
468
- len_3 = np.linalg.norm(poly[2] - poly[3])
469
- len_4 = np.linalg.norm(poly[3] - poly[0])
470
-
471
- if (len_1 + len_3) * 1.5 < (len_2 + len_4):
472
- poly = poly[[1, 2, 3, 0], :]
473
-
474
- elif point_num > 4:
475
- vector_1 = poly[0] - poly[1]
476
- vector_2 = poly[1] - poly[2]
477
- cos_theta = np.dot(vector_1, vector_2) / (
478
- np.linalg.norm(vector_1) * np.linalg.norm(vector_2) + 1e-6)
479
- theta = np.arccos(np.round(cos_theta, decimals=4))
480
-
481
- if abs(theta) > (70 / 180 * math.pi):
482
- index = list(range(1, point_num)) + [0]
483
- poly = poly[np.array(index), :]
484
- return poly
485
-
486
- def gen_min_area_quad_from_poly(self, poly):
487
- """
488
- Generate min area quad from poly.
489
- """
490
- point_num = poly.shape[0]
491
- min_area_quad = np.zeros((4, 2), dtype=np.float32)
492
- if point_num == 4:
493
- min_area_quad = poly
494
- center_point = np.sum(poly, axis=0) / 4
495
- else:
496
- rect = cv2.minAreaRect(poly.astype(
497
- np.int32)) # (center (x,y), (width, height), angle of rotation)
498
- center_point = rect[0]
499
- box = np.array(cv2.boxPoints(rect))
500
-
501
- first_point_idx = 0
502
- min_dist = 1e4
503
- for i in range(4):
504
- dist = np.linalg.norm(box[(i + 0) % 4] - poly[0]) + \
505
- np.linalg.norm(box[(i + 1) % 4] - poly[point_num // 2 - 1]) + \
506
- np.linalg.norm(box[(i + 2) % 4] - poly[point_num // 2]) + \
507
- np.linalg.norm(box[(i + 3) % 4] - poly[-1])
508
- if dist < min_dist:
509
- min_dist = dist
510
- first_point_idx = i
511
-
512
- for i in range(4):
513
- min_area_quad[i] = box[(first_point_idx + i) % 4]
514
-
515
- return min_area_quad, center_point
516
-
517
- def shrink_quad_along_width(self,
518
- quad,
519
- begin_width_ratio=0.,
520
- end_width_ratio=1.):
521
- """
522
- Generate shrink_quad_along_width.
523
- """
524
- ratio_pair = np.array(
525
- [[begin_width_ratio], [end_width_ratio]], dtype=np.float32)
526
- p0_1 = quad[0] + (quad[1] - quad[0]) * ratio_pair
527
- p3_2 = quad[3] + (quad[2] - quad[3]) * ratio_pair
528
- return np.array([p0_1[0], p0_1[1], p3_2[1], p3_2[0]])
529
-
530
- def shrink_poly_along_width(self,
531
- quads,
532
- shrink_ratio_of_width,
533
- expand_height_ratio=1.0):
534
- """
535
- shrink poly with given length.
536
- """
537
- upper_edge_list = []
538
-
539
- def get_cut_info(edge_len_list, cut_len):
540
- for idx, edge_len in enumerate(edge_len_list):
541
- cut_len -= edge_len
542
- if cut_len <= 0.000001:
543
- ratio = (cut_len + edge_len_list[idx]) / edge_len_list[idx]
544
- return idx, ratio
545
-
546
- for quad in quads:
547
- upper_edge_len = np.linalg.norm(quad[0] - quad[1])
548
- upper_edge_list.append(upper_edge_len)
549
-
550
- # length of left edge and right edge.
551
- left_length = np.linalg.norm(quads[0][0] - quads[0][
552
- 3]) * expand_height_ratio
553
- right_length = np.linalg.norm(quads[-1][1] - quads[-1][
554
- 2]) * expand_height_ratio
555
-
556
- shrink_length = min(left_length, right_length,
557
- sum(upper_edge_list)) * shrink_ratio_of_width
558
- # shrinking length
559
- upper_len_left = shrink_length
560
- upper_len_right = sum(upper_edge_list) - shrink_length
561
-
562
- left_idx, left_ratio = get_cut_info(upper_edge_list, upper_len_left)
563
- left_quad = self.shrink_quad_along_width(
564
- quads[left_idx], begin_width_ratio=left_ratio, end_width_ratio=1)
565
- right_idx, right_ratio = get_cut_info(upper_edge_list, upper_len_right)
566
- right_quad = self.shrink_quad_along_width(
567
- quads[right_idx], begin_width_ratio=0, end_width_ratio=right_ratio)
568
-
569
- out_quad_list = []
570
- if left_idx == right_idx:
571
- out_quad_list.append(
572
- [left_quad[0], right_quad[1], right_quad[2], left_quad[3]])
573
- else:
574
- out_quad_list.append(left_quad)
575
- for idx in range(left_idx + 1, right_idx):
576
- out_quad_list.append(quads[idx])
577
- out_quad_list.append(right_quad)
578
-
579
- return np.array(out_quad_list), list(range(left_idx, right_idx + 1))
580
-
581
- def prepare_text_label(self, label_str, Lexicon_Table):
582
- """
583
- Prepare text lablel by given Lexicon_Table.
584
- """
585
- if len(Lexicon_Table) == 36:
586
- return label_str.lower()
587
- else:
588
- return label_str
589
-
590
- def vector_angle(self, A, B):
591
- """
592
- Calculate the angle between vector AB and x-axis positive direction.
593
- """
594
- AB = np.array([B[1] - A[1], B[0] - A[0]])
595
- return np.arctan2(*AB)
596
-
597
- def theta_line_cross_point(self, theta, point):
598
- """
599
- Calculate the line through given point and angle in ax + by + c =0 form.
600
- """
601
- x, y = point
602
- cos = np.cos(theta)
603
- sin = np.sin(theta)
604
- return [sin, -cos, cos * y - sin * x]
605
-
606
- def line_cross_two_point(self, A, B):
607
- """
608
- Calculate the line through given point A and B in ax + by + c =0 form.
609
- """
610
- angle = self.vector_angle(A, B)
611
- return self.theta_line_cross_point(angle, A)
612
-
613
- def average_angle(self, poly):
614
- """
615
- Calculate the average angle between left and right edge in given poly.
616
- """
617
- p0, p1, p2, p3 = poly
618
- angle30 = self.vector_angle(p3, p0)
619
- angle21 = self.vector_angle(p2, p1)
620
- return (angle30 + angle21) / 2
621
-
622
- def line_cross_point(self, line1, line2):
623
- """
624
- line1 and line2 in 0=ax+by+c form, compute the cross point of line1 and line2
625
- """
626
- a1, b1, c1 = line1
627
- a2, b2, c2 = line2
628
- d = a1 * b2 - a2 * b1
629
-
630
- if d == 0:
631
- print('Cross point does not exist')
632
- return np.array([0, 0], dtype=np.float32)
633
- else:
634
- x = (b1 * c2 - b2 * c1) / d
635
- y = (a2 * c1 - a1 * c2) / d
636
-
637
- return np.array([x, y], dtype=np.float32)
638
-
639
- def quad2tcl(self, poly, ratio):
640
- """
641
- Generate center line by poly clock-wise point. (4, 2)
642
- """
643
- ratio_pair = np.array(
644
- [[0.5 - ratio / 2], [0.5 + ratio / 2]], dtype=np.float32)
645
- p0_3 = poly[0] + (poly[3] - poly[0]) * ratio_pair
646
- p1_2 = poly[1] + (poly[2] - poly[1]) * ratio_pair
647
- return np.array([p0_3[0], p1_2[0], p1_2[1], p0_3[1]])
648
-
649
- def poly2tcl(self, poly, ratio):
650
- """
651
- Generate center line by poly clock-wise point.
652
- """
653
- ratio_pair = np.array(
654
- [[0.5 - ratio / 2], [0.5 + ratio / 2]], dtype=np.float32)
655
- tcl_poly = np.zeros_like(poly)
656
- point_num = poly.shape[0]
657
-
658
- for idx in range(point_num // 2):
659
- point_pair = poly[idx] + (poly[point_num - 1 - idx] - poly[idx]
660
- ) * ratio_pair
661
- tcl_poly[idx] = point_pair[0]
662
- tcl_poly[point_num - 1 - idx] = point_pair[1]
663
- return tcl_poly
664
-
665
- def gen_quad_tbo(self, quad, tcl_mask, tbo_map):
666
- """
667
- Generate tbo_map for give quad.
668
- """
669
- # upper and lower line function: ax + by + c = 0;
670
- up_line = self.line_cross_two_point(quad[0], quad[1])
671
- lower_line = self.line_cross_two_point(quad[3], quad[2])
672
-
673
- quad_h = 0.5 * (np.linalg.norm(quad[0] - quad[3]) +
674
- np.linalg.norm(quad[1] - quad[2]))
675
- quad_w = 0.5 * (np.linalg.norm(quad[0] - quad[1]) +
676
- np.linalg.norm(quad[2] - quad[3]))
677
-
678
- # average angle of left and right line.
679
- angle = self.average_angle(quad)
680
-
681
- xy_in_poly = np.argwhere(tcl_mask == 1)
682
- for y, x in xy_in_poly:
683
- point = (x, y)
684
- line = self.theta_line_cross_point(angle, point)
685
- cross_point_upper = self.line_cross_point(up_line, line)
686
- cross_point_lower = self.line_cross_point(lower_line, line)
687
- ##FIX, offset reverse
688
- upper_offset_x, upper_offset_y = cross_point_upper - point
689
- lower_offset_x, lower_offset_y = cross_point_lower - point
690
- tbo_map[y, x, 0] = upper_offset_y
691
- tbo_map[y, x, 1] = upper_offset_x
692
- tbo_map[y, x, 2] = lower_offset_y
693
- tbo_map[y, x, 3] = lower_offset_x
694
- tbo_map[y, x, 4] = 1.0 / max(min(quad_h, quad_w), 1.0) * 2
695
- return tbo_map
696
-
697
- def poly2quads(self, poly):
698
- """
699
- Split poly into quads.
700
- """
701
- quad_list = []
702
- point_num = poly.shape[0]
703
-
704
- # point pair
705
- point_pair_list = []
706
- for idx in range(point_num // 2):
707
- point_pair = [poly[idx], poly[point_num - 1 - idx]]
708
- point_pair_list.append(point_pair)
709
-
710
- quad_num = point_num // 2 - 1
711
- for idx in range(quad_num):
712
- # reshape and adjust to clock-wise
713
- quad_list.append((np.array(point_pair_list)[[idx, idx + 1]]
714
- ).reshape(4, 2)[[0, 2, 3, 1]])
715
-
716
- return np.array(quad_list)
717
-
718
- def rotate_im_poly(self, im, text_polys):
719
- """
720
- rotate image with 90 / 180 / 270 degre
721
- """
722
- im_w, im_h = im.shape[1], im.shape[0]
723
- dst_im = im.copy()
724
- dst_polys = []
725
- rand_degree_ratio = np.random.rand()
726
- rand_degree_cnt = 1
727
- if rand_degree_ratio > 0.5:
728
- rand_degree_cnt = 3
729
- for i in range(rand_degree_cnt):
730
- dst_im = np.rot90(dst_im)
731
- rot_degree = -90 * rand_degree_cnt
732
- rot_angle = rot_degree * math.pi / 180.0
733
- n_poly = text_polys.shape[0]
734
- cx, cy = 0.5 * im_w, 0.5 * im_h
735
- ncx, ncy = 0.5 * dst_im.shape[1], 0.5 * dst_im.shape[0]
736
- for i in range(n_poly):
737
- wordBB = text_polys[i]
738
- poly = []
739
- for j in range(4): # 16->4
740
- sx, sy = wordBB[j][0], wordBB[j][1]
741
- dx = math.cos(rot_angle) * (sx - cx) - math.sin(rot_angle) * (
742
- sy - cy) + ncx
743
- dy = math.sin(rot_angle) * (sx - cx) + math.cos(rot_angle) * (
744
- sy - cy) + ncy
745
- poly.append([dx, dy])
746
- dst_polys.append(poly)
747
- return dst_im, np.array(dst_polys, dtype=np.float32)
748
-
749
- def __call__(self, data):
750
- input_size = 512
751
- im = data['image']
752
- text_polys = data['polys']
753
- text_tags = data['ignore_tags']
754
- text_strs = data['texts']
755
- h, w, _ = im.shape
756
- text_polys, text_tags, hv_tags = self.check_and_validate_polys(
757
- text_polys, text_tags, (h, w))
758
- if text_polys.shape[0] <= 0:
759
- return None
760
- # set aspect ratio and keep area fix
761
- asp_scales = np.arange(1.0, 1.55, 0.1)
762
- asp_scale = np.random.choice(asp_scales)
763
- if np.random.rand() < 0.5:
764
- asp_scale = 1.0 / asp_scale
765
- asp_scale = math.sqrt(asp_scale)
766
-
767
- asp_wx = asp_scale
768
- asp_hy = 1.0 / asp_scale
769
- im = cv2.resize(im, dsize=None, fx=asp_wx, fy=asp_hy)
770
- text_polys[:, :, 0] *= asp_wx
771
- text_polys[:, :, 1] *= asp_hy
772
-
773
- h, w, _ = im.shape
774
- if max(h, w) > 2048:
775
- rd_scale = 2048.0 / max(h, w)
776
- im = cv2.resize(im, dsize=None, fx=rd_scale, fy=rd_scale)
777
- text_polys *= rd_scale
778
- h, w, _ = im.shape
779
- if min(h, w) < 16:
780
- return None
781
-
782
- # no background
783
- im, text_polys, text_tags, hv_tags, text_strs = self.crop_area(
784
- im,
785
- text_polys,
786
- text_tags,
787
- hv_tags,
788
- text_strs,
789
- crop_background=False)
790
-
791
- if text_polys.shape[0] == 0:
792
- return None
793
- # # continue for all ignore case
794
- if np.sum((text_tags * 1.0)) >= text_tags.size:
795
- return None
796
- new_h, new_w, _ = im.shape
797
- if (new_h is None) or (new_w is None):
798
- return None
799
- # resize image
800
- std_ratio = float(input_size) / max(new_w, new_h)
801
- rand_scales = np.array(
802
- [0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.0, 1.0, 1.0, 1.0])
803
- rz_scale = std_ratio * np.random.choice(rand_scales)
804
- im = cv2.resize(im, dsize=None, fx=rz_scale, fy=rz_scale)
805
- text_polys[:, :, 0] *= rz_scale
806
- text_polys[:, :, 1] *= rz_scale
807
-
808
- # add gaussian blur
809
- if np.random.rand() < 0.1 * 0.5:
810
- ks = np.random.permutation(5)[0] + 1
811
- ks = int(ks / 2) * 2 + 1
812
- im = cv2.GaussianBlur(im, ksize=(ks, ks), sigmaX=0, sigmaY=0)
813
- # add brighter
814
- if np.random.rand() < 0.1 * 0.5:
815
- im = im * (1.0 + np.random.rand() * 0.5)
816
- im = np.clip(im, 0.0, 255.0)
817
- # add darker
818
- if np.random.rand() < 0.1 * 0.5:
819
- im = im * (1.0 - np.random.rand() * 0.5)
820
- im = np.clip(im, 0.0, 255.0)
821
-
822
- # Padding the im to [input_size, input_size]
823
- new_h, new_w, _ = im.shape
824
- if min(new_w, new_h) < input_size * 0.5:
825
- return None
826
- im_padded = np.ones((input_size, input_size, 3), dtype=np.float32)
827
- im_padded[:, :, 2] = 0.485 * 255
828
- im_padded[:, :, 1] = 0.456 * 255
829
- im_padded[:, :, 0] = 0.406 * 255
830
-
831
- # Random the start position
832
- del_h = input_size - new_h
833
- del_w = input_size - new_w
834
- sh, sw = 0, 0
835
- if del_h > 1:
836
- sh = int(np.random.rand() * del_h)
837
- if del_w > 1:
838
- sw = int(np.random.rand() * del_w)
839
-
840
- # Padding
841
- im_padded[sh:sh + new_h, sw:sw + new_w, :] = im.copy()
842
- text_polys[:, :, 0] += sw
843
- text_polys[:, :, 1] += sh
844
-
845
- score_map, score_label_map, border_map, direction_map, training_mask, \
846
- pos_list, pos_mask, label_list, score_label_map_text_label = self.generate_tcl_ctc_label(input_size,
847
- input_size,
848
- text_polys,
849
- text_tags,
850
- text_strs, 0.25)
851
- if len(label_list) <= 0: # eliminate negative samples
852
- return None
853
- pos_list_temp = np.zeros([64, 3])
854
- pos_mask_temp = np.zeros([64, 1])
855
- label_list_temp = np.zeros([self.max_text_length, 1]) + self.pad_num
856
-
857
- for i, label in enumerate(label_list):
858
- n = len(label)
859
- if n > self.max_text_length:
860
- label_list[i] = label[:self.max_text_length]
861
- continue
862
- while n < self.max_text_length:
863
- label.append([self.pad_num])
864
- n += 1
865
-
866
- for i in range(len(label_list)):
867
- label_list[i] = np.array(label_list[i])
868
-
869
- if len(pos_list) <= 0 or len(pos_list) > self.max_text_nums:
870
- return None
871
- for __ in range(self.max_text_nums - len(pos_list), 0, -1):
872
- pos_list.append(pos_list_temp)
873
- pos_mask.append(pos_mask_temp)
874
- label_list.append(label_list_temp)
875
-
876
- if self.img_id == self.batch_size - 1:
877
- self.img_id = 0
878
- else:
879
- self.img_id += 1
880
-
881
- im_padded[:, :, 2] -= 0.485 * 255
882
- im_padded[:, :, 1] -= 0.456 * 255
883
- im_padded[:, :, 0] -= 0.406 * 255
884
- im_padded[:, :, 2] /= (255.0 * 0.229)
885
- im_padded[:, :, 1] /= (255.0 * 0.224)
886
- im_padded[:, :, 0] /= (255.0 * 0.225)
887
- im_padded = im_padded.transpose((2, 0, 1))
888
- images = im_padded[::-1, :, :]
889
- tcl_maps = score_map[np.newaxis, :, :]
890
- tcl_label_maps = score_label_map[np.newaxis, :, :]
891
- border_maps = border_map.transpose((2, 0, 1))
892
- direction_maps = direction_map.transpose((2, 0, 1))
893
- training_masks = training_mask[np.newaxis, :, :]
894
- pos_list = np.array(pos_list)
895
- pos_mask = np.array(pos_mask)
896
- label_list = np.array(label_list)
897
- data['images'] = images
898
- data['tcl_maps'] = tcl_maps
899
- data['tcl_label_maps'] = tcl_label_maps
900
- data['border_maps'] = border_maps
901
- data['direction_maps'] = direction_maps
902
- data['training_masks'] = training_masks
903
- data['label_list'] = label_list
904
- data['pos_list'] = pos_list
905
- data['pos_mask'] = pos_mask
906
- return data