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.
- pyxllib/algo/geo.py +12 -0
- pyxllib/algo/intervals.py +1 -1
- pyxllib/algo/matcher.py +78 -0
- pyxllib/algo/pupil.py +187 -19
- pyxllib/algo/specialist.py +2 -1
- pyxllib/algo/stat.py +38 -2
- {pyxlpr → pyxllib/autogui}/__init__.py +1 -1
- pyxllib/autogui/activewin.py +246 -0
- pyxllib/autogui/all.py +9 -0
- pyxllib/{ext/autogui → autogui}/autogui.py +40 -11
- pyxllib/autogui/uiautolib.py +362 -0
- pyxllib/autogui/wechat.py +827 -0
- pyxllib/autogui/wechat_msg.py +421 -0
- pyxllib/autogui/wxautolib.py +84 -0
- pyxllib/cv/slidercaptcha.py +137 -0
- pyxllib/data/echarts.py +123 -12
- pyxllib/data/jsonlib.py +89 -0
- pyxllib/data/pglib.py +514 -30
- pyxllib/data/sqlite.py +231 -4
- pyxllib/ext/JLineViewer.py +14 -1
- pyxllib/ext/drissionlib.py +277 -0
- pyxllib/ext/kq5034lib.py +0 -1594
- pyxllib/ext/robustprocfile.py +497 -0
- pyxllib/ext/unixlib.py +6 -5
- pyxllib/ext/utools.py +108 -95
- pyxllib/ext/webhook.py +32 -14
- pyxllib/ext/wjxlib.py +88 -0
- pyxllib/ext/wpsapi.py +124 -0
- pyxllib/ext/xlwork.py +9 -0
- pyxllib/ext/yuquelib.py +1003 -71
- pyxllib/file/docxlib.py +1 -1
- pyxllib/file/libreoffice.py +165 -0
- pyxllib/file/movielib.py +9 -0
- pyxllib/file/packlib/__init__.py +112 -75
- pyxllib/file/pdflib.py +1 -1
- pyxllib/file/pupil.py +1 -1
- pyxllib/file/specialist/dirlib.py +1 -1
- pyxllib/file/specialist/download.py +10 -3
- pyxllib/file/specialist/filelib.py +266 -55
- pyxllib/file/xlsxlib.py +205 -50
- pyxllib/file/xlsyncfile.py +341 -0
- pyxllib/prog/cachetools.py +64 -0
- pyxllib/prog/filelock.py +42 -0
- pyxllib/prog/multiprogs.py +940 -0
- pyxllib/prog/newbie.py +9 -2
- pyxllib/prog/pupil.py +129 -60
- pyxllib/prog/specialist/__init__.py +176 -2
- pyxllib/prog/specialist/bc.py +5 -2
- pyxllib/prog/specialist/browser.py +11 -2
- pyxllib/prog/specialist/datetime.py +68 -0
- pyxllib/prog/specialist/tictoc.py +12 -13
- pyxllib/prog/specialist/xllog.py +5 -5
- pyxllib/prog/xlosenv.py +7 -0
- pyxllib/text/airscript.js +744 -0
- pyxllib/text/charclasslib.py +17 -5
- pyxllib/text/jiebalib.py +6 -3
- pyxllib/text/jinjalib.py +32 -0
- pyxllib/text/jsa_ai_prompt.md +271 -0
- pyxllib/text/jscode.py +159 -4
- pyxllib/text/nestenv.py +1 -1
- pyxllib/text/newbie.py +12 -0
- pyxllib/text/pupil/common.py +26 -0
- pyxllib/text/specialist/ptag.py +2 -2
- pyxllib/text/templates/echart_base.html +11 -0
- pyxllib/text/templates/highlight_code.html +17 -0
- pyxllib/text/templates/latex_editor.html +103 -0
- pyxllib/text/xmllib.py +76 -14
- pyxllib/xl.py +2 -1
- pyxllib-0.3.197.dist-info/METADATA +48 -0
- pyxllib-0.3.197.dist-info/RECORD +126 -0
- {pyxllib-0.3.96.dist-info → pyxllib-0.3.197.dist-info}/WHEEL +1 -2
- pyxllib/ext/autogui/__init__.py +0 -8
- pyxllib-0.3.96.dist-info/METADATA +0 -51
- pyxllib-0.3.96.dist-info/RECORD +0 -333
- pyxllib-0.3.96.dist-info/top_level.txt +0 -2
- pyxlpr/ai/__init__.py +0 -5
- pyxlpr/ai/clientlib.py +0 -1281
- pyxlpr/ai/specialist.py +0 -286
- pyxlpr/ai/torch_app.py +0 -172
- pyxlpr/ai/xlpaddle.py +0 -655
- pyxlpr/ai/xltorch.py +0 -705
- pyxlpr/data/__init__.py +0 -11
- pyxlpr/data/coco.py +0 -1325
- pyxlpr/data/datacls.py +0 -365
- pyxlpr/data/datasets.py +0 -200
- pyxlpr/data/gptlib.py +0 -1291
- pyxlpr/data/icdar/__init__.py +0 -96
- pyxlpr/data/icdar/deteval.py +0 -377
- pyxlpr/data/icdar/icdar2013.py +0 -341
- pyxlpr/data/icdar/iou.py +0 -340
- pyxlpr/data/icdar/rrc_evaluation_funcs_1_1.py +0 -463
- pyxlpr/data/imtextline.py +0 -473
- pyxlpr/data/labelme.py +0 -866
- pyxlpr/data/removeline.py +0 -179
- pyxlpr/data/specialist.py +0 -57
- pyxlpr/eval/__init__.py +0 -85
- pyxlpr/paddleocr.py +0 -776
- pyxlpr/ppocr/__init__.py +0 -15
- pyxlpr/ppocr/configs/rec/multi_language/generate_multi_language_configs.py +0 -226
- pyxlpr/ppocr/data/__init__.py +0 -135
- pyxlpr/ppocr/data/imaug/ColorJitter.py +0 -26
- pyxlpr/ppocr/data/imaug/__init__.py +0 -67
- pyxlpr/ppocr/data/imaug/copy_paste.py +0 -170
- pyxlpr/ppocr/data/imaug/east_process.py +0 -437
- pyxlpr/ppocr/data/imaug/gen_table_mask.py +0 -244
- pyxlpr/ppocr/data/imaug/iaa_augment.py +0 -114
- pyxlpr/ppocr/data/imaug/label_ops.py +0 -789
- pyxlpr/ppocr/data/imaug/make_border_map.py +0 -184
- pyxlpr/ppocr/data/imaug/make_pse_gt.py +0 -106
- pyxlpr/ppocr/data/imaug/make_shrink_map.py +0 -126
- pyxlpr/ppocr/data/imaug/operators.py +0 -433
- pyxlpr/ppocr/data/imaug/pg_process.py +0 -906
- pyxlpr/ppocr/data/imaug/randaugment.py +0 -143
- pyxlpr/ppocr/data/imaug/random_crop_data.py +0 -239
- pyxlpr/ppocr/data/imaug/rec_img_aug.py +0 -533
- pyxlpr/ppocr/data/imaug/sast_process.py +0 -777
- pyxlpr/ppocr/data/imaug/text_image_aug/__init__.py +0 -17
- pyxlpr/ppocr/data/imaug/text_image_aug/augment.py +0 -120
- pyxlpr/ppocr/data/imaug/text_image_aug/warp_mls.py +0 -168
- pyxlpr/ppocr/data/lmdb_dataset.py +0 -115
- pyxlpr/ppocr/data/pgnet_dataset.py +0 -104
- pyxlpr/ppocr/data/pubtab_dataset.py +0 -107
- pyxlpr/ppocr/data/simple_dataset.py +0 -372
- pyxlpr/ppocr/losses/__init__.py +0 -61
- pyxlpr/ppocr/losses/ace_loss.py +0 -52
- pyxlpr/ppocr/losses/basic_loss.py +0 -135
- pyxlpr/ppocr/losses/center_loss.py +0 -88
- pyxlpr/ppocr/losses/cls_loss.py +0 -30
- pyxlpr/ppocr/losses/combined_loss.py +0 -67
- pyxlpr/ppocr/losses/det_basic_loss.py +0 -208
- pyxlpr/ppocr/losses/det_db_loss.py +0 -80
- pyxlpr/ppocr/losses/det_east_loss.py +0 -63
- pyxlpr/ppocr/losses/det_pse_loss.py +0 -149
- pyxlpr/ppocr/losses/det_sast_loss.py +0 -121
- pyxlpr/ppocr/losses/distillation_loss.py +0 -272
- pyxlpr/ppocr/losses/e2e_pg_loss.py +0 -140
- pyxlpr/ppocr/losses/kie_sdmgr_loss.py +0 -113
- pyxlpr/ppocr/losses/rec_aster_loss.py +0 -99
- pyxlpr/ppocr/losses/rec_att_loss.py +0 -39
- pyxlpr/ppocr/losses/rec_ctc_loss.py +0 -44
- pyxlpr/ppocr/losses/rec_enhanced_ctc_loss.py +0 -70
- pyxlpr/ppocr/losses/rec_nrtr_loss.py +0 -30
- pyxlpr/ppocr/losses/rec_sar_loss.py +0 -28
- pyxlpr/ppocr/losses/rec_srn_loss.py +0 -47
- pyxlpr/ppocr/losses/table_att_loss.py +0 -109
- pyxlpr/ppocr/metrics/__init__.py +0 -44
- pyxlpr/ppocr/metrics/cls_metric.py +0 -45
- pyxlpr/ppocr/metrics/det_metric.py +0 -82
- pyxlpr/ppocr/metrics/distillation_metric.py +0 -73
- pyxlpr/ppocr/metrics/e2e_metric.py +0 -86
- pyxlpr/ppocr/metrics/eval_det_iou.py +0 -274
- pyxlpr/ppocr/metrics/kie_metric.py +0 -70
- pyxlpr/ppocr/metrics/rec_metric.py +0 -75
- pyxlpr/ppocr/metrics/table_metric.py +0 -50
- pyxlpr/ppocr/modeling/architectures/__init__.py +0 -32
- pyxlpr/ppocr/modeling/architectures/base_model.py +0 -88
- pyxlpr/ppocr/modeling/architectures/distillation_model.py +0 -60
- pyxlpr/ppocr/modeling/backbones/__init__.py +0 -54
- pyxlpr/ppocr/modeling/backbones/det_mobilenet_v3.py +0 -268
- pyxlpr/ppocr/modeling/backbones/det_resnet_vd.py +0 -246
- pyxlpr/ppocr/modeling/backbones/det_resnet_vd_sast.py +0 -285
- pyxlpr/ppocr/modeling/backbones/e2e_resnet_vd_pg.py +0 -265
- pyxlpr/ppocr/modeling/backbones/kie_unet_sdmgr.py +0 -186
- pyxlpr/ppocr/modeling/backbones/rec_mobilenet_v3.py +0 -138
- pyxlpr/ppocr/modeling/backbones/rec_mv1_enhance.py +0 -258
- pyxlpr/ppocr/modeling/backbones/rec_nrtr_mtb.py +0 -48
- pyxlpr/ppocr/modeling/backbones/rec_resnet_31.py +0 -210
- pyxlpr/ppocr/modeling/backbones/rec_resnet_aster.py +0 -143
- pyxlpr/ppocr/modeling/backbones/rec_resnet_fpn.py +0 -307
- pyxlpr/ppocr/modeling/backbones/rec_resnet_vd.py +0 -286
- pyxlpr/ppocr/modeling/heads/__init__.py +0 -54
- pyxlpr/ppocr/modeling/heads/cls_head.py +0 -52
- pyxlpr/ppocr/modeling/heads/det_db_head.py +0 -118
- pyxlpr/ppocr/modeling/heads/det_east_head.py +0 -121
- pyxlpr/ppocr/modeling/heads/det_pse_head.py +0 -37
- pyxlpr/ppocr/modeling/heads/det_sast_head.py +0 -128
- pyxlpr/ppocr/modeling/heads/e2e_pg_head.py +0 -253
- pyxlpr/ppocr/modeling/heads/kie_sdmgr_head.py +0 -206
- pyxlpr/ppocr/modeling/heads/multiheadAttention.py +0 -163
- pyxlpr/ppocr/modeling/heads/rec_aster_head.py +0 -393
- pyxlpr/ppocr/modeling/heads/rec_att_head.py +0 -202
- pyxlpr/ppocr/modeling/heads/rec_ctc_head.py +0 -88
- pyxlpr/ppocr/modeling/heads/rec_nrtr_head.py +0 -826
- pyxlpr/ppocr/modeling/heads/rec_sar_head.py +0 -402
- pyxlpr/ppocr/modeling/heads/rec_srn_head.py +0 -280
- pyxlpr/ppocr/modeling/heads/self_attention.py +0 -406
- pyxlpr/ppocr/modeling/heads/table_att_head.py +0 -246
- pyxlpr/ppocr/modeling/necks/__init__.py +0 -32
- pyxlpr/ppocr/modeling/necks/db_fpn.py +0 -111
- pyxlpr/ppocr/modeling/necks/east_fpn.py +0 -188
- pyxlpr/ppocr/modeling/necks/fpn.py +0 -138
- pyxlpr/ppocr/modeling/necks/pg_fpn.py +0 -314
- pyxlpr/ppocr/modeling/necks/rnn.py +0 -92
- pyxlpr/ppocr/modeling/necks/sast_fpn.py +0 -284
- pyxlpr/ppocr/modeling/necks/table_fpn.py +0 -110
- pyxlpr/ppocr/modeling/transforms/__init__.py +0 -28
- pyxlpr/ppocr/modeling/transforms/stn.py +0 -135
- pyxlpr/ppocr/modeling/transforms/tps.py +0 -308
- pyxlpr/ppocr/modeling/transforms/tps_spatial_transformer.py +0 -156
- pyxlpr/ppocr/optimizer/__init__.py +0 -61
- pyxlpr/ppocr/optimizer/learning_rate.py +0 -228
- pyxlpr/ppocr/optimizer/lr_scheduler.py +0 -49
- pyxlpr/ppocr/optimizer/optimizer.py +0 -160
- pyxlpr/ppocr/optimizer/regularizer.py +0 -52
- pyxlpr/ppocr/postprocess/__init__.py +0 -55
- pyxlpr/ppocr/postprocess/cls_postprocess.py +0 -33
- pyxlpr/ppocr/postprocess/db_postprocess.py +0 -234
- pyxlpr/ppocr/postprocess/east_postprocess.py +0 -143
- pyxlpr/ppocr/postprocess/locality_aware_nms.py +0 -200
- pyxlpr/ppocr/postprocess/pg_postprocess.py +0 -52
- pyxlpr/ppocr/postprocess/pse_postprocess/__init__.py +0 -15
- pyxlpr/ppocr/postprocess/pse_postprocess/pse/__init__.py +0 -29
- pyxlpr/ppocr/postprocess/pse_postprocess/pse/setup.py +0 -14
- pyxlpr/ppocr/postprocess/pse_postprocess/pse_postprocess.py +0 -118
- pyxlpr/ppocr/postprocess/rec_postprocess.py +0 -654
- pyxlpr/ppocr/postprocess/sast_postprocess.py +0 -355
- pyxlpr/ppocr/tools/__init__.py +0 -14
- pyxlpr/ppocr/tools/eval.py +0 -83
- pyxlpr/ppocr/tools/export_center.py +0 -77
- pyxlpr/ppocr/tools/export_model.py +0 -129
- pyxlpr/ppocr/tools/infer/predict_cls.py +0 -151
- pyxlpr/ppocr/tools/infer/predict_det.py +0 -300
- pyxlpr/ppocr/tools/infer/predict_e2e.py +0 -169
- pyxlpr/ppocr/tools/infer/predict_rec.py +0 -414
- pyxlpr/ppocr/tools/infer/predict_system.py +0 -204
- pyxlpr/ppocr/tools/infer/utility.py +0 -629
- pyxlpr/ppocr/tools/infer_cls.py +0 -83
- pyxlpr/ppocr/tools/infer_det.py +0 -134
- pyxlpr/ppocr/tools/infer_e2e.py +0 -122
- pyxlpr/ppocr/tools/infer_kie.py +0 -153
- pyxlpr/ppocr/tools/infer_rec.py +0 -146
- pyxlpr/ppocr/tools/infer_table.py +0 -107
- pyxlpr/ppocr/tools/program.py +0 -596
- pyxlpr/ppocr/tools/test_hubserving.py +0 -117
- pyxlpr/ppocr/tools/train.py +0 -163
- pyxlpr/ppocr/tools/xlprog.py +0 -748
- pyxlpr/ppocr/utils/EN_symbol_dict.txt +0 -94
- pyxlpr/ppocr/utils/__init__.py +0 -24
- pyxlpr/ppocr/utils/dict/ar_dict.txt +0 -117
- pyxlpr/ppocr/utils/dict/arabic_dict.txt +0 -162
- pyxlpr/ppocr/utils/dict/be_dict.txt +0 -145
- pyxlpr/ppocr/utils/dict/bg_dict.txt +0 -140
- pyxlpr/ppocr/utils/dict/chinese_cht_dict.txt +0 -8421
- pyxlpr/ppocr/utils/dict/cyrillic_dict.txt +0 -163
- pyxlpr/ppocr/utils/dict/devanagari_dict.txt +0 -167
- pyxlpr/ppocr/utils/dict/en_dict.txt +0 -63
- pyxlpr/ppocr/utils/dict/fa_dict.txt +0 -136
- pyxlpr/ppocr/utils/dict/french_dict.txt +0 -136
- pyxlpr/ppocr/utils/dict/german_dict.txt +0 -143
- pyxlpr/ppocr/utils/dict/hi_dict.txt +0 -162
- pyxlpr/ppocr/utils/dict/it_dict.txt +0 -118
- pyxlpr/ppocr/utils/dict/japan_dict.txt +0 -4399
- pyxlpr/ppocr/utils/dict/ka_dict.txt +0 -153
- pyxlpr/ppocr/utils/dict/korean_dict.txt +0 -3688
- pyxlpr/ppocr/utils/dict/latin_dict.txt +0 -185
- pyxlpr/ppocr/utils/dict/mr_dict.txt +0 -153
- pyxlpr/ppocr/utils/dict/ne_dict.txt +0 -153
- pyxlpr/ppocr/utils/dict/oc_dict.txt +0 -96
- pyxlpr/ppocr/utils/dict/pu_dict.txt +0 -130
- pyxlpr/ppocr/utils/dict/rs_dict.txt +0 -91
- pyxlpr/ppocr/utils/dict/rsc_dict.txt +0 -134
- pyxlpr/ppocr/utils/dict/ru_dict.txt +0 -125
- pyxlpr/ppocr/utils/dict/ta_dict.txt +0 -128
- pyxlpr/ppocr/utils/dict/table_dict.txt +0 -277
- pyxlpr/ppocr/utils/dict/table_structure_dict.txt +0 -2759
- pyxlpr/ppocr/utils/dict/te_dict.txt +0 -151
- pyxlpr/ppocr/utils/dict/ug_dict.txt +0 -114
- pyxlpr/ppocr/utils/dict/uk_dict.txt +0 -142
- pyxlpr/ppocr/utils/dict/ur_dict.txt +0 -137
- pyxlpr/ppocr/utils/dict/xi_dict.txt +0 -110
- pyxlpr/ppocr/utils/dict90.txt +0 -90
- pyxlpr/ppocr/utils/e2e_metric/Deteval.py +0 -574
- pyxlpr/ppocr/utils/e2e_metric/polygon_fast.py +0 -83
- pyxlpr/ppocr/utils/e2e_utils/extract_batchsize.py +0 -87
- pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_fast.py +0 -457
- pyxlpr/ppocr/utils/e2e_utils/extract_textpoint_slow.py +0 -592
- pyxlpr/ppocr/utils/e2e_utils/pgnet_pp_utils.py +0 -162
- pyxlpr/ppocr/utils/e2e_utils/visual.py +0 -162
- pyxlpr/ppocr/utils/en_dict.txt +0 -95
- pyxlpr/ppocr/utils/gen_label.py +0 -81
- pyxlpr/ppocr/utils/ic15_dict.txt +0 -36
- pyxlpr/ppocr/utils/iou.py +0 -54
- pyxlpr/ppocr/utils/logging.py +0 -69
- pyxlpr/ppocr/utils/network.py +0 -84
- pyxlpr/ppocr/utils/ppocr_keys_v1.txt +0 -6623
- pyxlpr/ppocr/utils/profiler.py +0 -110
- pyxlpr/ppocr/utils/save_load.py +0 -150
- pyxlpr/ppocr/utils/stats.py +0 -72
- pyxlpr/ppocr/utils/utility.py +0 -80
- pyxlpr/ppstructure/__init__.py +0 -13
- pyxlpr/ppstructure/predict_system.py +0 -187
- pyxlpr/ppstructure/table/__init__.py +0 -13
- pyxlpr/ppstructure/table/eval_table.py +0 -72
- pyxlpr/ppstructure/table/matcher.py +0 -192
- pyxlpr/ppstructure/table/predict_structure.py +0 -136
- pyxlpr/ppstructure/table/predict_table.py +0 -221
- pyxlpr/ppstructure/table/table_metric/__init__.py +0 -16
- pyxlpr/ppstructure/table/table_metric/parallel.py +0 -51
- pyxlpr/ppstructure/table/table_metric/table_metric.py +0 -247
- pyxlpr/ppstructure/table/tablepyxl/__init__.py +0 -13
- pyxlpr/ppstructure/table/tablepyxl/style.py +0 -283
- pyxlpr/ppstructure/table/tablepyxl/tablepyxl.py +0 -118
- pyxlpr/ppstructure/utility.py +0 -71
- pyxlpr/xlai.py +0 -10
- /pyxllib/{ext/autogui → autogui}/virtualkey.py +0 -0
- {pyxllib-0.3.96.dist-info → pyxllib-0.3.197.dist-info/licenses}/LICENSE +0 -0
pyxlpr/data/icdar/icdar2013.py
DELETED
@@ -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)
|