pyxllib 0.3.96__py3-none-any.whl → 0.3.197__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 (306) hide show
  1. pyxllib/algo/geo.py +12 -0
  2. pyxllib/algo/intervals.py +1 -1
  3. pyxllib/algo/matcher.py +78 -0
  4. pyxllib/algo/pupil.py +187 -19
  5. pyxllib/algo/specialist.py +2 -1
  6. pyxllib/algo/stat.py +38 -2
  7. {pyxlpr → pyxllib/autogui}/__init__.py +1 -1
  8. pyxllib/autogui/activewin.py +246 -0
  9. pyxllib/autogui/all.py +9 -0
  10. pyxllib/{ext/autogui → autogui}/autogui.py +40 -11
  11. pyxllib/autogui/uiautolib.py +362 -0
  12. pyxllib/autogui/wechat.py +827 -0
  13. pyxllib/autogui/wechat_msg.py +421 -0
  14. pyxllib/autogui/wxautolib.py +84 -0
  15. pyxllib/cv/slidercaptcha.py +137 -0
  16. pyxllib/data/echarts.py +123 -12
  17. pyxllib/data/jsonlib.py +89 -0
  18. pyxllib/data/pglib.py +514 -30
  19. pyxllib/data/sqlite.py +231 -4
  20. pyxllib/ext/JLineViewer.py +14 -1
  21. pyxllib/ext/drissionlib.py +277 -0
  22. pyxllib/ext/kq5034lib.py +0 -1594
  23. pyxllib/ext/robustprocfile.py +497 -0
  24. pyxllib/ext/unixlib.py +6 -5
  25. pyxllib/ext/utools.py +108 -95
  26. pyxllib/ext/webhook.py +32 -14
  27. pyxllib/ext/wjxlib.py +88 -0
  28. pyxllib/ext/wpsapi.py +124 -0
  29. pyxllib/ext/xlwork.py +9 -0
  30. pyxllib/ext/yuquelib.py +1003 -71
  31. pyxllib/file/docxlib.py +1 -1
  32. pyxllib/file/libreoffice.py +165 -0
  33. pyxllib/file/movielib.py +9 -0
  34. pyxllib/file/packlib/__init__.py +112 -75
  35. pyxllib/file/pdflib.py +1 -1
  36. pyxllib/file/pupil.py +1 -1
  37. pyxllib/file/specialist/dirlib.py +1 -1
  38. pyxllib/file/specialist/download.py +10 -3
  39. pyxllib/file/specialist/filelib.py +266 -55
  40. pyxllib/file/xlsxlib.py +205 -50
  41. pyxllib/file/xlsyncfile.py +341 -0
  42. pyxllib/prog/cachetools.py +64 -0
  43. pyxllib/prog/filelock.py +42 -0
  44. pyxllib/prog/multiprogs.py +940 -0
  45. pyxllib/prog/newbie.py +9 -2
  46. pyxllib/prog/pupil.py +129 -60
  47. pyxllib/prog/specialist/__init__.py +176 -2
  48. pyxllib/prog/specialist/bc.py +5 -2
  49. pyxllib/prog/specialist/browser.py +11 -2
  50. pyxllib/prog/specialist/datetime.py +68 -0
  51. pyxllib/prog/specialist/tictoc.py +12 -13
  52. pyxllib/prog/specialist/xllog.py +5 -5
  53. pyxllib/prog/xlosenv.py +7 -0
  54. pyxllib/text/airscript.js +744 -0
  55. pyxllib/text/charclasslib.py +17 -5
  56. pyxllib/text/jiebalib.py +6 -3
  57. pyxllib/text/jinjalib.py +32 -0
  58. pyxllib/text/jsa_ai_prompt.md +271 -0
  59. pyxllib/text/jscode.py +159 -4
  60. pyxllib/text/nestenv.py +1 -1
  61. pyxllib/text/newbie.py +12 -0
  62. pyxllib/text/pupil/common.py +26 -0
  63. pyxllib/text/specialist/ptag.py +2 -2
  64. pyxllib/text/templates/echart_base.html +11 -0
  65. pyxllib/text/templates/highlight_code.html +17 -0
  66. pyxllib/text/templates/latex_editor.html +103 -0
  67. pyxllib/text/xmllib.py +76 -14
  68. pyxllib/xl.py +2 -1
  69. pyxllib-0.3.197.dist-info/METADATA +48 -0
  70. pyxllib-0.3.197.dist-info/RECORD +126 -0
  71. {pyxllib-0.3.96.dist-info → pyxllib-0.3.197.dist-info}/WHEEL +1 -2
  72. pyxllib/ext/autogui/__init__.py +0 -8
  73. pyxllib-0.3.96.dist-info/METADATA +0 -51
  74. pyxllib-0.3.96.dist-info/RECORD +0 -333
  75. pyxllib-0.3.96.dist-info/top_level.txt +0 -2
  76. pyxlpr/ai/__init__.py +0 -5
  77. pyxlpr/ai/clientlib.py +0 -1281
  78. pyxlpr/ai/specialist.py +0 -286
  79. pyxlpr/ai/torch_app.py +0 -172
  80. pyxlpr/ai/xlpaddle.py +0 -655
  81. pyxlpr/ai/xltorch.py +0 -705
  82. pyxlpr/data/__init__.py +0 -11
  83. pyxlpr/data/coco.py +0 -1325
  84. pyxlpr/data/datacls.py +0 -365
  85. pyxlpr/data/datasets.py +0 -200
  86. pyxlpr/data/gptlib.py +0 -1291
  87. pyxlpr/data/icdar/__init__.py +0 -96
  88. pyxlpr/data/icdar/deteval.py +0 -377
  89. pyxlpr/data/icdar/icdar2013.py +0 -341
  90. pyxlpr/data/icdar/iou.py +0 -340
  91. pyxlpr/data/icdar/rrc_evaluation_funcs_1_1.py +0 -463
  92. pyxlpr/data/imtextline.py +0 -473
  93. pyxlpr/data/labelme.py +0 -866
  94. pyxlpr/data/removeline.py +0 -179
  95. pyxlpr/data/specialist.py +0 -57
  96. pyxlpr/eval/__init__.py +0 -85
  97. pyxlpr/paddleocr.py +0 -776
  98. pyxlpr/ppocr/__init__.py +0 -15
  99. pyxlpr/ppocr/configs/rec/multi_language/generate_multi_language_configs.py +0 -226
  100. pyxlpr/ppocr/data/__init__.py +0 -135
  101. pyxlpr/ppocr/data/imaug/ColorJitter.py +0 -26
  102. pyxlpr/ppocr/data/imaug/__init__.py +0 -67
  103. pyxlpr/ppocr/data/imaug/copy_paste.py +0 -170
  104. pyxlpr/ppocr/data/imaug/east_process.py +0 -437
  105. pyxlpr/ppocr/data/imaug/gen_table_mask.py +0 -244
  106. pyxlpr/ppocr/data/imaug/iaa_augment.py +0 -114
  107. pyxlpr/ppocr/data/imaug/label_ops.py +0 -789
  108. pyxlpr/ppocr/data/imaug/make_border_map.py +0 -184
  109. pyxlpr/ppocr/data/imaug/make_pse_gt.py +0 -106
  110. pyxlpr/ppocr/data/imaug/make_shrink_map.py +0 -126
  111. pyxlpr/ppocr/data/imaug/operators.py +0 -433
  112. pyxlpr/ppocr/data/imaug/pg_process.py +0 -906
  113. pyxlpr/ppocr/data/imaug/randaugment.py +0 -143
  114. pyxlpr/ppocr/data/imaug/random_crop_data.py +0 -239
  115. pyxlpr/ppocr/data/imaug/rec_img_aug.py +0 -533
  116. pyxlpr/ppocr/data/imaug/sast_process.py +0 -777
  117. pyxlpr/ppocr/data/imaug/text_image_aug/__init__.py +0 -17
  118. pyxlpr/ppocr/data/imaug/text_image_aug/augment.py +0 -120
  119. pyxlpr/ppocr/data/imaug/text_image_aug/warp_mls.py +0 -168
  120. pyxlpr/ppocr/data/lmdb_dataset.py +0 -115
  121. pyxlpr/ppocr/data/pgnet_dataset.py +0 -104
  122. pyxlpr/ppocr/data/pubtab_dataset.py +0 -107
  123. pyxlpr/ppocr/data/simple_dataset.py +0 -372
  124. pyxlpr/ppocr/losses/__init__.py +0 -61
  125. pyxlpr/ppocr/losses/ace_loss.py +0 -52
  126. pyxlpr/ppocr/losses/basic_loss.py +0 -135
  127. pyxlpr/ppocr/losses/center_loss.py +0 -88
  128. pyxlpr/ppocr/losses/cls_loss.py +0 -30
  129. pyxlpr/ppocr/losses/combined_loss.py +0 -67
  130. pyxlpr/ppocr/losses/det_basic_loss.py +0 -208
  131. pyxlpr/ppocr/losses/det_db_loss.py +0 -80
  132. pyxlpr/ppocr/losses/det_east_loss.py +0 -63
  133. pyxlpr/ppocr/losses/det_pse_loss.py +0 -149
  134. pyxlpr/ppocr/losses/det_sast_loss.py +0 -121
  135. pyxlpr/ppocr/losses/distillation_loss.py +0 -272
  136. pyxlpr/ppocr/losses/e2e_pg_loss.py +0 -140
  137. pyxlpr/ppocr/losses/kie_sdmgr_loss.py +0 -113
  138. pyxlpr/ppocr/losses/rec_aster_loss.py +0 -99
  139. pyxlpr/ppocr/losses/rec_att_loss.py +0 -39
  140. pyxlpr/ppocr/losses/rec_ctc_loss.py +0 -44
  141. pyxlpr/ppocr/losses/rec_enhanced_ctc_loss.py +0 -70
  142. pyxlpr/ppocr/losses/rec_nrtr_loss.py +0 -30
  143. pyxlpr/ppocr/losses/rec_sar_loss.py +0 -28
  144. pyxlpr/ppocr/losses/rec_srn_loss.py +0 -47
  145. pyxlpr/ppocr/losses/table_att_loss.py +0 -109
  146. pyxlpr/ppocr/metrics/__init__.py +0 -44
  147. pyxlpr/ppocr/metrics/cls_metric.py +0 -45
  148. pyxlpr/ppocr/metrics/det_metric.py +0 -82
  149. pyxlpr/ppocr/metrics/distillation_metric.py +0 -73
  150. pyxlpr/ppocr/metrics/e2e_metric.py +0 -86
  151. pyxlpr/ppocr/metrics/eval_det_iou.py +0 -274
  152. pyxlpr/ppocr/metrics/kie_metric.py +0 -70
  153. pyxlpr/ppocr/metrics/rec_metric.py +0 -75
  154. pyxlpr/ppocr/metrics/table_metric.py +0 -50
  155. pyxlpr/ppocr/modeling/architectures/__init__.py +0 -32
  156. pyxlpr/ppocr/modeling/architectures/base_model.py +0 -88
  157. pyxlpr/ppocr/modeling/architectures/distillation_model.py +0 -60
  158. pyxlpr/ppocr/modeling/backbones/__init__.py +0 -54
  159. pyxlpr/ppocr/modeling/backbones/det_mobilenet_v3.py +0 -268
  160. pyxlpr/ppocr/modeling/backbones/det_resnet_vd.py +0 -246
  161. pyxlpr/ppocr/modeling/backbones/det_resnet_vd_sast.py +0 -285
  162. pyxlpr/ppocr/modeling/backbones/e2e_resnet_vd_pg.py +0 -265
  163. pyxlpr/ppocr/modeling/backbones/kie_unet_sdmgr.py +0 -186
  164. pyxlpr/ppocr/modeling/backbones/rec_mobilenet_v3.py +0 -138
  165. pyxlpr/ppocr/modeling/backbones/rec_mv1_enhance.py +0 -258
  166. pyxlpr/ppocr/modeling/backbones/rec_nrtr_mtb.py +0 -48
  167. pyxlpr/ppocr/modeling/backbones/rec_resnet_31.py +0 -210
  168. pyxlpr/ppocr/modeling/backbones/rec_resnet_aster.py +0 -143
  169. pyxlpr/ppocr/modeling/backbones/rec_resnet_fpn.py +0 -307
  170. pyxlpr/ppocr/modeling/backbones/rec_resnet_vd.py +0 -286
  171. pyxlpr/ppocr/modeling/heads/__init__.py +0 -54
  172. pyxlpr/ppocr/modeling/heads/cls_head.py +0 -52
  173. pyxlpr/ppocr/modeling/heads/det_db_head.py +0 -118
  174. pyxlpr/ppocr/modeling/heads/det_east_head.py +0 -121
  175. pyxlpr/ppocr/modeling/heads/det_pse_head.py +0 -37
  176. pyxlpr/ppocr/modeling/heads/det_sast_head.py +0 -128
  177. pyxlpr/ppocr/modeling/heads/e2e_pg_head.py +0 -253
  178. pyxlpr/ppocr/modeling/heads/kie_sdmgr_head.py +0 -206
  179. pyxlpr/ppocr/modeling/heads/multiheadAttention.py +0 -163
  180. pyxlpr/ppocr/modeling/heads/rec_aster_head.py +0 -393
  181. pyxlpr/ppocr/modeling/heads/rec_att_head.py +0 -202
  182. pyxlpr/ppocr/modeling/heads/rec_ctc_head.py +0 -88
  183. pyxlpr/ppocr/modeling/heads/rec_nrtr_head.py +0 -826
  184. pyxlpr/ppocr/modeling/heads/rec_sar_head.py +0 -402
  185. pyxlpr/ppocr/modeling/heads/rec_srn_head.py +0 -280
  186. pyxlpr/ppocr/modeling/heads/self_attention.py +0 -406
  187. pyxlpr/ppocr/modeling/heads/table_att_head.py +0 -246
  188. pyxlpr/ppocr/modeling/necks/__init__.py +0 -32
  189. pyxlpr/ppocr/modeling/necks/db_fpn.py +0 -111
  190. pyxlpr/ppocr/modeling/necks/east_fpn.py +0 -188
  191. pyxlpr/ppocr/modeling/necks/fpn.py +0 -138
  192. pyxlpr/ppocr/modeling/necks/pg_fpn.py +0 -314
  193. pyxlpr/ppocr/modeling/necks/rnn.py +0 -92
  194. pyxlpr/ppocr/modeling/necks/sast_fpn.py +0 -284
  195. pyxlpr/ppocr/modeling/necks/table_fpn.py +0 -110
  196. pyxlpr/ppocr/modeling/transforms/__init__.py +0 -28
  197. pyxlpr/ppocr/modeling/transforms/stn.py +0 -135
  198. pyxlpr/ppocr/modeling/transforms/tps.py +0 -308
  199. pyxlpr/ppocr/modeling/transforms/tps_spatial_transformer.py +0 -156
  200. pyxlpr/ppocr/optimizer/__init__.py +0 -61
  201. pyxlpr/ppocr/optimizer/learning_rate.py +0 -228
  202. pyxlpr/ppocr/optimizer/lr_scheduler.py +0 -49
  203. pyxlpr/ppocr/optimizer/optimizer.py +0 -160
  204. pyxlpr/ppocr/optimizer/regularizer.py +0 -52
  205. pyxlpr/ppocr/postprocess/__init__.py +0 -55
  206. pyxlpr/ppocr/postprocess/cls_postprocess.py +0 -33
  207. pyxlpr/ppocr/postprocess/db_postprocess.py +0 -234
  208. pyxlpr/ppocr/postprocess/east_postprocess.py +0 -143
  209. pyxlpr/ppocr/postprocess/locality_aware_nms.py +0 -200
  210. pyxlpr/ppocr/postprocess/pg_postprocess.py +0 -52
  211. pyxlpr/ppocr/postprocess/pse_postprocess/__init__.py +0 -15
  212. pyxlpr/ppocr/postprocess/pse_postprocess/pse/__init__.py +0 -29
  213. pyxlpr/ppocr/postprocess/pse_postprocess/pse/setup.py +0 -14
  214. pyxlpr/ppocr/postprocess/pse_postprocess/pse_postprocess.py +0 -118
  215. pyxlpr/ppocr/postprocess/rec_postprocess.py +0 -654
  216. pyxlpr/ppocr/postprocess/sast_postprocess.py +0 -355
  217. pyxlpr/ppocr/tools/__init__.py +0 -14
  218. pyxlpr/ppocr/tools/eval.py +0 -83
  219. pyxlpr/ppocr/tools/export_center.py +0 -77
  220. pyxlpr/ppocr/tools/export_model.py +0 -129
  221. pyxlpr/ppocr/tools/infer/predict_cls.py +0 -151
  222. pyxlpr/ppocr/tools/infer/predict_det.py +0 -300
  223. pyxlpr/ppocr/tools/infer/predict_e2e.py +0 -169
  224. pyxlpr/ppocr/tools/infer/predict_rec.py +0 -414
  225. pyxlpr/ppocr/tools/infer/predict_system.py +0 -204
  226. pyxlpr/ppocr/tools/infer/utility.py +0 -629
  227. pyxlpr/ppocr/tools/infer_cls.py +0 -83
  228. pyxlpr/ppocr/tools/infer_det.py +0 -134
  229. pyxlpr/ppocr/tools/infer_e2e.py +0 -122
  230. pyxlpr/ppocr/tools/infer_kie.py +0 -153
  231. pyxlpr/ppocr/tools/infer_rec.py +0 -146
  232. pyxlpr/ppocr/tools/infer_table.py +0 -107
  233. pyxlpr/ppocr/tools/program.py +0 -596
  234. pyxlpr/ppocr/tools/test_hubserving.py +0 -117
  235. pyxlpr/ppocr/tools/train.py +0 -163
  236. pyxlpr/ppocr/tools/xlprog.py +0 -748
  237. pyxlpr/ppocr/utils/EN_symbol_dict.txt +0 -94
  238. pyxlpr/ppocr/utils/__init__.py +0 -24
  239. pyxlpr/ppocr/utils/dict/ar_dict.txt +0 -117
  240. pyxlpr/ppocr/utils/dict/arabic_dict.txt +0 -162
  241. pyxlpr/ppocr/utils/dict/be_dict.txt +0 -145
  242. pyxlpr/ppocr/utils/dict/bg_dict.txt +0 -140
  243. pyxlpr/ppocr/utils/dict/chinese_cht_dict.txt +0 -8421
  244. pyxlpr/ppocr/utils/dict/cyrillic_dict.txt +0 -163
  245. pyxlpr/ppocr/utils/dict/devanagari_dict.txt +0 -167
  246. pyxlpr/ppocr/utils/dict/en_dict.txt +0 -63
  247. pyxlpr/ppocr/utils/dict/fa_dict.txt +0 -136
  248. pyxlpr/ppocr/utils/dict/french_dict.txt +0 -136
  249. pyxlpr/ppocr/utils/dict/german_dict.txt +0 -143
  250. pyxlpr/ppocr/utils/dict/hi_dict.txt +0 -162
  251. pyxlpr/ppocr/utils/dict/it_dict.txt +0 -118
  252. pyxlpr/ppocr/utils/dict/japan_dict.txt +0 -4399
  253. pyxlpr/ppocr/utils/dict/ka_dict.txt +0 -153
  254. pyxlpr/ppocr/utils/dict/korean_dict.txt +0 -3688
  255. pyxlpr/ppocr/utils/dict/latin_dict.txt +0 -185
  256. pyxlpr/ppocr/utils/dict/mr_dict.txt +0 -153
  257. pyxlpr/ppocr/utils/dict/ne_dict.txt +0 -153
  258. pyxlpr/ppocr/utils/dict/oc_dict.txt +0 -96
  259. pyxlpr/ppocr/utils/dict/pu_dict.txt +0 -130
  260. pyxlpr/ppocr/utils/dict/rs_dict.txt +0 -91
  261. pyxlpr/ppocr/utils/dict/rsc_dict.txt +0 -134
  262. pyxlpr/ppocr/utils/dict/ru_dict.txt +0 -125
  263. pyxlpr/ppocr/utils/dict/ta_dict.txt +0 -128
  264. pyxlpr/ppocr/utils/dict/table_dict.txt +0 -277
  265. pyxlpr/ppocr/utils/dict/table_structure_dict.txt +0 -2759
  266. pyxlpr/ppocr/utils/dict/te_dict.txt +0 -151
  267. pyxlpr/ppocr/utils/dict/ug_dict.txt +0 -114
  268. pyxlpr/ppocr/utils/dict/uk_dict.txt +0 -142
  269. pyxlpr/ppocr/utils/dict/ur_dict.txt +0 -137
  270. pyxlpr/ppocr/utils/dict/xi_dict.txt +0 -110
  271. pyxlpr/ppocr/utils/dict90.txt +0 -90
  272. pyxlpr/ppocr/utils/e2e_metric/Deteval.py +0 -574
  273. pyxlpr/ppocr/utils/e2e_metric/polygon_fast.py +0 -83
  274. pyxlpr/ppocr/utils/e2e_utils/extract_batchsize.py +0 -87
  275. pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_fast.py +0 -457
  276. pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_slow.py +0 -592
  277. pyxlpr/ppocr/utils/e2e_utils/pgnet_pp_utils.py +0 -162
  278. pyxlpr/ppocr/utils/e2e_utils/visual.py +0 -162
  279. pyxlpr/ppocr/utils/en_dict.txt +0 -95
  280. pyxlpr/ppocr/utils/gen_label.py +0 -81
  281. pyxlpr/ppocr/utils/ic15_dict.txt +0 -36
  282. pyxlpr/ppocr/utils/iou.py +0 -54
  283. pyxlpr/ppocr/utils/logging.py +0 -69
  284. pyxlpr/ppocr/utils/network.py +0 -84
  285. pyxlpr/ppocr/utils/ppocr_keys_v1.txt +0 -6623
  286. pyxlpr/ppocr/utils/profiler.py +0 -110
  287. pyxlpr/ppocr/utils/save_load.py +0 -150
  288. pyxlpr/ppocr/utils/stats.py +0 -72
  289. pyxlpr/ppocr/utils/utility.py +0 -80
  290. pyxlpr/ppstructure/__init__.py +0 -13
  291. pyxlpr/ppstructure/predict_system.py +0 -187
  292. pyxlpr/ppstructure/table/__init__.py +0 -13
  293. pyxlpr/ppstructure/table/eval_table.py +0 -72
  294. pyxlpr/ppstructure/table/matcher.py +0 -192
  295. pyxlpr/ppstructure/table/predict_structure.py +0 -136
  296. pyxlpr/ppstructure/table/predict_table.py +0 -221
  297. pyxlpr/ppstructure/table/table_metric/__init__.py +0 -16
  298. pyxlpr/ppstructure/table/table_metric/parallel.py +0 -51
  299. pyxlpr/ppstructure/table/table_metric/table_metric.py +0 -247
  300. pyxlpr/ppstructure/table/tablepyxl/__init__.py +0 -13
  301. pyxlpr/ppstructure/table/tablepyxl/style.py +0 -283
  302. pyxlpr/ppstructure/table/tablepyxl/tablepyxl.py +0 -118
  303. pyxlpr/ppstructure/utility.py +0 -71
  304. pyxlpr/xlai.py +0 -10
  305. /pyxllib/{ext/autogui → autogui}/virtualkey.py +0 -0
  306. {pyxllib-0.3.96.dist-info → pyxllib-0.3.197.dist-info/licenses}/LICENSE +0 -0
