openocr-python 0.0.2__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 (323) hide show
  1. openocr/__init__.py +11 -0
  2. openocr/configs/det/dbnet/repvit_db.yml +173 -0
  3. openocr/configs/rec/abinet/resnet45_trans_abinet_lang.yml +94 -0
  4. openocr/configs/rec/abinet/resnet45_trans_abinet_wo_lang.yml +93 -0
  5. openocr/configs/rec/abinet/svtrv2_abinet_lang.yml +130 -0
  6. openocr/configs/rec/abinet/svtrv2_abinet_wo_lang.yml +128 -0
  7. openocr/configs/rec/aster/resnet31_lstm_aster_tps_on.yml +93 -0
  8. openocr/configs/rec/aster/svtrv2_aster.yml +127 -0
  9. openocr/configs/rec/aster/svtrv2_aster_tps_on.yml +102 -0
  10. openocr/configs/rec/autostr/autostr_lstm_aster_tps_on.yml +95 -0
  11. openocr/configs/rec/busnet/svtrv2_busnet.yml +135 -0
  12. openocr/configs/rec/busnet/svtrv2_busnet_pretraining.yml +134 -0
  13. openocr/configs/rec/busnet/vit_busnet.yml +104 -0
  14. openocr/configs/rec/busnet/vit_busnet_pretraining.yml +104 -0
  15. openocr/configs/rec/cam/convnextv2_cam_tps_on.yml +118 -0
  16. openocr/configs/rec/cam/convnextv2_tiny_cam_tps_on.yml +118 -0
  17. openocr/configs/rec/cam/svtrv2_cam_tps_on.yml +123 -0
  18. openocr/configs/rec/cdistnet/resnet45_trans_cdistnet.yml +93 -0
  19. openocr/configs/rec/cdistnet/svtrv2_cdistnet.yml +139 -0
  20. openocr/configs/rec/cppd/svtr_base_cppd.yml +123 -0
  21. openocr/configs/rec/cppd/svtr_base_cppd_ch.yml +126 -0
  22. openocr/configs/rec/cppd/svtr_base_cppd_h8.yml +123 -0
  23. openocr/configs/rec/cppd/svtr_base_cppd_syn.yml +124 -0
  24. openocr/configs/rec/cppd/svtrv2_cppd.yml +150 -0
  25. openocr/configs/rec/dan/resnet45_fpn_dan.yml +98 -0
  26. openocr/configs/rec/dan/svtrv2_dan.yml +130 -0
  27. openocr/configs/rec/focalsvtr/focalsvtr_ctc.yml +137 -0
  28. openocr/configs/rec/gtc/svtrv2_lnconv_nrtr_gtc.yml +168 -0
  29. openocr/configs/rec/gtc/svtrv2_lnconv_smtr_gtc_long_infer.yml +151 -0
  30. openocr/configs/rec/gtc/svtrv2_lnconv_smtr_gtc_smtr_long.yml +150 -0
  31. openocr/configs/rec/gtc/svtrv2_lnconv_smtr_gtc_stream.yml +152 -0
  32. openocr/configs/rec/igtr/svtr_base_ds_igtr.yml +157 -0
  33. openocr/configs/rec/lister/focalsvtr_lister_wo_fem_maxratio12.yml +133 -0
  34. openocr/configs/rec/lister/svtrv2_lister_wo_fem_maxratio12.yml +138 -0
  35. openocr/configs/rec/lpv/svtr_base_lpv.yml +124 -0
  36. openocr/configs/rec/lpv/svtr_base_lpv_wo_glrm.yml +123 -0
  37. openocr/configs/rec/lpv/svtrv2_lpv.yml +147 -0
  38. openocr/configs/rec/lpv/svtrv2_lpv_wo_glrm.yml +146 -0
  39. openocr/configs/rec/maerec/vit_nrtr.yml +116 -0
  40. openocr/configs/rec/matrn/resnet45_trans_matrn.yml +95 -0
  41. openocr/configs/rec/matrn/svtrv2_matrn.yml +130 -0
  42. openocr/configs/rec/mgpstr/svtrv2_mgpstr_only_char.yml +140 -0
  43. openocr/configs/rec/mgpstr/vit_base_mgpstr_only_char.yml +111 -0
  44. openocr/configs/rec/mgpstr/vit_large_mgpstr_only_char.yml +110 -0
  45. openocr/configs/rec/mgpstr/vit_mgpstr.yml +110 -0
  46. openocr/configs/rec/mgpstr/vit_mgpstr_only_char.yml +110 -0
  47. openocr/configs/rec/moran/resnet31_lstm_moran.yml +92 -0
  48. openocr/configs/rec/nrtr/focalsvtr_nrtr_maxraio12.yml +145 -0
  49. openocr/configs/rec/nrtr/nrtr.yml +107 -0
  50. openocr/configs/rec/nrtr/svtr_base_nrtr.yml +118 -0
  51. openocr/configs/rec/nrtr/svtr_base_nrtr_syn.yml +119 -0
  52. openocr/configs/rec/nrtr/svtrv2_nrtr.yml +146 -0
  53. openocr/configs/rec/ote/svtr_base_h8_ote.yml +117 -0
  54. openocr/configs/rec/ote/svtr_base_ote.yml +116 -0
  55. openocr/configs/rec/parseq/focalsvtr_parseq_maxratio12.yml +140 -0
  56. openocr/configs/rec/parseq/svrtv2_parseq.yml +136 -0
  57. openocr/configs/rec/parseq/vit_parseq.yml +100 -0
  58. openocr/configs/rec/robustscanner/resnet31_robustscanner.yml +102 -0
  59. openocr/configs/rec/robustscanner/svtrv2_robustscanner.yml +134 -0
  60. openocr/configs/rec/sar/resnet31_lstm_sar.yml +94 -0
  61. openocr/configs/rec/sar/svtrv2_sar.yml +128 -0
  62. openocr/configs/rec/seed/resnet31_lstm_seed_tps_on.yml +96 -0
  63. openocr/configs/rec/smtr/focalsvtr_smtr.yml +150 -0
  64. openocr/configs/rec/smtr/focalsvtr_smtr_long.yml +133 -0
  65. openocr/configs/rec/smtr/svtrv2_smtr.yml +150 -0
  66. openocr/configs/rec/smtr/svtrv2_smtr_bi.yml +136 -0
  67. openocr/configs/rec/srn/resnet50_fpn_srn.yml +97 -0
  68. openocr/configs/rec/srn/svtrv2_srn.yml +131 -0
  69. openocr/configs/rec/svtrs/convnextv2_ctc.yml +105 -0
  70. openocr/configs/rec/svtrs/convnextv2_h8_ctc.yml +105 -0
  71. openocr/configs/rec/svtrs/convnextv2_h8_rctc.yml +106 -0
  72. openocr/configs/rec/svtrs/convnextv2_rctc.yml +106 -0
  73. openocr/configs/rec/svtrs/convnextv2_tiny_h8_ctc.yml +105 -0
  74. openocr/configs/rec/svtrs/convnextv2_tiny_h8_rctc.yml +106 -0
  75. openocr/configs/rec/svtrs/crnn_ctc.yml +99 -0
  76. openocr/configs/rec/svtrs/crnn_ctc_long.yml +116 -0
  77. openocr/configs/rec/svtrs/focalnet_base_ctc.yml +108 -0
  78. openocr/configs/rec/svtrs/focalnet_base_rctc.yml +109 -0
  79. openocr/configs/rec/svtrs/focalsvtr_ctc.yml +106 -0
  80. openocr/configs/rec/svtrs/focalsvtr_rctc.yml +107 -0
  81. openocr/configs/rec/svtrs/resnet45_trans_ctc.yml +103 -0
  82. openocr/configs/rec/svtrs/resnet45_trans_rctc.yml +104 -0
  83. openocr/configs/rec/svtrs/svtr_base_ctc.yml +110 -0
  84. openocr/configs/rec/svtrs/svtr_base_rctc.yml +111 -0
  85. openocr/configs/rec/svtrs/svtrnet_ctc_syn.yml +111 -0
  86. openocr/configs/rec/svtrs/vit_ctc.yml +103 -0
  87. openocr/configs/rec/svtrs/vit_rctc.yml +103 -0
  88. openocr/configs/rec/svtrv2/repsvtr_ch.yml +121 -0
  89. openocr/configs/rec/svtrv2/svtrv2_ch.yml +133 -0
  90. openocr/configs/rec/svtrv2/svtrv2_ctc.yml +136 -0
  91. openocr/configs/rec/svtrv2/svtrv2_rctc.yml +135 -0
  92. openocr/configs/rec/svtrv2/svtrv2_small_rctc.yml +135 -0
  93. openocr/configs/rec/svtrv2/svtrv2_smtr_gtc_rctc.yml +162 -0
  94. openocr/configs/rec/svtrv2/svtrv2_smtr_gtc_rctc_ch.yml +153 -0
  95. openocr/configs/rec/svtrv2/svtrv2_tiny_rctc.yml +135 -0
  96. openocr/configs/rec/visionlan/resnet45_trans_visionlan_LA.yml +103 -0
  97. openocr/configs/rec/visionlan/resnet45_trans_visionlan_LF_1.yml +102 -0
  98. openocr/configs/rec/visionlan/resnet45_trans_visionlan_LF_2.yml +103 -0
  99. openocr/configs/rec/visionlan/svtrv2_visionlan_LA.yml +112 -0
  100. openocr/configs/rec/visionlan/svtrv2_visionlan_LF_1.yml +111 -0
  101. openocr/configs/rec/visionlan/svtrv2_visionlan_LF_2.yml +112 -0
  102. openocr/demo_gradio.py +128 -0
  103. openocr/opendet/modeling/__init__.py +11 -0
  104. openocr/opendet/modeling/backbones/__init__.py +14 -0
  105. openocr/opendet/modeling/backbones/repvit.py +340 -0
  106. openocr/opendet/modeling/base_detector.py +69 -0
  107. openocr/opendet/modeling/heads/__init__.py +14 -0
  108. openocr/opendet/modeling/heads/db_head.py +73 -0
  109. openocr/opendet/modeling/necks/__init__.py +14 -0
  110. openocr/opendet/modeling/necks/db_fpn.py +609 -0
  111. openocr/opendet/postprocess/__init__.py +18 -0
  112. openocr/opendet/postprocess/db_postprocess.py +273 -0
  113. openocr/opendet/preprocess/__init__.py +154 -0
  114. openocr/opendet/preprocess/crop_resize.py +121 -0
  115. openocr/opendet/preprocess/db_resize_for_test.py +135 -0
  116. openocr/openrec/losses/__init__.py +62 -0
  117. openocr/openrec/losses/abinet_loss.py +42 -0
  118. openocr/openrec/losses/ar_loss.py +23 -0
  119. openocr/openrec/losses/cam_loss.py +48 -0
  120. openocr/openrec/losses/cdistnet_loss.py +34 -0
  121. openocr/openrec/losses/ce_loss.py +68 -0
  122. openocr/openrec/losses/cppd_loss.py +77 -0
  123. openocr/openrec/losses/ctc_loss.py +33 -0
  124. openocr/openrec/losses/igtr_loss.py +12 -0
  125. openocr/openrec/losses/lister_loss.py +14 -0
  126. openocr/openrec/losses/lpv_loss.py +30 -0
  127. openocr/openrec/losses/mgp_loss.py +34 -0
  128. openocr/openrec/losses/parseq_loss.py +12 -0
  129. openocr/openrec/losses/robustscanner_loss.py +20 -0
  130. openocr/openrec/losses/seed_loss.py +46 -0
  131. openocr/openrec/losses/smtr_loss.py +12 -0
  132. openocr/openrec/losses/srn_loss.py +40 -0
  133. openocr/openrec/losses/visionlan_loss.py +58 -0
  134. openocr/openrec/metrics/__init__.py +19 -0
  135. openocr/openrec/metrics/rec_metric.py +270 -0
  136. openocr/openrec/metrics/rec_metric_gtc.py +58 -0
  137. openocr/openrec/metrics/rec_metric_long.py +142 -0
  138. openocr/openrec/metrics/rec_metric_mgp.py +93 -0
  139. openocr/openrec/modeling/__init__.py +11 -0
  140. openocr/openrec/modeling/base_recognizer.py +69 -0
  141. openocr/openrec/modeling/common.py +238 -0
  142. openocr/openrec/modeling/decoders/__init__.py +109 -0
  143. openocr/openrec/modeling/decoders/abinet_decoder.py +283 -0
  144. openocr/openrec/modeling/decoders/aster_decoder.py +170 -0
  145. openocr/openrec/modeling/decoders/bus_decoder.py +133 -0
  146. openocr/openrec/modeling/decoders/cam_decoder.py +43 -0
  147. openocr/openrec/modeling/decoders/cdistnet_decoder.py +334 -0
  148. openocr/openrec/modeling/decoders/cppd_decoder.py +393 -0
  149. openocr/openrec/modeling/decoders/ctc_decoder.py +203 -0
  150. openocr/openrec/modeling/decoders/dan_decoder.py +203 -0
  151. openocr/openrec/modeling/decoders/igtr_decoder.py +815 -0
  152. openocr/openrec/modeling/decoders/lister_decoder.py +535 -0
  153. openocr/openrec/modeling/decoders/lpv_decoder.py +119 -0
  154. openocr/openrec/modeling/decoders/matrn_decoder.py +236 -0
  155. openocr/openrec/modeling/decoders/mgp_decoder.py +99 -0
  156. openocr/openrec/modeling/decoders/nrtr_decoder.py +439 -0
  157. openocr/openrec/modeling/decoders/ote_decoder.py +205 -0
  158. openocr/openrec/modeling/decoders/parseq_decoder.py +504 -0
  159. openocr/openrec/modeling/decoders/rctc_decoder.py +70 -0
  160. openocr/openrec/modeling/decoders/robustscanner_decoder.py +749 -0
  161. openocr/openrec/modeling/decoders/sar_decoder.py +236 -0
  162. openocr/openrec/modeling/decoders/smtr_decoder.py +621 -0
  163. openocr/openrec/modeling/decoders/smtr_decoder_nattn.py +521 -0
  164. openocr/openrec/modeling/decoders/srn_decoder.py +283 -0
  165. openocr/openrec/modeling/decoders/visionlan_decoder.py +321 -0
  166. openocr/openrec/modeling/encoders/__init__.py +39 -0
  167. openocr/openrec/modeling/encoders/autostr_encoder.py +327 -0
  168. openocr/openrec/modeling/encoders/cam_encoder.py +760 -0
  169. openocr/openrec/modeling/encoders/convnextv2.py +213 -0
  170. openocr/openrec/modeling/encoders/focalsvtr.py +631 -0
  171. openocr/openrec/modeling/encoders/nrtr_encoder.py +28 -0
  172. openocr/openrec/modeling/encoders/rec_hgnet.py +346 -0
  173. openocr/openrec/modeling/encoders/rec_lcnetv3.py +488 -0
  174. openocr/openrec/modeling/encoders/rec_mobilenet_v3.py +132 -0
  175. openocr/openrec/modeling/encoders/rec_mv1_enhance.py +254 -0
  176. openocr/openrec/modeling/encoders/rec_nrtr_mtb.py +37 -0
  177. openocr/openrec/modeling/encoders/rec_resnet_31.py +213 -0
  178. openocr/openrec/modeling/encoders/rec_resnet_45.py +183 -0
  179. openocr/openrec/modeling/encoders/rec_resnet_fpn.py +216 -0
  180. openocr/openrec/modeling/encoders/rec_resnet_vd.py +252 -0
  181. openocr/openrec/modeling/encoders/repvit.py +338 -0
  182. openocr/openrec/modeling/encoders/resnet31_rnn.py +123 -0
  183. openocr/openrec/modeling/encoders/svtrnet.py +574 -0
  184. openocr/openrec/modeling/encoders/svtrnet2dpos.py +616 -0
  185. openocr/openrec/modeling/encoders/svtrv2.py +470 -0
  186. openocr/openrec/modeling/encoders/svtrv2_lnconv.py +503 -0
  187. openocr/openrec/modeling/encoders/svtrv2_lnconv_two33.py +517 -0
  188. openocr/openrec/modeling/encoders/vit.py +120 -0
  189. openocr/openrec/modeling/transforms/__init__.py +15 -0
  190. openocr/openrec/modeling/transforms/aster_tps.py +262 -0
  191. openocr/openrec/modeling/transforms/moran.py +136 -0
  192. openocr/openrec/modeling/transforms/tps.py +246 -0
  193. openocr/openrec/optimizer/__init__.py +73 -0
  194. openocr/openrec/optimizer/lr.py +227 -0
  195. openocr/openrec/postprocess/__init__.py +72 -0
  196. openocr/openrec/postprocess/abinet_postprocess.py +37 -0
  197. openocr/openrec/postprocess/ar_postprocess.py +63 -0
  198. openocr/openrec/postprocess/ce_postprocess.py +43 -0
  199. openocr/openrec/postprocess/char_postprocess.py +108 -0
  200. openocr/openrec/postprocess/cppd_postprocess.py +42 -0
  201. openocr/openrec/postprocess/ctc_postprocess.py +119 -0
  202. openocr/openrec/postprocess/igtr_postprocess.py +100 -0
  203. openocr/openrec/postprocess/lister_postprocess.py +59 -0
  204. openocr/openrec/postprocess/mgp_postprocess.py +143 -0
  205. openocr/openrec/postprocess/nrtr_postprocess.py +75 -0
  206. openocr/openrec/postprocess/smtr_postprocess.py +73 -0
  207. openocr/openrec/postprocess/srn_postprocess.py +80 -0
  208. openocr/openrec/postprocess/visionlan_postprocess.py +81 -0
  209. openocr/openrec/preprocess/__init__.py +173 -0
  210. openocr/openrec/preprocess/abinet_aug.py +473 -0
  211. openocr/openrec/preprocess/abinet_label_encode.py +36 -0
  212. openocr/openrec/preprocess/ar_label_encode.py +36 -0
  213. openocr/openrec/preprocess/auto_augment.py +1012 -0
  214. openocr/openrec/preprocess/cam_label_encode.py +141 -0
  215. openocr/openrec/preprocess/ce_label_encode.py +116 -0
  216. openocr/openrec/preprocess/char_label_encode.py +36 -0
  217. openocr/openrec/preprocess/cppd_label_encode.py +173 -0
  218. openocr/openrec/preprocess/ctc_label_encode.py +124 -0
  219. openocr/openrec/preprocess/ep_label_encode.py +38 -0
  220. openocr/openrec/preprocess/igtr_label_encode.py +360 -0
  221. openocr/openrec/preprocess/mgp_label_encode.py +95 -0
  222. openocr/openrec/preprocess/parseq_aug.py +150 -0
  223. openocr/openrec/preprocess/rec_aug.py +211 -0
  224. openocr/openrec/preprocess/resize.py +534 -0
  225. openocr/openrec/preprocess/smtr_label_encode.py +125 -0
  226. openocr/openrec/preprocess/srn_label_encode.py +37 -0
  227. openocr/openrec/preprocess/visionlan_label_encode.py +67 -0
  228. openocr/tools/create_lmdb_dataset.py +118 -0
  229. openocr/tools/data/__init__.py +94 -0
  230. openocr/tools/data/collate_fn.py +100 -0
  231. openocr/tools/data/lmdb_dataset.py +142 -0
  232. openocr/tools/data/lmdb_dataset_test.py +166 -0
  233. openocr/tools/data/multi_scale_sampler.py +177 -0
  234. openocr/tools/data/ratio_dataset.py +217 -0
  235. openocr/tools/data/ratio_dataset_test.py +273 -0
  236. openocr/tools/data/ratio_dataset_tvresize.py +213 -0
  237. openocr/tools/data/ratio_dataset_tvresize_test.py +276 -0
  238. openocr/tools/data/ratio_sampler.py +190 -0
  239. openocr/tools/data/simple_dataset.py +263 -0
  240. openocr/tools/data/strlmdb_dataset.py +143 -0
  241. openocr/tools/engine/__init__.py +5 -0
  242. openocr/tools/engine/config.py +158 -0
  243. openocr/tools/engine/trainer.py +621 -0
  244. openocr/tools/eval_rec.py +41 -0
  245. openocr/tools/eval_rec_all_ch.py +184 -0
  246. openocr/tools/eval_rec_all_en.py +206 -0
  247. openocr/tools/eval_rec_all_long.py +119 -0
  248. openocr/tools/eval_rec_all_long_simple.py +122 -0
  249. openocr/tools/export_rec.py +118 -0
  250. openocr/tools/infer/onnx_engine.py +65 -0
  251. openocr/tools/infer/predict_rec.py +140 -0
  252. openocr/tools/infer/utility.py +234 -0
  253. openocr/tools/infer_det.py +449 -0
  254. openocr/tools/infer_e2e.py +462 -0
  255. openocr/tools/infer_e2e_parallel.py +184 -0
  256. openocr/tools/infer_rec.py +371 -0
  257. openocr/tools/train_rec.py +37 -0
  258. openocr/tools/utility.py +45 -0
  259. openocr/tools/utils/EN_symbol_dict.txt +94 -0
  260. openocr/tools/utils/__init__.py +0 -0
  261. openocr/tools/utils/ckpt.py +87 -0
  262. openocr/tools/utils/dict/ar_dict.txt +117 -0
  263. openocr/tools/utils/dict/arabic_dict.txt +161 -0
  264. openocr/tools/utils/dict/be_dict.txt +145 -0
  265. openocr/tools/utils/dict/bg_dict.txt +140 -0
  266. openocr/tools/utils/dict/chinese_cht_dict.txt +8421 -0
  267. openocr/tools/utils/dict/cyrillic_dict.txt +163 -0
  268. openocr/tools/utils/dict/devanagari_dict.txt +167 -0
  269. openocr/tools/utils/dict/en_dict.txt +63 -0
  270. openocr/tools/utils/dict/fa_dict.txt +136 -0
  271. openocr/tools/utils/dict/french_dict.txt +136 -0
  272. openocr/tools/utils/dict/german_dict.txt +143 -0
  273. openocr/tools/utils/dict/hi_dict.txt +162 -0
  274. openocr/tools/utils/dict/it_dict.txt +118 -0
  275. openocr/tools/utils/dict/japan_dict.txt +4399 -0
  276. openocr/tools/utils/dict/ka_dict.txt +153 -0
  277. openocr/tools/utils/dict/kie_dict/xfund_class_list.txt +4 -0
  278. openocr/tools/utils/dict/korean_dict.txt +3688 -0
  279. openocr/tools/utils/dict/latex_symbol_dict.txt +111 -0
  280. openocr/tools/utils/dict/latin_dict.txt +185 -0
  281. openocr/tools/utils/dict/layout_dict/layout_cdla_dict.txt +10 -0
  282. openocr/tools/utils/dict/layout_dict/layout_publaynet_dict.txt +5 -0
  283. openocr/tools/utils/dict/layout_dict/layout_table_dict.txt +1 -0
  284. openocr/tools/utils/dict/mr_dict.txt +153 -0
  285. openocr/tools/utils/dict/ne_dict.txt +153 -0
  286. openocr/tools/utils/dict/oc_dict.txt +96 -0
  287. openocr/tools/utils/dict/pu_dict.txt +130 -0
  288. openocr/tools/utils/dict/rs_dict.txt +91 -0
  289. openocr/tools/utils/dict/rsc_dict.txt +134 -0
  290. openocr/tools/utils/dict/ru_dict.txt +125 -0
  291. openocr/tools/utils/dict/spin_dict.txt +68 -0
  292. openocr/tools/utils/dict/ta_dict.txt +128 -0
  293. openocr/tools/utils/dict/table_dict.txt +277 -0
  294. openocr/tools/utils/dict/table_master_structure_dict.txt +39 -0
  295. openocr/tools/utils/dict/table_structure_dict.txt +28 -0
  296. openocr/tools/utils/dict/table_structure_dict_ch.txt +48 -0
  297. openocr/tools/utils/dict/te_dict.txt +151 -0
  298. openocr/tools/utils/dict/ug_dict.txt +114 -0
  299. openocr/tools/utils/dict/uk_dict.txt +142 -0
  300. openocr/tools/utils/dict/ur_dict.txt +137 -0
  301. openocr/tools/utils/dict/xi_dict.txt +110 -0
  302. openocr/tools/utils/dict90.txt +90 -0
  303. openocr/tools/utils/e2e_metric/Deteval.py +802 -0
  304. openocr/tools/utils/e2e_metric/polygon_fast.py +70 -0
  305. openocr/tools/utils/e2e_utils/extract_batchsize.py +86 -0
  306. openocr/tools/utils/e2e_utils/extract_textpoint_fast.py +479 -0
  307. openocr/tools/utils/e2e_utils/extract_textpoint_slow.py +582 -0
  308. openocr/tools/utils/e2e_utils/pgnet_pp_utils.py +159 -0
  309. openocr/tools/utils/e2e_utils/visual.py +152 -0
  310. openocr/tools/utils/en_dict.txt +95 -0
  311. openocr/tools/utils/gen_label.py +68 -0
  312. openocr/tools/utils/ic15_dict.txt +36 -0
  313. openocr/tools/utils/logging.py +56 -0
  314. openocr/tools/utils/poly_nms.py +132 -0
  315. openocr/tools/utils/ppocr_keys_v1.txt +6623 -0
  316. openocr/tools/utils/stats.py +58 -0
  317. openocr/tools/utils/utility.py +165 -0
  318. openocr/tools/utils/visual.py +117 -0
  319. openocr_python-0.0.2.dist-info/LICENCE +201 -0
  320. openocr_python-0.0.2.dist-info/METADATA +98 -0
  321. openocr_python-0.0.2.dist-info/RECORD +323 -0
  322. openocr_python-0.0.2.dist-info/WHEEL +5 -0
  323. openocr_python-0.0.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,159 @@
