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,341 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- #File: TL2p_icdar_1_1.py
5
- #Version: 1.1
6
- #Version info: changes for Python 3
7
- #Date: 2019-12-29
8
- #Description: Evaluation script that computes Text Localization following the algorithm of Wolf et al [1]
9
- #1. C. Wolf and J.M. Jolion, "Object Count / Area Graphs for the Evaluation of Object Detection and Segmentation Algorithms", International Journal of Document Analysis, vol. 8, no. 4, pp. 280-296, 2006.
10
-
11
- from collections import namedtuple
12
- import pyxlpr.data.icdar.rrc_evaluation_funcs_1_1 as rrc_evaluation_funcs
13
- import importlib
14
-
15
- def evaluation_imports():
16
- """
17
- evaluation_imports: Dictionary ( key = module name , value = alias ) with python modules used in the evaluation.
18
- """
19
- return {
20
- 'math':'math',
21
- 'numpy':'np'
22
- }
23
-
24
- def default_evaluation_params():
25
- """
26
- default_evaluation_params: Default parameters to use for the validation and evaluation.
27
- """
28
- return {
29
- 'AREA_RECALL_CONSTRAINT' : 0.8,
30
- 'AREA_PRECISION_CONSTRAINT' : 0.4,
31
- 'EV_PARAM_IND_CENTER_DIFF_THR': 1,
32
- 'MTYPE_OO_O':1.,
33
- 'MTYPE_OM_O':0.8,
34
- 'MTYPE_OM_M':1.,
35
- 'GT_SAMPLE_NAME_2_ID':'gt_img_([0-9]+).txt',
36
- 'DET_SAMPLE_NAME_2_ID':'res_img_([0-9]+).txt',
37
- 'CRLF':False # Lines are delimited by Windows CRLF format
38
- }
39
-
40
- def validate_data(gtFilePath, submFilePath,evaluationParams):
41
- """
42
- Method validate_data: validates that all files in the results folder are correct (have the correct name contents).
43
- Validates also that there are no missing files in the folder.
44
- If some error detected, the method raises the error
45
- """
46
- gt = rrc_evaluation_funcs.load_zip_file(gtFilePath, evaluationParams['GT_SAMPLE_NAME_2_ID'])
47
-
48
- subm = rrc_evaluation_funcs.load_zip_file(submFilePath, evaluationParams['DET_SAMPLE_NAME_2_ID'], True)
49
-
50
- #Validate format of GroundTruth
51
- for k in gt:
52
- rrc_evaluation_funcs.validate_lines_in_file(k,gt[k],evaluationParams['CRLF'],True,True)
53
-
54
- #Validate format of results
55
- for k in subm:
56
- if (k in gt) == False :
57
- raise Exception("The sample %s not present in GT" %k)
58
-
59
- rrc_evaluation_funcs.validate_lines_in_file(k,subm[k],evaluationParams['CRLF'],True,False)
60
-
61
- def evaluate_method(gtFilePath, submFilePath, evaluationParams):
62
- """
63
- Method evaluate_method: evaluate method and returns the results
64
- Results. Dictionary with the following values:
65
- - method (required) Global method metrics. Ex: { 'Precision':0.8,'Recall':0.9 }
66
- - samples (optional) Per sample metrics. Ex: {'sample1' : { 'Precision':0.8,'Recall':0.9 } , 'sample2' : { 'Precision':0.8,'Recall':0.9 }
67
- """
68
-
69
- for module,alias in evaluation_imports().items():
70
- globals()[alias] = importlib.import_module(module)
71
-
72
- def one_to_one_match(row, col):
73
- cont = 0
74
- for j in range(len(recallMat[0])):
75
- if recallMat[row,j] >= evaluationParams['AREA_RECALL_CONSTRAINT'] and precisionMat[row,j] >= evaluationParams['AREA_PRECISION_CONSTRAINT'] :
76
- cont = cont +1
77
- if (cont != 1):
78
- return False
79
- cont = 0
80
- for i in range(len(recallMat)):
81
- if recallMat[i,col] >= evaluationParams['AREA_RECALL_CONSTRAINT'] and precisionMat[i,col] >= evaluationParams['AREA_PRECISION_CONSTRAINT'] :
82
- cont = cont +1
83
- if (cont != 1):
84
- return False
85
-
86
- if recallMat[row,col] >= evaluationParams['AREA_RECALL_CONSTRAINT'] and precisionMat[row,col] >= evaluationParams['AREA_PRECISION_CONSTRAINT'] :
87
- return True
88
- return False
89
-
90
- def one_to_many_match(gtNum):
91
- many_sum = 0
92
- detRects = []
93
- for detNum in range(len(recallMat[0])):
94
- if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and detNum not in detDontCareRectsNum:
95
- if precisionMat[gtNum,detNum] >= evaluationParams['AREA_PRECISION_CONSTRAINT'] :
96
- many_sum += recallMat[gtNum,detNum]
97
- detRects.append(detNum)
98
- if many_sum>=evaluationParams['AREA_RECALL_CONSTRAINT'] :
99
- return True,detRects
100
- else:
101
- return False,[]
102
-
103
- def many_to_one_match(detNum):
104
- many_sum = 0
105
- gtRects = []
106
- for gtNum in range(len(recallMat)):
107
- if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and gtNum not in gtDontCareRectsNum:
108
- if recallMat[gtNum,detNum] >= evaluationParams['AREA_RECALL_CONSTRAINT'] :
109
- many_sum += precisionMat[gtNum,detNum]
110
- gtRects.append(gtNum)
111
- if many_sum>=evaluationParams['AREA_PRECISION_CONSTRAINT'] :
112
- return True,gtRects
113
- else:
114
- return False,[]
115
-
116
- def area(a, b):
117
- dx = min(a.xmax, b.xmax) - max(a.xmin, b.xmin) + 1
118
- dy = min(a.ymax, b.ymax) - max(a.ymin, b.ymin) + 1
119
- if (dx>=0) and (dy>=0):
120
- return dx*dy
121
- else:
122
- return 0.
123
-
124
- def center(r):
125
- x = float(r.xmin) + float(r.xmax - r.xmin + 1) / 2.;
126
- y = float(r.ymin) + float(r.ymax - r.ymin + 1) / 2.;
127
- return Point(x,y)
128
-
129
- def point_distance(r1, r2):
130
- distx = math.fabs(r1.x - r2.x)
131
- disty = math.fabs(r1.y - r2.y)
132
- return math.sqrt(distx * distx + disty * disty )
133
-
134
- def center_distance(r1, r2):
135
- return point_distance(center(r1), center(r2))
136
-
137
- def diag(r):
138
- w = (r.xmax - r.xmin + 1)
139
- h = (r.ymax - r.ymin + 1)
140
- return math.sqrt(h * h + w * w)
141
-
142
- perSampleMetrics = {}
143
-
144
- methodRecallSum = 0
145
- methodPrecisionSum = 0
146
-
147
- Rectangle = namedtuple('Rectangle', 'xmin ymin xmax ymax')
148
- Point = namedtuple('Point', 'x y')
149
-
150
- # 整体参数的解析
151
- if isinstance(gtFilePath, str):
152
- gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
153
- else:
154
- gt = gtFilePath
155
- if isinstance(submFilePath, str):
156
- subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
157
- else:
158
- subm = submFilePath
159
-
160
- numGt = 0;
161
- numDet = 0;
162
-
163
- for resFile in gt:
164
- if isinstance(gt[resFile], bytes):
165
- gtFile = rrc_evaluation_funcs.decode_utf8(gt[resFile])
166
- else:
167
- gtFile = gt[resFile]
168
- recall = 0
169
- precision = 0
170
- hmean = 0
171
- recallAccum = 0.
172
- precisionAccum = 0.
173
- gtRects = []
174
- detRects = []
175
- gtPolPoints = []
176
- detPolPoints = []
177
- gtDontCareRectsNum = []#Array of Ground Truth Rectangles' keys marked as don't Care
178
- detDontCareRectsNum = []#Array of Detected Rectangles' matched with a don't Care GT
179
- pairs = []
180
- evaluationLog = ""
181
-
182
- recallMat = np.empty([1,1])
183
- precisionMat = np.empty([1,1])
184
-
185
- pointsList,_,transcriptionsList = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(gtFile,evaluationParams['CRLF'],True,True,False)
186
- for n in range(len(pointsList)):
187
- points = pointsList[n]
188
- transcription = transcriptionsList[n]
189
- dontCare = transcription == "###"
190
- gtRect = Rectangle(*points)
191
- gtRects.append(gtRect)
192
- gtPolPoints.append(points)
193
- if dontCare:
194
- gtDontCareRectsNum.append( len(gtRects)-1 )
195
-
196
- evaluationLog += "GT rectangles: " + str(len(gtRects)) + (" (" + str(len(gtDontCareRectsNum)) + " don't care)\n" if len(gtDontCareRectsNum)>0 else "\n")
197
-
198
- if resFile in subm:
199
- if isinstance(subm[resFile], bytes):
200
- detFile = rrc_evaluation_funcs.decode_utf8(subm[resFile])
201
- else:
202
- detFile = subm[resFile]
203
- pointsList,_,_ = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(detFile,evaluationParams['CRLF'],True,False,False)
204
- for n in range(len(pointsList)):
205
- points = pointsList[n]
206
- detRect = Rectangle(*points)
207
- detRects.append(detRect)
208
- detPolPoints.append(points)
209
- if len(gtDontCareRectsNum)>0 :
210
- for dontCareRectNum in gtDontCareRectsNum:
211
- dontCareRect = gtRects[dontCareRectNum]
212
- intersected_area = area(dontCareRect,detRect)
213
- rdDimensions = ( (detRect.xmax - detRect.xmin+1) * (detRect.ymax - detRect.ymin+1));
214
- if (rdDimensions==0) :
215
- precision = 0
216
- else:
217
- precision= intersected_area / rdDimensions
218
- if (precision > evaluationParams['AREA_PRECISION_CONSTRAINT'] ):
219
- detDontCareRectsNum.append( len(detRects)-1 )
220
- break
221
-
222
- evaluationLog += "DET rectangles: " + str(len(detRects)) + (" (" + str(len(detDontCareRectsNum)) + " don't care)\n" if len(detDontCareRectsNum)>0 else "\n")
223
-
224
- if len(gtRects)==0:
225
- recall = 1
226
- precision = 0 if len(detRects)>0 else 1
227
-
228
- if len(detRects)>0:
229
- #Calculate recall and precision matrixs
230
- outputShape=[len(gtRects),len(detRects)]
231
- recallMat = np.empty(outputShape)
232
- precisionMat = np.empty(outputShape)
233
- gtRectMat = np.zeros(len(gtRects),np.int8)
234
- detRectMat = np.zeros(len(detRects),np.int8)
235
- for gtNum in range(len(gtRects)):
236
- for detNum in range(len(detRects)):
237
- rG = gtRects[gtNum]
238
- rD = detRects[detNum]
239
- intersected_area = area(rG,rD)
240
- rgDimensions = ( (rG.xmax - rG.xmin+1) * (rG.ymax - rG.ymin+1) );
241
- rdDimensions = ( (rD.xmax - rD.xmin+1) * (rD.ymax - rD.ymin+1));
242
- recallMat[gtNum,detNum] = 0 if rgDimensions==0 else intersected_area / rgDimensions
243
- precisionMat[gtNum,detNum] = 0 if rdDimensions==0 else intersected_area / rdDimensions
244
-
245
- # Find one-to-one matches
246
- evaluationLog += "Find one-to-one matches\n"
247
- for gtNum in range(len(gtRects)):
248
- for detNum in range(len(detRects)):
249
- if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and gtNum not in gtDontCareRectsNum and detNum not in detDontCareRectsNum :
250
- match = one_to_one_match(gtNum, detNum)
251
- if match is True :
252
- rG = gtRects[gtNum]
253
- rD = detRects[detNum]
254
- normDist = center_distance(rG, rD);
255
- normDist /= diag(rG) + diag(rD);
256
- normDist *= 2.0;
257
- if normDist < evaluationParams['EV_PARAM_IND_CENTER_DIFF_THR'] :
258
- gtRectMat[gtNum] = 1
259
- detRectMat[detNum] = 1
260
- recallAccum += evaluationParams['MTYPE_OO_O']
261
- precisionAccum += evaluationParams['MTYPE_OO_O']
262
- pairs.append({'gt':gtNum,'det':detNum,'type':'OO'})
263
- evaluationLog += "Match GT #" + str(gtNum) + " with Det #" + str(detNum) + "\n"
264
- else:
265
- evaluationLog += "Match Discarded GT #" + str(gtNum) + " with Det #" + str(detNum) + " normDist: " + str(normDist) + " \n"
266
- # Find one-to-many matches
267
- evaluationLog += "Find one-to-many matches\n"
268
- for gtNum in range(len(gtRects)):
269
- if gtNum not in gtDontCareRectsNum:
270
- match,matchesDet = one_to_many_match(gtNum)
271
- if match is True :
272
- gtRectMat[gtNum] = 1
273
- recallAccum += evaluationParams['MTYPE_OM_O']
274
- precisionAccum += evaluationParams['MTYPE_OM_O']*len(matchesDet)
275
- pairs.append({'gt':gtNum,'det':matchesDet,'type':'OM'})
276
- for detNum in matchesDet :
277
- detRectMat[detNum] = 1
278
- evaluationLog += "Match GT #" + str(gtNum) + " with Det #" + str(matchesDet) + "\n"
279
-
280
- # Find many-to-one matches
281
- evaluationLog += "Find many-to-one matches\n"
282
- for detNum in range(len(detRects)):
283
- if detNum not in detDontCareRectsNum:
284
- match,matchesGt = many_to_one_match(detNum)
285
- if match is True :
286
- detRectMat[detNum] = 1
287
- recallAccum += evaluationParams['MTYPE_OM_M']*len(matchesGt)
288
- precisionAccum += evaluationParams['MTYPE_OM_M']
289
- pairs.append({'gt':matchesGt,'det':detNum,'type':'MO'})
290
- for gtNum in matchesGt :
291
- gtRectMat[gtNum] = 1
292
- evaluationLog += "Match GT #" + str(matchesGt) + " with Det #" + str(detNum) + "\n"
293
-
294
- numGtCare = (len(gtRects) - len(gtDontCareRectsNum))
295
- if numGtCare == 0:
296
- recall = float(1)
297
- precision = float(0) if len(detRects)>0 else float(1)
298
- else:
299
- recall = float(recallAccum) / numGtCare
300
- precision = float(0) if (len(detRects) - len(detDontCareRectsNum))==0 else float(precisionAccum) / (len(detRects) - len(detDontCareRectsNum))
301
- hmean = 0 if (precision + recall)==0 else 2.0 * precision * recall / (precision + recall)
302
-
303
- evaluationLog += "Recall = " + str(recall) + "\n"
304
- evaluationLog += "Precision = " + str(precision) + "\n"
305
-
306
- methodRecallSum += recallAccum
307
- methodPrecisionSum += precisionAccum
308
- numGt += len(gtRects) - len(gtDontCareRectsNum)
309
- numDet += len(detRects) - len(detDontCareRectsNum)
310
-
311
- perSampleMetrics[resFile] = {
312
- 'precision':precision,
313
- 'recall':recall,
314
- 'hmean':hmean,
315
- 'pairs':pairs,
316
- 'recallMat': [] if len(detRects)>100 else recallMat.tolist(),
317
- 'precisionMat':[] if len(detRects)>100 else precisionMat.tolist(),
318
- 'gtPolPoints':gtPolPoints,
319
- 'detPolPoints':detPolPoints,
320
- 'gtDontCare':gtDontCareRectsNum,
321
- 'detDontCare':detDontCareRectsNum,
322
- 'evaluationParams': evaluationParams,
323
- 'evaluationLog': evaluationLog
324
- }
325
-
326
- methodRecall = 0 if numGt==0 else methodRecallSum/numGt
327
- methodPrecision = 0 if numDet==0 else methodPrecisionSum/numDet
328
- methodHmean = 0 if methodRecall + methodPrecision==0 else 2* methodRecall * methodPrecision / (methodRecall + methodPrecision)
329
-
330
- methodMetrics = {'precision':methodPrecision, 'recall':methodRecall,'hmean': methodHmean }
331
-
332
- resDict = {'calculated':True,'Message':'','method': methodMetrics,'per_sample': perSampleMetrics}
333
-
334
-
335
- return resDict;
336
-
337
-
338
-
339
- if __name__=='__main__':
340
-
341
- rrc_evaluation_funcs.main_evaluation(None,default_evaluation_params,validate_data,evaluate_method)
pyxlpr/data/icdar/iou.py DELETED
@@ -1,340 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- #File: TL_iou_1_1.py
5
- #Version: 1.1
6
- #Version info: changes for Python 3
7
- #Date: 2019-12-29
8
- #Description: Evaluation script that computes Text Localization by Intersection over Union
9
- #Average Precision is also calcuted when 'CONFIDENCES' parameter is True
10
-
11
- from collections import namedtuple
12
- import pyxlpr.data.icdar.rrc_evaluation_funcs_1_1 as rrc_evaluation_funcs
13
- import importlib
14
-
15
- import numpy as np
16
- # import shapely.geometry as plg
17
- import Polygon as plg
18
-
19
- # def evaluation_imports():
20
- # """
21
- # evaluation_imports: Dictionary ( key = module name , value = alias ) with python modules used in the evaluation.
22
- # """
23
- # return {
24
- # # 'Polygon':'plg', # 220830周二10:53,报错,用不了,换成自己的shapely
25
- # 'shapely.geometry':'plg', # ckz: 可以换成自己的多边形库
26
- # 'numpy':'np'
27
- # }
28
-
29
- def default_evaluation_params():
30
- """
31
- default_evaluation_params: Default parameters to use for the validation and evaluation.
32
- """
33
- return {
34
- 'IOU_CONSTRAINT' : 0.5,
35
- 'AREA_PRECISION_CONSTRAINT' : 0.5,
36
- 'GT_SAMPLE_NAME_2_ID':'gt_img_([0-9]+).txt',
37
- 'DET_SAMPLE_NAME_2_ID':'res_img_([0-9]+).txt',
38
- 'LTRB':True, #LTRB:2points(left,top,right,bottom) or 4 points(x1,y1,x2,y2,x3,y3,x4,y4)
39
- 'CRLF':False, # Lines are delimited by Windows CRLF format
40
- 'CONFIDENCES':False, #Detections must include confidence value. AP will be calculated
41
- 'PER_SAMPLE_RESULTS':True #Generate per sample results and produce data for visualization
42
- }
43
-
44
- def validate_data(gtFilePath, submFilePath,evaluationParams):
45
- """
46
- Method validate_data: validates that all files in the results folder are correct (have the correct name contents).
47
- Validates also that there are no missing files in the folder.
48
- If some error detected, the method raises the error
49
- """
50
- gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
51
-
52
- subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
53
-
54
- #Validate format of GroundTruth
55
- for k in gt:
56
- rrc_evaluation_funcs.validate_lines_in_file(k,gt[k],evaluationParams['CRLF'],evaluationParams['LTRB'],True)
57
-
58
- #Validate format of results
59
- for k in subm:
60
- if (k in gt) == False :
61
- raise Exception("The sample %s not present in GT" %k)
62
-
63
- rrc_evaluation_funcs.validate_lines_in_file(k,subm[k],evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
64
-
65
-
66
- def evaluate_method(gtFilePath, submFilePath, evaluationParams):
67
- """
68
- Method evaluate_method: evaluate method and returns the results
69
- Results. Dictionary with the following values:
70
- - method (required) Global method metrics. Ex: { 'Precision':0.8,'Recall':0.9 }
71
- - samples (optional) Per sample metrics. Ex: {'sample1' : { 'Precision':0.8,'Recall':0.9 } , 'sample2' : { 'Precision':0.8,'Recall':0.9 }
72
- """
73
-
74
- # for module,alias in evaluation_imports().items():
75
- # globals()[alias] = importlib.import_module(module)
76
-
77
- def polygon_from_points(points):
78
- """
79
- Returns a Polygon object to use with the Polygon2 class from a list of 8 points: x1,y1,x2,y2,x3,y3,x4,y4
80
- """
81
- resBoxes=np.empty([1,8],dtype='int32')
82
- resBoxes[0,0]=int(points[0])
83
- resBoxes[0,4]=int(points[1])
84
- resBoxes[0,1]=int(points[2])
85
- resBoxes[0,5]=int(points[3])
86
- resBoxes[0,2]=int(points[4])
87
- resBoxes[0,6]=int(points[5])
88
- resBoxes[0,3]=int(points[6])
89
- resBoxes[0,7]=int(points[7])
90
- pointMat = resBoxes[0].reshape([2,4]).T
91
- return plg.Polygon(pointMat)
92
-
93
- def rectangle_to_polygon(rect):
94
- resBoxes=np.empty([1,8],dtype='int32')
95
- resBoxes[0,0]=int(rect.xmin)
96
- resBoxes[0,4]=int(rect.ymax)
97
- resBoxes[0,1]=int(rect.xmin)
98
- resBoxes[0,5]=int(rect.ymin)
99
- resBoxes[0,2]=int(rect.xmax)
100
- resBoxes[0,6]=int(rect.ymin)
101
- resBoxes[0,3]=int(rect.xmax)
102
- resBoxes[0,7]=int(rect.ymax)
103
-
104
- pointMat = resBoxes[0].reshape([2,4]).T
105
-
106
- return plg.Polygon(pointMat)
107
-
108
- def rectangle_to_points(rect):
109
- points = [int(rect.xmin), int(rect.ymax), int(rect.xmax), int(rect.ymax), int(rect.xmax), int(rect.ymin), int(rect.xmin), int(rect.ymin)]
110
- return points
111
-
112
- def get_union(pD,pG):
113
- areaA = pD.area()
114
- areaB = pG.area()
115
- return areaA + areaB - get_intersection(pD, pG)
116
-
117
- def get_intersection_over_union(pD,pG):
118
- try:
119
- return get_intersection(pD, pG) / get_union(pD, pG)
120
- except:
121
- return 0
122
-
123
- def get_intersection(pD,pG):
124
- pInt = pD & pG
125
- if len(pInt) == 0:
126
- return 0
127
- return pInt.area()
128
-
129
- def compute_ap(confList, matchList,numGtCare):
130
- correct = 0
131
- AP = 0
132
- if len(confList)>0:
133
- confList = np.array(confList)
134
- matchList = np.array(matchList)
135
- sorted_ind = np.argsort(-confList)
136
- confList = confList[sorted_ind]
137
- matchList = matchList[sorted_ind]
138
- for n in range(len(confList)):
139
- match = matchList[n]
140
- if match:
141
- correct += 1
142
- AP += float(correct)/(n + 1)
143
-
144
- if numGtCare>0:
145
- AP /= numGtCare
146
-
147
- return AP
148
-
149
- perSampleMetrics = {}
150
-
151
- matchedSum = 0
152
-
153
- Rectangle = namedtuple('Rectangle', 'xmin ymin xmax ymax')
154
-
155
- if isinstance(gtFilePath, str):
156
- gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
157
- else:
158
- gt = gtFilePath
159
- if isinstance(submFilePath, str):
160
- subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
161
- else:
162
- subm = submFilePath
163
-
164
- numGlobalCareGt = 0
165
- numGlobalCareDet = 0
166
-
167
- arrGlobalConfidences = []
168
- arrGlobalMatches = []
169
-
170
- for resFile in gt:
171
-
172
- if isinstance(gt[resFile], bytes):
173
- gtFile = rrc_evaluation_funcs.decode_utf8(gt[resFile])
174
- else:
175
- gtFile = gt[resFile]
176
-
177
- recall = 0
178
- precision = 0
179
- hmean = 0
180
-
181
- detMatched = 0
182
-
183
- iouMat = np.empty([1,1])
184
-
185
- gtPols = []
186
- detPols = []
187
-
188
- gtPolPoints = []
189
- detPolPoints = []
190
-
191
- #Array of Ground Truth Polygons' keys marked as don't Care
192
- gtDontCarePolsNum = []
193
- #Array of Detected Polygons' matched with a don't Care GT
194
- detDontCarePolsNum = []
195
-
196
- pairs = []
197
- detMatchedNums = []
198
-
199
- arrSampleConfidences = []
200
- arrSampleMatch = []
201
- sampleAP = 0
202
-
203
- evaluationLog = ""
204
-
205
- pointsList,_,transcriptionsList = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(gtFile,evaluationParams['CRLF'],evaluationParams['LTRB'],True,False)
206
- for n in range(len(pointsList)):
207
- points = pointsList[n]
208
- transcription = transcriptionsList[n]
209
- dontCare = transcription == "###"
210
- if evaluationParams['LTRB']:
211
- gtRect = Rectangle(*points)
212
- gtPol = rectangle_to_polygon(gtRect)
213
- else:
214
- gtPol = polygon_from_points(points)
215
- gtPols.append(gtPol)
216
- gtPolPoints.append(points)
217
- if dontCare:
218
- gtDontCarePolsNum.append( len(gtPols)-1 )
219
-
220
- evaluationLog += "GT polygons: " + str(len(gtPols)) + (" (" + str(len(gtDontCarePolsNum)) + " don't care)\n" if len(gtDontCarePolsNum)>0 else "\n")
221
-
222
- if resFile in subm:
223
-
224
- if isinstance(subm[resFile], bytes):
225
- detFile = rrc_evaluation_funcs.decode_utf8(subm[resFile])
226
- else:
227
- detFile = subm[resFile]
228
-
229
- pointsList,confidencesList,_ = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(detFile,evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
230
- for n in range(len(pointsList)):
231
- points = pointsList[n]
232
-
233
- if evaluationParams['LTRB']:
234
- detRect = Rectangle(*points)
235
- detPol = rectangle_to_polygon(detRect)
236
- else:
237
- detPol = polygon_from_points(points)
238
- detPols.append(detPol)
239
- detPolPoints.append(points)
240
- if len(gtDontCarePolsNum)>0 :
241
- for dontCarePol in gtDontCarePolsNum:
242
- dontCarePol = gtPols[dontCarePol]
243
- intersected_area = get_intersection(dontCarePol,detPol)
244
- pdDimensions = detPol.area()
245
- precision = 0 if pdDimensions == 0 else intersected_area / pdDimensions
246
- if (precision > evaluationParams['AREA_PRECISION_CONSTRAINT'] ):
247
- detDontCarePolsNum.append( len(detPols)-1 )
248
- break
249
-
250
- evaluationLog += "DET polygons: " + str(len(detPols)) + (" (" + str(len(detDontCarePolsNum)) + " don't care)\n" if len(detDontCarePolsNum)>0 else "\n")
251
-
252
- if len(gtPols)>0 and len(detPols)>0:
253
- #Calculate IoU and precision matrixs
254
- outputShape=[len(gtPols),len(detPols)]
255
- iouMat = np.empty(outputShape)
256
- gtRectMat = np.zeros(len(gtPols),np.int8)
257
- detRectMat = np.zeros(len(detPols),np.int8)
258
- for gtNum in range(len(gtPols)):
259
- for detNum in range(len(detPols)):
260
- pG = gtPols[gtNum]
261
- pD = detPols[detNum]
262
- iouMat[gtNum,detNum] = get_intersection_over_union(pD,pG)
263
-
264
- for gtNum in range(len(gtPols)):
265
- for detNum in range(len(detPols)):
266
- if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and gtNum not in gtDontCarePolsNum and detNum not in detDontCarePolsNum :
267
- if iouMat[gtNum,detNum]>evaluationParams['IOU_CONSTRAINT']:
268
- gtRectMat[gtNum] = 1
269
- detRectMat[detNum] = 1
270
- detMatched += 1
271
- pairs.append({'gt':gtNum,'det':detNum})
272
- detMatchedNums.append(detNum)
273
- evaluationLog += "Match GT #" + str(gtNum) + " with Det #" + str(detNum) + "\n"
274
-
275
- if evaluationParams['CONFIDENCES']:
276
- for detNum in range(len(detPols)):
277
- if detNum not in detDontCarePolsNum :
278
- #we exclude the don't care detections
279
- match = detNum in detMatchedNums
280
-
281
- arrSampleConfidences.append(confidencesList[detNum])
282
- arrSampleMatch.append(match)
283
-
284
- arrGlobalConfidences.append(confidencesList[detNum])
285
- arrGlobalMatches.append(match)
286
-
287
- numGtCare = (len(gtPols) - len(gtDontCarePolsNum))
288
- numDetCare = (len(detPols) - len(detDontCarePolsNum))
289
- if numGtCare == 0:
290
- recall = float(1)
291
- precision = float(0) if numDetCare >0 else float(1)
292
- sampleAP = precision
293
- else:
294
- recall = float(detMatched) / numGtCare
295
- precision = 0 if numDetCare==0 else float(detMatched) / numDetCare
296
- if evaluationParams['CONFIDENCES'] and evaluationParams['PER_SAMPLE_RESULTS']:
297
- sampleAP = compute_ap(arrSampleConfidences, arrSampleMatch, numGtCare )
298
-
299
- hmean = 0 if (precision + recall)==0 else 2.0 * precision * recall / (precision + recall)
300
-
301
- matchedSum += detMatched
302
- numGlobalCareGt += numGtCare
303
- numGlobalCareDet += numDetCare
304
-
305
- if evaluationParams['PER_SAMPLE_RESULTS']:
306
- perSampleMetrics[resFile] = {
307
- 'precision':precision,
308
- 'recall':recall,
309
- 'hmean':hmean,
310
- 'pairs':pairs,
311
- 'AP':sampleAP,
312
- 'iouMat':[] if len(detPols)>100 else iouMat.tolist(),
313
- 'gtPolPoints':gtPolPoints,
314
- 'detPolPoints':detPolPoints,
315
- 'gtDontCare':gtDontCarePolsNum,
316
- 'detDontCare':detDontCarePolsNum,
317
- 'evaluationParams': evaluationParams,
318
- 'evaluationLog': evaluationLog
319
- }
320
-
321
- # Compute MAP and MAR
322
- AP = 0
323
- if evaluationParams['CONFIDENCES']:
324
- AP = compute_ap(arrGlobalConfidences, arrGlobalMatches, numGlobalCareGt)
325
-
326
- methodRecall = 0 if numGlobalCareGt == 0 else float(matchedSum)/numGlobalCareGt
327
- methodPrecision = 0 if numGlobalCareDet == 0 else float(matchedSum)/numGlobalCareDet
328
- methodHmean = 0 if methodRecall + methodPrecision==0 else 2* methodRecall * methodPrecision / (methodRecall + methodPrecision)
329
-
330
- methodMetrics = {'precision': methodPrecision, 'recall': methodRecall, 'hmean': methodHmean, 'AP': AP}
331
-
332
- resDict = {'calculated': True, 'Message': '', 'method': methodMetrics, 'per_sample': perSampleMetrics}
333
-
334
- return resDict
335
-
336
-
337
-
338
- if __name__=='__main__':
339
-
340
- rrc_evaluation_funcs.main_evaluation(None,default_evaluation_params,validate_data,evaluate_method)