@@ -1,777 +0,0 @@
1
- #copyright (c) 2020 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
- This part code is refered from:
16
- https://github.com/songdejia/EAST/blob/master/data_utils.py
17
- """
18
- import math
19
- import cv2
20
- import numpy as np
21
- import json
22
- import sys
23
- import os
24
-
25
- __all__ = ['SASTProcessTrain']
26
-
27
-
28
- class SASTProcessTrain(object):
29
- def __init__(self,
30
- image_shape=[512, 512],
31
- min_crop_size=24,
32
- min_crop_side_ratio=0.3,
33
- min_text_size=10,
34
- max_text_size=512,
35
- **kwargs):
36
- self.input_size = image_shape[1]
37
- self.min_crop_size = min_crop_size
38
- self.min_crop_side_ratio = min_crop_side_ratio
39
- self.min_text_size = min_text_size
40
- self.max_text_size = max_text_size
41
-
42
- def quad_area(self, poly):
43
- """
44
- compute area of a polygon
45
- :param poly:
46
- :return:
47
- """
48
- edge = [(poly[1][0] - poly[0][0]) * (poly[1][1] + poly[0][1]),
49
- (poly[2][0] - poly[1][0]) * (poly[2][1] + poly[1][1]),
50
- (poly[3][0] - poly[2][0]) * (poly[3][1] + poly[2][1]),
51
- (poly[0][0] - poly[3][0]) * (poly[0][1] + poly[3][1])]
52
- return np.sum(edge) / 2.
53
-
54
- def gen_quad_from_poly(self, poly):
55
- """
56
- Generate min area quad from poly.
57
- """
58
- point_num = poly.shape[0]
59
- min_area_quad = np.zeros((4, 2), dtype=np.float32)
60
- if True:
61
- rect = cv2.minAreaRect(poly.astype(
62
- np.int32)) # (center (x,y), (width, height), angle of rotation)
63
- center_point = rect[0]
64
- box = np.array(cv2.boxPoints(rect))
65
-
66
- first_point_idx = 0
67
- min_dist = 1e4
68
- for i in range(4):
69
- dist = np.linalg.norm(box[(i + 0) % 4] - poly[0]) + \
70
- np.linalg.norm(box[(i + 1) % 4] - poly[point_num // 2 - 1]) + \
71
- np.linalg.norm(box[(i + 2) % 4] - poly[point_num // 2]) + \
72
- np.linalg.norm(box[(i + 3) % 4] - poly[-1])
73
- if dist < min_dist:
74
- min_dist = dist
75
- first_point_idx = i
76
- for i in range(4):
77
- min_area_quad[i] = box[(first_point_idx + i) % 4]
78
-
79
- return min_area_quad
80
-
81
- def check_and_validate_polys(self, polys, tags, xxx_todo_changeme):
82
- """
83
- check so that the text poly is in the same direction,
84
- and also filter some invalid polygons
85
- :param polys:
86
- :param tags:
87
- :return:
88
- """
89
- (h, w) = xxx_todo_changeme
90
- if polys.shape[0] == 0:
91
- return polys, np.array([]), np.array([])
92
- polys[:, :, 0] = np.clip(polys[:, :, 0], 0, w - 1)
93
- polys[:, :, 1] = np.clip(polys[:, :, 1], 0, h - 1)
94
-
95
- validated_polys = []
96
- validated_tags = []
97
- hv_tags = []
98
- for poly, tag in zip(polys, tags):
99
- quad = self.gen_quad_from_poly(poly)
100
- p_area = self.quad_area(quad)
101
- if abs(p_area) < 1:
102
- print('invalid poly')
103
- continue
104
- if p_area > 0:
105
- if tag == False:
106
- print('poly in wrong direction')
107
- tag = True # reversed cases should be ignore
108
- poly = poly[(0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
109
- 1), :]
110
- quad = quad[(0, 3, 2, 1), :]
111
-
112
- len_w = np.linalg.norm(quad[0] - quad[1]) + np.linalg.norm(quad[3] -
113
- quad[2])
114
- len_h = np.linalg.norm(quad[0] - quad[3]) + np.linalg.norm(quad[1] -
115
- quad[2])
116
- hv_tag = 1
117
-
118
- if len_w * 2.0 < len_h:
119
- hv_tag = 0
120
-
121
- validated_polys.append(poly)
122
- validated_tags.append(tag)
123
- hv_tags.append(hv_tag)
124
- return np.array(validated_polys), np.array(validated_tags), np.array(
125
- hv_tags)
126
-
127
- def crop_area(self,
128
- im,
129
- polys,
130
- tags,
131
- hv_tags,
132
- crop_background=False,
133
- max_tries=25):
134
- """
135
- make random crop from the input image
136
- :param im:
137
- :param polys:
138
- :param tags:
139
- :param crop_background:
140
- :param max_tries: 50 -> 25
141
- :return:
142
- """
143
- h, w, _ = im.shape
144
- pad_h = h // 10
145
- pad_w = w // 10
146
- h_array = np.zeros((h + pad_h * 2), dtype=np.int32)
147
- w_array = np.zeros((w + pad_w * 2), dtype=np.int32)
148
- for poly in polys:
149
- poly = np.round(poly, decimals=0).astype(np.int32)
150
- minx = np.min(poly[:, 0])
151
- maxx = np.max(poly[:, 0])
152
- w_array[minx + pad_w:maxx + pad_w] = 1
153
- miny = np.min(poly[:, 1])
154
- maxy = np.max(poly[:, 1])
155
- h_array[miny + pad_h:maxy + pad_h] = 1
156
- # ensure the cropped area not across a text
157
- h_axis = np.where(h_array == 0)[0]
158
- w_axis = np.where(w_array == 0)[0]
159
- if len(h_axis) == 0 or len(w_axis) == 0:
160
- return im, polys, tags, hv_tags
161
- for i in range(max_tries):
162
- xx = np.random.choice(w_axis, size=2)
163
- xmin = np.min(xx) - pad_w
164
- xmax = np.max(xx) - pad_w
165
- xmin = np.clip(xmin, 0, w - 1)
166
- xmax = np.clip(xmax, 0, w - 1)
167
- yy = np.random.choice(h_axis, size=2)
168
- ymin = np.min(yy) - pad_h
169
- ymax = np.max(yy) - pad_h
170
- ymin = np.clip(ymin, 0, h - 1)
171
- ymax = np.clip(ymax, 0, h - 1)
172
- # if xmax - xmin < ARGS.min_crop_side_ratio * w or \
173
- # ymax - ymin < ARGS.min_crop_side_ratio * h:
174
- if xmax - xmin < self.min_crop_size or \
175
- ymax - ymin < self.min_crop_size:
176
- # area too small
177
- continue
178
- if polys.shape[0] != 0:
179
- poly_axis_in_area = (polys[:, :, 0] >= xmin) & (polys[:, :, 0] <= xmax) \
180
- & (polys[:, :, 1] >= ymin) & (polys[:, :, 1] <= ymax)
181
- selected_polys = np.where(
182
- np.sum(poly_axis_in_area, axis=1) == 4)[0]
183
- else:
184
- selected_polys = []
185
- if len(selected_polys) == 0:
186
- # no text in this area
187
- if crop_background:
188
- return im[ymin : ymax + 1, xmin : xmax + 1, :], \
189
- polys[selected_polys], tags[selected_polys], hv_tags[selected_polys]
190
- else:
191
- continue
192
- im = im[ymin:ymax + 1, xmin:xmax + 1, :]
193
- polys = polys[selected_polys]
194
- tags = tags[selected_polys]
195
- hv_tags = hv_tags[selected_polys]
196
- polys[:, :, 0] -= xmin
197
- polys[:, :, 1] -= ymin
198
- return im, polys, tags, hv_tags
199
-
200
- return im, polys, tags, hv_tags
201
-
202
- def generate_direction_map(self, poly_quads, direction_map):
203
- """
204
- """
205
- width_list = []
206
- height_list = []
207
- for quad in poly_quads:
208
- quad_w = (np.linalg.norm(quad[0] - quad[1]) +
209
- np.linalg.norm(quad[2] - quad[3])) / 2.0
210
- quad_h = (np.linalg.norm(quad[0] - quad[3]) +
211
- np.linalg.norm(quad[2] - quad[1])) / 2.0
212
- width_list.append(quad_w)
213
- height_list.append(quad_h)
214
- norm_width = max(sum(width_list) / (len(width_list) + 1e-6), 1.0)
215
- average_height = max(sum(height_list) / (len(height_list) + 1e-6), 1.0)
216
-
217
- for quad in poly_quads:
218
- direct_vector_full = (
219
- (quad[1] + quad[2]) - (quad[0] + quad[3])) / 2.0
220
- direct_vector = direct_vector_full / (
221
- np.linalg.norm(direct_vector_full) + 1e-6) * norm_width
222
- direction_label = tuple(
223
- map(float, [
224
- direct_vector[0], direct_vector[1], 1.0 / (average_height +
225
- 1e-6)
226
- ]))
227
- cv2.fillPoly(direction_map,
228
- quad.round().astype(np.int32)[np.newaxis, :, :],
229
- direction_label)
230
- return direction_map
231
-
232
- def calculate_average_height(self, poly_quads):
233
- """
234
- """
235
- height_list = []
236
- for quad in poly_quads:
237
- quad_h = (np.linalg.norm(quad[0] - quad[3]) +
238
- np.linalg.norm(quad[2] - quad[1])) / 2.0
239
- height_list.append(quad_h)
240
- average_height = max(sum(height_list) / len(height_list), 1.0)
241
- return average_height
242
-
243
- def generate_tcl_label(self,
244
- hw,
245
- polys,
246
- tags,
247
- ds_ratio,
248
- tcl_ratio=0.3,
249
- shrink_ratio_of_width=0.15):
250
- """
251
- Generate polygon.
252
- """
253
- h, w = hw
254
- h, w = int(h * ds_ratio), int(w * ds_ratio)
255
- polys = polys * ds_ratio
256
-
257
- score_map = np.zeros(
258
- (
259
- h,
260
- w, ), dtype=np.float32)
261
- tbo_map = np.zeros((h, w, 5), dtype=np.float32)
262
- training_mask = np.ones(
263
- (
264
- h,
265
- w, ), dtype=np.float32)
266
- direction_map = np.ones((h, w, 3)) * np.array([0, 0, 1]).reshape(
267
- [1, 1, 3]).astype(np.float32)
268
-
269
- for poly_idx, poly_tag in enumerate(zip(polys, tags)):
270
- poly = poly_tag[0]
271
- tag = poly_tag[1]
272
-
273
- # generate min_area_quad
274
- min_area_quad, center_point = self.gen_min_area_quad_from_poly(poly)
275
- min_area_quad_h = 0.5 * (
276
- np.linalg.norm(min_area_quad[0] - min_area_quad[3]) +
277
- np.linalg.norm(min_area_quad[1] - min_area_quad[2]))
278
- min_area_quad_w = 0.5 * (
279
- np.linalg.norm(min_area_quad[0] - min_area_quad[1]) +
280
- np.linalg.norm(min_area_quad[2] - min_area_quad[3]))
281
-
282
- if min(min_area_quad_h, min_area_quad_w) < self.min_text_size * ds_ratio \
283
- or min(min_area_quad_h, min_area_quad_w) > self.max_text_size * ds_ratio:
284
- continue
285
-
286
- if tag:
287
- # continue
288
- cv2.fillPoly(training_mask,
289
- poly.astype(np.int32)[np.newaxis, :, :], 0.15)
290
- else:
291
- tcl_poly = self.poly2tcl(poly, tcl_ratio)
292
- tcl_quads = self.poly2quads(tcl_poly)
293
- poly_quads = self.poly2quads(poly)
294
- # stcl map
295
- stcl_quads, quad_index = self.shrink_poly_along_width(
296
- tcl_quads,
297
- shrink_ratio_of_width=shrink_ratio_of_width,
298
- expand_height_ratio=1.0 / tcl_ratio)
299
- # generate tcl map
300
- cv2.fillPoly(score_map,
301
- np.round(stcl_quads).astype(np.int32), 1.0)
302
-
303
- # generate tbo map
304
- for idx, quad in enumerate(stcl_quads):
305
- quad_mask = np.zeros((h, w), dtype=np.float32)
306
- quad_mask = cv2.fillPoly(
307
- quad_mask,
308
- np.round(quad[np.newaxis, :, :]).astype(np.int32), 1.0)
309
- tbo_map = self.gen_quad_tbo(poly_quads[quad_index[idx]],
310
- quad_mask, tbo_map)
311
- return score_map, tbo_map, training_mask
312
-
313
- def generate_tvo_and_tco(self,
314
- hw,
315
- polys,
316
- tags,
317
- tcl_ratio=0.3,
318
- ds_ratio=0.25):
319
- """
320
- Generate tcl map, tvo map and tbo map.
321
- """
322
- h, w = hw
323
- h, w = int(h * ds_ratio), int(w * ds_ratio)
324
- polys = polys * ds_ratio
325
- poly_mask = np.zeros((h, w), dtype=np.float32)
326
-
327
- tvo_map = np.ones((9, h, w), dtype=np.float32)
328
- tvo_map[0:-1:2] = np.tile(np.arange(0, w), (h, 1))
329
- tvo_map[1:-1:2] = np.tile(np.arange(0, w), (h, 1)).T
330
- poly_tv_xy_map = np.zeros((8, h, w), dtype=np.float32)
331
-
332
- # tco map
333
- tco_map = np.ones((3, h, w), dtype=np.float32)
334
- tco_map[0] = np.tile(np.arange(0, w), (h, 1))
335
- tco_map[1] = np.tile(np.arange(0, w), (h, 1)).T
336
- poly_tc_xy_map = np.zeros((2, h, w), dtype=np.float32)
337
-
338
- poly_short_edge_map = np.ones((h, w), dtype=np.float32)
339
-
340
- for poly, poly_tag in zip(polys, tags):
341
-
342
- if poly_tag == True:
343
- continue
344
-
345
- # adjust point order for vertical poly
346
- poly = self.adjust_point(poly)
347
-
348
- # generate min_area_quad
349
- min_area_quad, center_point = self.gen_min_area_quad_from_poly(poly)
350
- min_area_quad_h = 0.5 * (
351
- np.linalg.norm(min_area_quad[0] - min_area_quad[3]) +
352
- np.linalg.norm(min_area_quad[1] - min_area_quad[2]))
353
- min_area_quad_w = 0.5 * (
354
- np.linalg.norm(min_area_quad[0] - min_area_quad[1]) +
355
- np.linalg.norm(min_area_quad[2] - min_area_quad[3]))
356
-
357
- # generate tcl map and text, 128 * 128
358
- tcl_poly = self.poly2tcl(poly, tcl_ratio)
359
-
360
- # generate poly_tv_xy_map
361
- for idx in range(4):
362
- cv2.fillPoly(
363
- poly_tv_xy_map[2 * idx],
364
- np.round(tcl_poly[np.newaxis, :, :]).astype(np.int32),
365
- float(min(max(min_area_quad[idx, 0], 0), w)))
366
- cv2.fillPoly(
367
- poly_tv_xy_map[2 * idx + 1],
368
- np.round(tcl_poly[np.newaxis, :, :]).astype(np.int32),
369
- float(min(max(min_area_quad[idx, 1], 0), h)))
370
-
371
- # generate poly_tc_xy_map
372
- for idx in range(2):
373
- cv2.fillPoly(
374
- poly_tc_xy_map[idx],
375
- np.round(tcl_poly[np.newaxis, :, :]).astype(np.int32),
376
- float(center_point[idx]))
377
-
378
- # generate poly_short_edge_map
379
- cv2.fillPoly(
380
- poly_short_edge_map,
381
- np.round(tcl_poly[np.newaxis, :, :]).astype(np.int32),
382
- float(max(min(min_area_quad_h, min_area_quad_w), 1.0)))
383
-
384
- # generate poly_mask and training_mask
385
- cv2.fillPoly(poly_mask,
386
- np.round(tcl_poly[np.newaxis, :, :]).astype(np.int32),
387
- 1)
388
-
389
- tvo_map *= poly_mask
390
- tvo_map[:8] -= poly_tv_xy_map
391
- tvo_map[-1] /= poly_short_edge_map
392
- tvo_map = tvo_map.transpose((1, 2, 0))
393
-
394
- tco_map *= poly_mask
395
- tco_map[:2] -= poly_tc_xy_map
396
- tco_map[-1] /= poly_short_edge_map
397
- tco_map = tco_map.transpose((1, 2, 0))
398
-
399
- return tvo_map, tco_map
400
-
401
- def adjust_point(self, poly):
402
- """
403
- adjust point order.
404
- """
405
- point_num = poly.shape[0]
406
- if point_num == 4:
407
- len_1 = np.linalg.norm(poly[0] - poly[1])
408
- len_2 = np.linalg.norm(poly[1] - poly[2])
409
- len_3 = np.linalg.norm(poly[2] - poly[3])
410
- len_4 = np.linalg.norm(poly[3] - poly[0])
411
-
412
- if (len_1 + len_3) * 1.5 < (len_2 + len_4):
413
- poly = poly[[1, 2, 3, 0], :]
414
-
415
- elif point_num > 4:
416
- vector_1 = poly[0] - poly[1]
417
- vector_2 = poly[1] - poly[2]
418
- cos_theta = np.dot(vector_1, vector_2) / (
419
- np.linalg.norm(vector_1) * np.linalg.norm(vector_2) + 1e-6)
420
- theta = np.arccos(np.round(cos_theta, decimals=4))
421
-
422
- if abs(theta) > (70 / 180 * math.pi):
423
- index = list(range(1, point_num)) + [0]
424
- poly = poly[np.array(index), :]
425
- return poly
426
-
427
- def gen_min_area_quad_from_poly(self, poly):
428
- """
429
- Generate min area quad from poly.
430
- """
431
- point_num = poly.shape[0]
432
- min_area_quad = np.zeros((4, 2), dtype=np.float32)
433
- if point_num == 4:
434
- min_area_quad = poly
435
- center_point = np.sum(poly, axis=0) / 4
436
- else:
437
- rect = cv2.minAreaRect(poly.astype(
438
- np.int32)) # (center (x,y), (width, height), angle of rotation)
439
- center_point = rect[0]
440
- box = np.array(cv2.boxPoints(rect))
441
-
442
- first_point_idx = 0
443
- min_dist = 1e4
444
- for i in range(4):
445
- dist = np.linalg.norm(box[(i + 0) % 4] - poly[0]) + \
446
- np.linalg.norm(box[(i + 1) % 4] - poly[point_num // 2 - 1]) + \
447
- np.linalg.norm(box[(i + 2) % 4] - poly[point_num // 2]) + \
448
- np.linalg.norm(box[(i + 3) % 4] - poly[-1])
449
- if dist < min_dist:
450
- min_dist = dist
451
- first_point_idx = i
452
-
453
- for i in range(4):
454
- min_area_quad[i] = box[(first_point_idx + i) % 4]
455
-
456
- return min_area_quad, center_point
457
-
458
- def shrink_quad_along_width(self,
459
- quad,
460
- begin_width_ratio=0.,
461
- end_width_ratio=1.):
462
- """
463
- Generate shrink_quad_along_width.
464
- """
465
- ratio_pair = np.array(
466
- [[begin_width_ratio], [end_width_ratio]], dtype=np.float32)
467
- p0_1 = quad[0] + (quad[1] - quad[0]) * ratio_pair
468
- p3_2 = quad[3] + (quad[2] - quad[3]) * ratio_pair
469
- return np.array([p0_1[0], p0_1[1], p3_2[1], p3_2[0]])
470
-
471
- def shrink_poly_along_width(self,
472
- quads,
473
- shrink_ratio_of_width,
474
- expand_height_ratio=1.0):
475
- """
476
- shrink poly with given length.
477
- """
478
- upper_edge_list = []
479
-
480
- def get_cut_info(edge_len_list, cut_len):
481
- for idx, edge_len in enumerate(edge_len_list):
482
- cut_len -= edge_len
483
- if cut_len <= 0.000001:
484
- ratio = (cut_len + edge_len_list[idx]) / edge_len_list[idx]
485
- return idx, ratio
486
-
487
- for quad in quads:
488
- upper_edge_len = np.linalg.norm(quad[0] - quad[1])
489
- upper_edge_list.append(upper_edge_len)
490
-
491
- # length of left edge and right edge.
492
- left_length = np.linalg.norm(quads[0][0] - quads[0][
493
- 3]) * expand_height_ratio
494
- right_length = np.linalg.norm(quads[-1][1] - quads[-1][
495
- 2]) * expand_height_ratio
496
-
497
- shrink_length = min(left_length, right_length,
498
- sum(upper_edge_list)) * shrink_ratio_of_width
499
- # shrinking length
500
- upper_len_left = shrink_length
501
- upper_len_right = sum(upper_edge_list) - shrink_length
502
-
503
- left_idx, left_ratio = get_cut_info(upper_edge_list, upper_len_left)
504
- left_quad = self.shrink_quad_along_width(
505
- quads[left_idx], begin_width_ratio=left_ratio, end_width_ratio=1)
506
- right_idx, right_ratio = get_cut_info(upper_edge_list, upper_len_right)
507
- right_quad = self.shrink_quad_along_width(
508
- quads[right_idx], begin_width_ratio=0, end_width_ratio=right_ratio)
509
-
510
- out_quad_list = []
511
- if left_idx == right_idx:
512
- out_quad_list.append(
513
- [left_quad[0], right_quad[1], right_quad[2], left_quad[3]])
514
- else:
515
- out_quad_list.append(left_quad)
516
- for idx in range(left_idx + 1, right_idx):
517
- out_quad_list.append(quads[idx])
518
- out_quad_list.append(right_quad)
519
-
520
- return np.array(out_quad_list), list(range(left_idx, right_idx + 1))
521
-
522
- def vector_angle(self, A, B):
523
- """
524
- Calculate the angle between vector AB and x-axis positive direction.
525
- """
526
- AB = np.array([B[1] - A[1], B[0] - A[0]])
527
- return np.arctan2(*AB)
528
-
529
- def theta_line_cross_point(self, theta, point):
530
- """
531
- Calculate the line through given point and angle in ax + by + c =0 form.
532
- """
533
- x, y = point
534
- cos = np.cos(theta)
535
- sin = np.sin(theta)
536
- return [sin, -cos, cos * y - sin * x]
537
-
538
- def line_cross_two_point(self, A, B):
539
- """
540
- Calculate the line through given point A and B in ax + by + c =0 form.
541
- """
542
- angle = self.vector_angle(A, B)
543
- return self.theta_line_cross_point(angle, A)
544
-
545
- def average_angle(self, poly):
546
- """
547
- Calculate the average angle between left and right edge in given poly.
548
- """
549
- p0, p1, p2, p3 = poly
550
- angle30 = self.vector_angle(p3, p0)
551
- angle21 = self.vector_angle(p2, p1)
552
- return (angle30 + angle21) / 2
553
-
554
- def line_cross_point(self, line1, line2):
555
- """
556
- line1 and line2 in 0=ax+by+c form, compute the cross point of line1 and line2
557
- """
558
- a1, b1, c1 = line1
559
- a2, b2, c2 = line2
560
- d = a1 * b2 - a2 * b1
561
-
562
- if d == 0:
563
- #print("line1", line1)
564
- #print("line2", line2)
565
- print('Cross point does not exist')
566
- return np.array([0, 0], dtype=np.float32)
567
- else:
568
- x = (b1 * c2 - b2 * c1) / d
569
- y = (a2 * c1 - a1 * c2) / d
570
-
571
- return np.array([x, y], dtype=np.float32)
572
-
573
- def quad2tcl(self, poly, ratio):
574
- """
575
- Generate center line by poly clock-wise point. (4, 2)
576
- """
577
- ratio_pair = np.array(
578
- [[0.5 - ratio / 2], [0.5 + ratio / 2]], dtype=np.float32)
579
- p0_3 = poly[0] + (poly[3] - poly[0]) * ratio_pair
580
- p1_2 = poly[1] + (poly[2] - poly[1]) * ratio_pair
581
- return np.array([p0_3[0], p1_2[0], p1_2[1], p0_3[1]])
582
-
583
- def poly2tcl(self, poly, ratio):
584
- """
585
- Generate center line by poly clock-wise point.
586
- """
587
- ratio_pair = np.array(
588
- [[0.5 - ratio / 2], [0.5 + ratio / 2]], dtype=np.float32)
589
- tcl_poly = np.zeros_like(poly)
590
- point_num = poly.shape[0]
591
-
592
- for idx in range(point_num // 2):
593
- point_pair = poly[idx] + (poly[point_num - 1 - idx] - poly[idx]
594
- ) * ratio_pair
595
- tcl_poly[idx] = point_pair[0]
596
- tcl_poly[point_num - 1 - idx] = point_pair[1]
597
- return tcl_poly
598
-
599
- def gen_quad_tbo(self, quad, tcl_mask, tbo_map):
600
- """
601
- Generate tbo_map for give quad.
602
- """
603
- # upper and lower line function: ax + by + c = 0;
604
- up_line = self.line_cross_two_point(quad[0], quad[1])
605
- lower_line = self.line_cross_two_point(quad[3], quad[2])
606
-
607
- quad_h = 0.5 * (np.linalg.norm(quad[0] - quad[3]) +
608
- np.linalg.norm(quad[1] - quad[2]))
609
- quad_w = 0.5 * (np.linalg.norm(quad[0] - quad[1]) +
610
- np.linalg.norm(quad[2] - quad[3]))
611
-
612
- # average angle of left and right line.
613
- angle = self.average_angle(quad)
614
-
615
- xy_in_poly = np.argwhere(tcl_mask == 1)
616
- for y, x in xy_in_poly:
617
- point = (x, y)
618
- line = self.theta_line_cross_point(angle, point)
619
- cross_point_upper = self.line_cross_point(up_line, line)
620
- cross_point_lower = self.line_cross_point(lower_line, line)
621
- ##FIX, offset reverse
622
- upper_offset_x, upper_offset_y = cross_point_upper - point
623
- lower_offset_x, lower_offset_y = cross_point_lower - point
624
- tbo_map[y, x, 0] = upper_offset_y
625
- tbo_map[y, x, 1] = upper_offset_x
626
- tbo_map[y, x, 2] = lower_offset_y
627
- tbo_map[y, x, 3] = lower_offset_x
628
- tbo_map[y, x, 4] = 1.0 / max(min(quad_h, quad_w), 1.0) * 2
629
- return tbo_map
630
-
631
- def poly2quads(self, poly):
632
- """
633
- Split poly into quads.
634
- """
635
- quad_list = []
636
- point_num = poly.shape[0]
637
-
638
- # point pair
639
- point_pair_list = []
640
- for idx in range(point_num // 2):
641
- point_pair = [poly[idx], poly[point_num - 1 - idx]]
642
- point_pair_list.append(point_pair)
643
-
644
- quad_num = point_num // 2 - 1
645
- for idx in range(quad_num):
646
- # reshape and adjust to clock-wise
647
- quad_list.append((np.array(point_pair_list)[[idx, idx + 1]]
648
- ).reshape(4, 2)[[0, 2, 3, 1]])
649
-
650
- return np.array(quad_list)
651
-
652
- def __call__(self, data):
653
- im = data['image']
654
- text_polys = data['polys']
655
- text_tags = data['ignore_tags']
656
- if im is None:
657
- return None
658
- if text_polys.shape[0] == 0:
659
- return None
660
-
661
- h, w, _ = im.shape
662
- text_polys, text_tags, hv_tags = self.check_and_validate_polys(
663
- text_polys, text_tags, (h, w))
664
-
665
- if text_polys.shape[0] == 0:
666
- return None
667
-
668
- #set aspect ratio and keep area fix
669
- asp_scales = np.arange(1.0, 1.55, 0.1)
670
- asp_scale = np.random.choice(asp_scales)
671
-
672
- if np.random.rand() < 0.5:
673
- asp_scale = 1.0 / asp_scale
674
- asp_scale = math.sqrt(asp_scale)
675
-
676
- asp_wx = asp_scale
677
- asp_hy = 1.0 / asp_scale
678
- im = cv2.resize(im, dsize=None, fx=asp_wx, fy=asp_hy)
679
- text_polys[:, :, 0] *= asp_wx
680
- text_polys[:, :, 1] *= asp_hy
681
-
682
- h, w, _ = im.shape
683
- if max(h, w) > 2048:
684
- rd_scale = 2048.0 / max(h, w)
685
- im = cv2.resize(im, dsize=None, fx=rd_scale, fy=rd_scale)
686
- text_polys *= rd_scale
687
- h, w, _ = im.shape
688
- if min(h, w) < 16:
689
- return None
690
-
691
- #no background
692
- im, text_polys, text_tags, hv_tags = self.crop_area(im, \
693
- text_polys, text_tags, hv_tags, crop_background=False)
694
-
695
- if text_polys.shape[0] == 0:
696
- return None
697
- #continue for all ignore case
698
- if np.sum((text_tags * 1.0)) >= text_tags.size:
699
- return None
700
- new_h, new_w, _ = im.shape
701
- if (new_h is None) or (new_w is None):
702
- return None
703
- #resize image
704
- std_ratio = float(self.input_size) / max(new_w, new_h)
705
- rand_scales = np.array(
706
- [0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.0, 1.0, 1.0, 1.0])
707
- rz_scale = std_ratio * np.random.choice(rand_scales)
708
- im = cv2.resize(im, dsize=None, fx=rz_scale, fy=rz_scale)
709
- text_polys[:, :, 0] *= rz_scale
710
- text_polys[:, :, 1] *= rz_scale
711
-
712
- #add gaussian blur
713
- if np.random.rand() < 0.1 * 0.5:
714
- ks = np.random.permutation(5)[0] + 1
715
- ks = int(ks / 2) * 2 + 1
716
- im = cv2.GaussianBlur(im, ksize=(ks, ks), sigmaX=0, sigmaY=0)
717
- #add brighter
718
- if np.random.rand() < 0.1 * 0.5:
719
- im = im * (1.0 + np.random.rand() * 0.5)
720
- im = np.clip(im, 0.0, 255.0)
721
- #add darker
722
- if np.random.rand() < 0.1 * 0.5:
723
- im = im * (1.0 - np.random.rand() * 0.5)
724
- im = np.clip(im, 0.0, 255.0)
725
-
726
- # Padding the im to [input_size, input_size]
727
- new_h, new_w, _ = im.shape
728
- if min(new_w, new_h) < self.input_size * 0.5:
729
- return None
730
-
731
- im_padded = np.ones(
732
- (self.input_size, self.input_size, 3), dtype=np.float32)
733
- im_padded[:, :, 2] = 0.485 * 255
734
- im_padded[:, :, 1] = 0.456 * 255
735
- im_padded[:, :, 0] = 0.406 * 255
736
-
737
- # Random the start position
738
- del_h = self.input_size - new_h
739
- del_w = self.input_size - new_w
740
- sh, sw = 0, 0
741
- if del_h > 1:
742
- sh = int(np.random.rand() * del_h)
743
- if del_w > 1:
744
- sw = int(np.random.rand() * del_w)
745
-
746
- # Padding
747
- im_padded[sh:sh + new_h, sw:sw + new_w, :] = im.copy()
748
- text_polys[:, :, 0] += sw
749
- text_polys[:, :, 1] += sh
750
-
751
- score_map, border_map, training_mask = self.generate_tcl_label(
752
- (self.input_size, self.input_size), text_polys, text_tags, 0.25)
753
-
754
- # SAST head
755
- tvo_map, tco_map = self.generate_tvo_and_tco(
756
- (self.input_size, self.input_size),
757
- text_polys,
758
- text_tags,
759
- tcl_ratio=0.3,
760
- ds_ratio=0.25)
761
- # print("test--------tvo_map shape:", tvo_map.shape)
762
-
763
- im_padded[:, :, 2] -= 0.485 * 255
764
- im_padded[:, :, 1] -= 0.456 * 255
765
- im_padded[:, :, 0] -= 0.406 * 255
766
- im_padded[:, :, 2] /= (255.0 * 0.229)
767
- im_padded[:, :, 1] /= (255.0 * 0.224)
768
- im_padded[:, :, 0] /= (255.0 * 0.225)
769
- im_padded = im_padded.transpose((2, 0, 1))
770
-
771
- data['image'] = im_padded[::-1, :, :]
772
- data['score_map'] = score_map[np.newaxis, :, :]
773
- data['border_map'] = border_map.transpose((2, 0, 1))
774
- data['training_mask'] = training_mask[np.newaxis, :, :]
775
- data['tvo_map'] = tvo_map.transpose((2, 0, 1))
776
- data['tco_map'] = tco_map.transpose((2, 0, 1))
777
- return data