1
+ import torch
2
+ import os
3
+ import sys
4
+
5
+ __dir__ = os.path.dirname(__file__)
6
+ sys.path.append(__dir__)
7
+ sys.path.append(os.path.join(__dir__, ".."))
8
+ from extract_textpoint_slow import *
9
+ from extract_textpoint_fast import generate_pivot_list_fast, restore_poly
10
+
11
+
12
+ class PGNet_PostProcess(object):
13
+ # two different post-process
14
+ def __init__(
15
+ self,
16
+ character_dict_path,
17
+ valid_set,
18
+ score_thresh,
19
+ outs_dict,
20
+ shape_list,
21
+ point_gather_mode=None, ):
22
+ self.Lexicon_Table = get_dict(character_dict_path)
23
+ self.valid_set = valid_set
24
+ self.score_thresh = score_thresh
25
+ self.outs_dict = outs_dict
26
+ self.shape_list = shape_list
27
+ self.point_gather_mode = point_gather_mode
28
+
29
+ def pg_postprocess_fast(self):
30
+ p_score = self.outs_dict["f_score"]
31
+ p_border = self.outs_dict["f_border"]
32
+ p_char = self.outs_dict["f_char"]
33
+ p_direction = self.outs_dict["f_direction"]
34
+ if isinstance(p_score, torch.Tensor):
35
+ p_score = p_score[0].numpy()
36
+ p_border = p_border[0].numpy()
37
+ p_direction = p_direction[0].numpy()
38
+ p_char = p_char[0].numpy()
39
+ else:
40
+ p_score = p_score[0]
41
+ p_border = p_border[0]
42
+ p_direction = p_direction[0]
43
+ p_char = p_char[0]
44
+
45
+ src_h, src_w, ratio_h, ratio_w = self.shape_list[0]
46
+ instance_yxs_list, seq_strs = generate_pivot_list_fast(
47
+ p_score,
48
+ p_char,
49
+ p_direction,
50
+ self.Lexicon_Table,
51
+ score_thresh=self.score_thresh,
52
+ point_gather_mode=self.point_gather_mode, )
53
+ poly_list, keep_str_list = restore_poly(
54
+ instance_yxs_list,
55
+ seq_strs,
56
+ p_border,
57
+ ratio_w,
58
+ ratio_h,
59
+ src_w,
60
+ src_h,
61
+ self.valid_set, )
62
+ data = {
63
+ "points": poly_list,
64
+ "texts": keep_str_list,
65
+ }
66
+ return data
67
+
68
+ def pg_postprocess_slow(self):
69
+ p_score = self.outs_dict["f_score"]
70
+ p_border = self.outs_dict["f_border"]
71
+ p_char = self.outs_dict["f_char"]
72
+ p_direction = self.outs_dict["f_direction"]
73
+ if isinstance(p_score, torch.Tensor):
74
+ p_score = p_score[0].numpy()
75
+ p_border = p_border[0].numpy()
76
+ p_direction = p_direction[0].numpy()
77
+ p_char = p_char[0].numpy()
78
+ else:
79
+ p_score = p_score[0]
80
+ p_border = p_border[0]
81
+ p_direction = p_direction[0]
82
+ p_char = p_char[0]
83
+ src_h, src_w, ratio_h, ratio_w = self.shape_list[0]
84
+ is_curved = self.valid_set == "totaltext"
85
+ char_seq_idx_set, instance_yxs_list = generate_pivot_list_slow(
86
+ p_score,
87
+ p_char,
88
+ p_direction,
89
+ score_thresh=self.score_thresh,
90
+ is_backbone=True,
91
+ is_curved=is_curved, )
92
+ seq_strs = []
93
+ for char_idx_set in char_seq_idx_set:
94
+ pr_str = "".join([self.Lexicon_Table[pos] for pos in char_idx_set])
95
+ seq_strs.append(pr_str)
96
+ poly_list = []
97
+ keep_str_list = []
98
+ all_point_list = []
99
+ all_point_pair_list = []
100
+ for yx_center_line, keep_str in zip(instance_yxs_list, seq_strs):
101
+ if len(yx_center_line) == 1:
102
+ yx_center_line.append(yx_center_line[-1])
103
+
104
+ offset_expand = 1.0
105
+ if self.valid_set == "totaltext":
106
+ offset_expand = 1.2
107
+
108
+ point_pair_list = []
109
+ for batch_id, y, x in yx_center_line:
110
+ offset = p_border[:, y, x].reshape(2, 2)
111
+ if offset_expand != 1.0:
112
+ offset_length = np.linalg.norm(
113
+ offset, axis=1, keepdims=True)
114
+ expand_length = np.clip(
115
+ offset_length * (offset_expand - 1),
116
+ a_min=0.5,
117
+ a_max=3.0)
118
+ offset_detal = offset / offset_length * expand_length
119
+ offset = offset + offset_detal
120
+ ori_yx = np.array([y, x], dtype=np.float32)
121
+ point_pair = ((ori_yx + offset)[:, ::-1] * 4.0 /
122
+ np.array([ratio_w, ratio_h]).reshape(-1, 2))
123
+ point_pair_list.append(point_pair)
124
+
125
+ all_point_list.append([
126
+ int(round(x * 4.0 / ratio_w)),
127
+ int(round(y * 4.0 / ratio_h))
128
+ ])
129
+ all_point_pair_list.append(point_pair.round().astype(np.int32)
130
+ .tolist())
131
+
132
+ detected_poly, pair_length_info = point_pair2poly(point_pair_list)
133
+ detected_poly = expand_poly_along_width(
134
+ detected_poly, shrink_ratio_of_width=0.2)
135
+ detected_poly[:, 0] = np.clip(
136
+ detected_poly[:, 0], a_min=0, a_max=src_w)
137
+ detected_poly[:, 1] = np.clip(
138
+ detected_poly[:, 1], a_min=0, a_max=src_h)
139
+
140
+ if len(keep_str) < 2:
141
+ continue
142
+
143
+ keep_str_list.append(keep_str)
144
+ detected_poly = np.round(detected_poly).astype("int32")
145
+ if self.valid_set == "partvgg":
146
+ middle_point = len(detected_poly) // 2
147
+ detected_poly = detected_poly[
148
+ [0, middle_point - 1, middle_point, -1], :]
149
+ poly_list.append(detected_poly)
150
+ elif self.valid_set == "totaltext":
151
+ poly_list.append(detected_poly)
152
+ else:
153
+ print("--> Not supported format.")
154
+ exit(-1)
155
+ data = {
156
+ "points": poly_list,
157
+ "texts": keep_str_list,
158
+ }
159
+ return data
@@ -0,0 +1,152 @@
1
+ import numpy as np
2
+ import cv2
3
+ import time
4
+
5
+
6
+ def resize_image(im, max_side_len=512):
7
+ """
8
+ resize image to a size multiple of max_stride which is required by the network
9
+ :param im: the resized image
10
+ :param max_side_len: limit of max image size to avoid out of memory in gpu
11
+ :return: the resized image and the resize ratio
12
+ """
13
+ h, w, _ = im.shape
14
+
15
+ resize_w = w
16
+ resize_h = h
17
+
18
+ if resize_h > resize_w:
19
+ ratio = float(max_side_len) / resize_h
20
+ else:
21
+ ratio = float(max_side_len) / resize_w
22
+
23
+ resize_h = int(resize_h * ratio)
24
+ resize_w = int(resize_w * ratio)
25
+
26
+ max_stride = 128
27
+ resize_h = (resize_h + max_stride - 1) // max_stride * max_stride
28
+ resize_w = (resize_w + max_stride - 1) // max_stride * max_stride
29
+ im = cv2.resize(im, (int(resize_w), int(resize_h)))
30
+ ratio_h = resize_h / float(h)
31
+ ratio_w = resize_w / float(w)
32
+
33
+ return im, (ratio_h, ratio_w)
34
+
35
+
36
+ def resize_image_min(im, max_side_len=512):
37
+ """ """
38
+ h, w, _ = im.shape
39
+
40
+ resize_w = w
41
+ resize_h = h
42
+
43
+ if resize_h < resize_w:
44
+ ratio = float(max_side_len) / resize_h
45
+ else:
46
+ ratio = float(max_side_len) / resize_w
47
+
48
+ resize_h = int(resize_h * ratio)
49
+ resize_w = int(resize_w * ratio)
50
+
51
+ max_stride = 128
52
+ resize_h = (resize_h + max_stride - 1) // max_stride * max_stride
53
+ resize_w = (resize_w + max_stride - 1) // max_stride * max_stride
54
+ im = cv2.resize(im, (int(resize_w), int(resize_h)))
55
+ ratio_h = resize_h / float(h)
56
+ ratio_w = resize_w / float(w)
57
+ return im, (ratio_h, ratio_w)
58
+
59
+
60
+ def resize_image_for_totaltext(im, max_side_len=512):
61
+ """ """
62
+ h, w, _ = im.shape
63
+
64
+ resize_w = w
65
+ resize_h = h
66
+ ratio = 1.25
67
+ if h * ratio > max_side_len:
68
+ ratio = float(max_side_len) / resize_h
69
+
70
+ resize_h = int(resize_h * ratio)
71
+ resize_w = int(resize_w * ratio)
72
+
73
+ max_stride = 128
74
+ resize_h = (resize_h + max_stride - 1) // max_stride * max_stride
75
+ resize_w = (resize_w + max_stride - 1) // max_stride * max_stride
76
+ im = cv2.resize(im, (int(resize_w), int(resize_h)))
77
+ ratio_h = resize_h / float(h)
78
+ ratio_w = resize_w / float(w)
79
+ return im, (ratio_h, ratio_w)
80
+
81
+
82
+ def point_pair2poly(point_pair_list):
83
+ """
84
+ Transfer vertical point_pairs into poly point in clockwise.
85
+ """
86
+ pair_length_list = []
87
+ for point_pair in point_pair_list:
88
+ pair_length = np.linalg.norm(point_pair[0] - point_pair[1])
89
+ pair_length_list.append(pair_length)
90
+ pair_length_list = np.array(pair_length_list)
91
+ pair_info = (
92
+ pair_length_list.max(),
93
+ pair_length_list.min(),
94
+ pair_length_list.mean(), )
95
+
96
+ point_num = len(point_pair_list) * 2
97
+ point_list = [0] * point_num
98
+ for idx, point_pair in enumerate(point_pair_list):
99
+ point_list[idx] = point_pair[0]
100
+ point_list[point_num - 1 - idx] = point_pair[1]
101
+ return np.array(point_list).reshape(-1, 2), pair_info
102
+
103
+
104
+ def shrink_quad_along_width(quad, begin_width_ratio=0.0, end_width_ratio=1.0):
105
+ """
106
+ Generate shrink_quad_along_width.
107
+ """
108
+ ratio_pair = np.array(
109
+ [[begin_width_ratio], [end_width_ratio]], dtype=np.float32)
110
+ p0_1 = quad[0] + (quad[1] - quad[0]) * ratio_pair
111
+ p3_2 = quad[3] + (quad[2] - quad[3]) * ratio_pair
112
+ return np.array([p0_1[0], p0_1[1], p3_2[1], p3_2[0]])
113
+
114
+
115
+ def expand_poly_along_width(poly, shrink_ratio_of_width=0.3):
116
+ """
117
+ expand poly along width.
118
+ """
119
+ point_num = poly.shape[0]
120
+ left_quad = np.array(
121
+ [poly[0], poly[1], poly[-2], poly[-1]], dtype=np.float32)
122
+ left_ratio = (-shrink_ratio_of_width *
123
+ np.linalg.norm(left_quad[0] - left_quad[3]) /
124
+ (np.linalg.norm(left_quad[0] - left_quad[1]) + 1e-6))
125
+ left_quad_expand = shrink_quad_along_width(left_quad, left_ratio, 1.0)
126
+ right_quad = np.array(
127
+ [
128
+ poly[point_num // 2 - 2],
129
+ poly[point_num // 2 - 1],
130
+ poly[point_num // 2],
131
+ poly[point_num // 2 + 1],
132
+ ],
133
+ dtype=np.float32, )
134
+ right_ratio = 1.0 + shrink_ratio_of_width * np.linalg.norm(right_quad[
135
+ 0] - right_quad[3]) / (np.linalg.norm(right_quad[0] - right_quad[1]) +
136
+ 1e-6)
137
+ right_quad_expand = shrink_quad_along_width(right_quad, 0.0, right_ratio)
138
+ poly[0] = left_quad_expand[0]
139
+ poly[-1] = left_quad_expand[-1]
140
+ poly[point_num // 2 - 1] = right_quad_expand[1]
141
+ poly[point_num // 2] = right_quad_expand[2]
142
+ return poly
143
+
144
+
145
+ def norm2(x, axis=None):
146
+ if axis:
147
+ return np.sqrt(np.sum(x**2, axis=axis))
148
+ return np.sqrt(np.sum(x**2))
149
+
150
+
151
+ def cos(p1, p2):
152
+ return (p1 * p2).sum() / (norm2(p1) * norm2(p2))
@@ -0,0 +1,95 @@
1
+ 0
2
+ 1
3
+ 2
4
+ 3
5
+ 4
6
+ 5
7
+ 6
8
+ 7
9
+ 8
10
+ 9
11
+ :
12
+ ;
13
+ <
14
+ =
15
+ >
16
+ ?
17
+ @
18
+ A
19
+ B
20
+ C
21
+ D
22
+ E
23
+ F
24
+ G
25
+ H
26
+ I
27
+ J
28
+ K
29
+ L
30
+ M
31
+ N
32
+ O
33
+ P
34
+ Q
35
+ R
36
+ S
37
+ T
38
+ U
39
+ V
40
+ W
41
+ X
42
+ Y
43
+ Z
44
+ [
45
+ \
46
+ ]
47
+ ^
48
+ _
49
+ `
50
+ a
51
+ b
52
+ c
53
+ d
54
+ e
55
+ f
56
+ g
57
+ h
58
+ i
59
+ j
60
+ k
61
+ l
62
+ m
63
+ n
64
+ o
65
+ p
66
+ q
67
+ r
68
+ s
69
+ t
70
+ u
71
+ v
72
+ w
73
+ x
74
+ y
75
+ z
76
+ {
77
+ |
78
+ }
79
+ ~
80
+ !
81
+ "
82
+ #
83
+ $
84
+ %
85
+ &
86
+ '
87
+ (
88
+ )
89
+ *
90
+ +
91
+ ,
92
+ -
93
+ .
94
+ /
95
+
@@ -0,0 +1,68 @@
1
+ import os
2
+ import argparse
3
+ import json
4
+
5
+
6
+ def gen_rec_label(input_path, out_label):
7
+ with open(out_label, "w") as out_file:
8
+ with open(input_path, "r") as f:
9
+ for line in f.readlines():
10
+ tmp = line.strip("\n").replace(" ", "").split(",")
11
+ img_path, label = tmp[0], tmp[1]
12
+ label = label.replace('"', "")
13
+ out_file.write(img_path + "\t" + label + "\n")
14
+
15
+
16
+ def gen_det_label(root_path, input_dir, out_label):
17
+ with open(out_label, "w") as out_file:
18
+ for label_file in os.listdir(input_dir):
19
+ img_path = os.path.join(root_path, label_file[3:-4] + ".jpg")
20
+ label = []
21
+ with open(
22
+ os.path.join(input_dir, label_file), "r",
23
+ encoding="utf-8-sig") as f:
24
+ for line in f.readlines():
25
+ tmp = line.strip("\n\r").replace("\xef\xbb\xbf",
26
+ "").split(",")
27
+ points = tmp[:8]
28
+ s = []
29
+ for i in range(0, len(points), 2):
30
+ b = points[i:i + 2]
31
+ b = [int(t) for t in b]
32
+ s.append(b)
33
+ result = {"transcription": tmp[8], "points": s}
34
+ label.append(result)
35
+
36
+ out_file.write(img_path + "\t" + json.dumps(
37
+ label, ensure_ascii=False) + "\n")
38
+
39
+
40
+ if __name__ == "__main__":
41
+ parser = argparse.ArgumentParser()
42
+ parser.add_argument(
43
+ "--mode",
44
+ type=str,
45
+ default="rec",
46
+ help="Generate rec_label or det_label, can be set rec or det", )
47
+ parser.add_argument(
48
+ "--root_path",
49
+ type=str,
50
+ default=".",
51
+ help="The root directory of images.Only takes effect when mode=det ", )
52
+ parser.add_argument(
53
+ "--input_path",
54
+ type=str,
55
+ default=".",
56
+ help="Input_label or input path to be converted", )
57
+ parser.add_argument(
58
+ "--output_label",
59
+ type=str,
60
+ default="out_label.txt",
61
+ help="Output file name")
62
+
63
+ args = parser.parse_args()
64
+ if args.mode == "rec":
65
+ print("Generate rec label")
66
+ gen_rec_label(args.input_path, args.output_label)
67
+ elif args.mode == "det":
68
+ gen_det_label(args.root_path, args.input_path, args.output_label)
@@ -0,0 +1,36 @@
1
+ 0
2
+ 1
3
+ 2
4
+ 3
5
+ 4
6
+ 5
7
+ 6
8
+ 7
9
+ 8
10
+ 9
11
+ a
12
+ b
13
+ c
14
+ d
15
+ e
16
+ f
17
+ g
18
+ h
19
+ i
20
+ j
21
+ k
22
+ l
23
+ m
24
+ n
25
+ o
26
+ p
27
+ q
28
+ r
29
+ s
30
+ t
31
+ u
32
+ v
33
+ w
34
+ x
35
+ y
36
+ z
@@ -0,0 +1,56 @@
1
+ import os
2
+ import sys
3
+ import logging
4
+ import functools
5
+ import torch
6
+ import torch.distributed as dist
7
+
8
+ logger_initialized = {}
9
+
10
+
11
+ @functools.lru_cache()
12
+ def get_logger(name="openrec", log_file=None, log_level=logging.DEBUG):
13
+ """Initialize and get a logger by name.
14
+ If the logger has not been initialized, this method will initialize the
15
+ logger by adding one or two handlers, otherwise the initialized logger will
16
+ be directly returned. During initialization, a StreamHandler will always be
17
+ added. If `log_file` is specified a FileHandler will also be added.
18
+ Args:
19
+ name (str): Logger name.
20
+ log_file (str | None): The log filename. If specified, a FileHandler
21
+ will be added to the logger.
22
+ log_level (int): The logger level. Note that only the process of
23
+ rank 0 is affected, and other processes will set the level to
24
+ "Error" thus be silent most of the time.
25
+ Returns:
26
+ logging.Logger: The expected logger.
27
+ """
28
+ logger = logging.getLogger(name)
29
+ if name in logger_initialized:
30
+ return logger
31
+ for logger_name in logger_initialized:
32
+ if name.startswith(logger_name):
33
+ return logger
34
+
35
+ formatter = logging.Formatter(
36
+ "[%(asctime)s] %(name)s %(levelname)s: %(message)s",
37
+ datefmt="%Y/%m/%d %H:%M:%S")
38
+
39
+ stream_handler = logging.StreamHandler(stream=sys.stdout)
40
+ stream_handler.setFormatter(formatter)
41
+ logger.addHandler(stream_handler)
42
+
43
+ rank = int(os.environ["LOCAL_RANK"]) if "LOCAL_RANK" in os.environ else 0
44
+ if log_file is not None and rank == 0:
45
+ log_file_folder = os.path.split(log_file)[0]
46
+ os.makedirs(log_file_folder, exist_ok=True)
47
+ file_handler = logging.FileHandler(log_file, "a")
48
+ file_handler.setFormatter(formatter)
49
+ logger.addHandler(file_handler)
50
+ if rank == 0:
51
+ logger.setLevel(log_level)
52
+ else:
53
+ logger.setLevel(logging.ERROR)
54
+ logger_initialized[name] = True
55
+ logger.propagate = False
56
+ return logger
@@ -0,0 +1,132 @@
1
+ import numpy as np
2
+ from shapely.geometry import Polygon
3
+
4
+
5
+ def points2polygon(points):
6
+ """Convert k points to 1 polygon.
7
+
8
+ Args:
9
+ points (ndarray or list): A ndarray or a list of shape (2k)
10
+ that indicates k points.
11
+
12
+ Returns:
13
+ polygon (Polygon): A polygon object.
14
+ """
15
+ if isinstance(points, list):
16
+ points = np.array(points)
17
+
18
+ assert isinstance(points, np.ndarray)
19
+ assert (points.size % 2 == 0) and (points.size >= 8)
20
+
21
+ point_mat = points.reshape([-1, 2])
22
+ return Polygon(point_mat)
23
+
24
+
25
+ def poly_intersection(poly_det, poly_gt, buffer=0.0001):
26
+ """Calculate the intersection area between two polygon.
27
+
28
+ Args:
29
+ poly_det (Polygon): A polygon predicted by detector.
30
+ poly_gt (Polygon): A gt polygon.
31
+
32
+ Returns:
33
+ intersection_area (float): The intersection area between two polygons.
34
+ """
35
+ assert isinstance(poly_det, Polygon)
36
+ assert isinstance(poly_gt, Polygon)
37
+
38
+ if buffer == 0:
39
+ poly_inter = poly_det & poly_gt
40
+ else:
41
+ poly_inter = poly_det.buffer(buffer) & poly_gt.buffer(buffer)
42
+ return poly_inter.area, poly_inter
43
+
44
+
45
+ def poly_union(poly_det, poly_gt):
46
+ """Calculate the union area between two polygon.
47
+
48
+ Args:
49
+ poly_det (Polygon): A polygon predicted by detector.
50
+ poly_gt (Polygon): A gt polygon.
51
+
52
+ Returns:
53
+ union_area (float): The union area between two polygons.
54
+ """
55
+ assert isinstance(poly_det, Polygon)
56
+ assert isinstance(poly_gt, Polygon)
57
+
58
+ area_det = poly_det.area
59
+ area_gt = poly_gt.area
60
+ area_inters, _ = poly_intersection(poly_det, poly_gt)
61
+ return area_det + area_gt - area_inters
62
+
63
+
64
+ def valid_boundary(x, with_score=True):
65
+ num = len(x)
66
+ if num < 8:
67
+ return False
68
+ if num % 2 == 0 and (not with_score):
69
+ return True
70
+ if num % 2 == 1 and with_score:
71
+ return True
72
+
73
+ return False
74
+
75
+
76
+ def boundary_iou(src, target):
77
+ """Calculate the IOU between two boundaries.
78
+
79
+ Args:
80
+ src (list): Source boundary.
81
+ target (list): Target boundary.
82
+
83
+ Returns:
84
+ iou (float): The iou between two boundaries.
85
+ """
86
+ assert valid_boundary(src, False)
87
+ assert valid_boundary(target, False)
88
+ src_poly = points2polygon(src)
89
+ target_poly = points2polygon(target)
90
+
91
+ return poly_iou(src_poly, target_poly)
92
+
93
+
94
+ def poly_iou(poly_det, poly_gt):
95
+ """Calculate the IOU between two polygons.
96
+
97
+ Args:
98
+ poly_det (Polygon): A polygon predicted by detector.
99
+ poly_gt (Polygon): A gt polygon.
100
+
101
+ Returns:
102
+ iou (float): The IOU between two polygons.
103
+ """
104
+ assert isinstance(poly_det, Polygon)
105
+ assert isinstance(poly_gt, Polygon)
106
+ area_inters, _ = poly_intersection(poly_det, poly_gt)
107
+ area_union = poly_union(poly_det, poly_gt)
108
+ if area_union == 0:
109
+ return 0.0
110
+ return area_inters / area_union
111
+
112
+
113
+ def poly_nms(polygons, threshold):
114
+ assert isinstance(polygons, list)
115
+
116
+ polygons = np.array(sorted(polygons, key=lambda x: x[-1]))
117
+
118
+ keep_poly = []
119
+ index = [i for i in range(polygons.shape[0])]
120
+
121
+ while len(index) > 0:
122
+ keep_poly.append(polygons[index[-1]].tolist())
123
+ A = polygons[index[-1]][:-1]
124
+ index = np.delete(index, -1)
125
+ iou_list = np.zeros((len(index), ))
126
+ for i in range(len(index)):
127
+ B = polygons[index[i]][:-1]
128
+ iou_list[i] = boundary_iou(A, B)
129
+ remove_index = np.where(iou_list > threshold)
130
+ index = np.delete(index, remove_index)
131
+
132
+ return keep_poly