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,582 @@
1
+ import cv2
2
+ import math
3
+
4
+ import numpy as np
5
+ from itertools import groupby
6
+ from skimage.morphology._skeletonize import thin
7
+
8
+
9
+ def get_dict(character_dict_path):
10
+ character_str = ""
11
+ with open(character_dict_path, "rb") as fin:
12
+ lines = fin.readlines()
13
+ for line in lines:
14
+ line = line.decode("utf-8").strip("\n").strip("\r\n")
15
+ character_str += line
16
+ dict_character = list(character_str)
17
+ return dict_character
18
+
19
+
20
+ def point_pair2poly(point_pair_list):
21
+ """
22
+ Transfer vertical point_pairs into poly point in clockwise.
23
+ """
24
+ pair_length_list = []
25
+ for point_pair in point_pair_list:
26
+ pair_length = np.linalg.norm(point_pair[0] - point_pair[1])
27
+ pair_length_list.append(pair_length)
28
+ pair_length_list = np.array(pair_length_list)
29
+ pair_info = (
30
+ pair_length_list.max(),
31
+ pair_length_list.min(),
32
+ pair_length_list.mean(), )
33
+
34
+ point_num = len(point_pair_list) * 2
35
+ point_list = [0] * point_num
36
+ for idx, point_pair in enumerate(point_pair_list):
37
+ point_list[idx] = point_pair[0]
38
+ point_list[point_num - 1 - idx] = point_pair[1]
39
+ return np.array(point_list).reshape(-1, 2), pair_info
40
+
41
+
42
+ def shrink_quad_along_width(quad, begin_width_ratio=0.0, end_width_ratio=1.0):
43
+ """
44
+ Generate shrink_quad_along_width.
45
+ """
46
+ ratio_pair = np.array(
47
+ [[begin_width_ratio], [end_width_ratio]], dtype=np.float32)
48
+ p0_1 = quad[0] + (quad[1] - quad[0]) * ratio_pair
49
+ p3_2 = quad[3] + (quad[2] - quad[3]) * ratio_pair
50
+ return np.array([p0_1[0], p0_1[1], p3_2[1], p3_2[0]])
51
+
52
+
53
+ def expand_poly_along_width(poly, shrink_ratio_of_width=0.3):
54
+ """
55
+ expand poly along width.
56
+ """
57
+ point_num = poly.shape[0]
58
+ left_quad = np.array(
59
+ [poly[0], poly[1], poly[-2], poly[-1]], dtype=np.float32)
60
+ left_ratio = (-shrink_ratio_of_width *
61
+ np.linalg.norm(left_quad[0] - left_quad[3]) /
62
+ (np.linalg.norm(left_quad[0] - left_quad[1]) + 1e-6))
63
+ left_quad_expand = shrink_quad_along_width(left_quad, left_ratio, 1.0)
64
+ right_quad = np.array(
65
+ [
66
+ poly[point_num // 2 - 2],
67
+ poly[point_num // 2 - 1],
68
+ poly[point_num // 2],
69
+ poly[point_num // 2 + 1],
70
+ ],
71
+ dtype=np.float32, )
72
+ right_ratio = 1.0 + shrink_ratio_of_width * np.linalg.norm(right_quad[
73
+ 0] - right_quad[3]) / (np.linalg.norm(right_quad[0] - right_quad[1]) +
74
+ 1e-6)
75
+ right_quad_expand = shrink_quad_along_width(right_quad, 0.0, right_ratio)
76
+ poly[0] = left_quad_expand[0]
77
+ poly[-1] = left_quad_expand[-1]
78
+ poly[point_num // 2 - 1] = right_quad_expand[1]
79
+ poly[point_num // 2] = right_quad_expand[2]
80
+ return poly
81
+
82
+
83
+ def softmax(logits):
84
+ """
85
+ logits: N x d
86
+ """
87
+ max_value = np.max(logits, axis=1, keepdims=True)
88
+ exp = np.exp(logits - max_value)
89
+ exp_sum = np.sum(exp, axis=1, keepdims=True)
90
+ dist = exp / exp_sum
91
+ return dist
92
+
93
+
94
+ def get_keep_pos_idxs(labels, remove_blank=None):
95
+ """
96
+ Remove duplicate and get pos idxs of keep items.
97
+ The value of keep_blank should be [None, 95].
98
+ """
99
+ duplicate_len_list = []
100
+ keep_pos_idx_list = []
101
+ keep_char_idx_list = []
102
+ for k, v_ in groupby(labels):
103
+ current_len = len(list(v_))
104
+ if k != remove_blank:
105
+ current_idx = int(sum(duplicate_len_list) + current_len // 2)
106
+ keep_pos_idx_list.append(current_idx)
107
+ keep_char_idx_list.append(k)
108
+ duplicate_len_list.append(current_len)
109
+ return keep_char_idx_list, keep_pos_idx_list
110
+
111
+
112
+ def remove_blank(labels, blank=0):
113
+ new_labels = [x for x in labels if x != blank]
114
+ return new_labels
115
+
116
+
117
+ def insert_blank(labels, blank=0):
118
+ new_labels = [blank]
119
+ for l in labels:
120
+ new_labels += [l, blank]
121
+ return new_labels
122
+
123
+
124
+ def ctc_greedy_decoder(probs_seq, blank=95, keep_blank_in_idxs=True):
125
+ """
126
+ CTC greedy (best path) decoder.
127
+ """
128
+ raw_str = np.argmax(np.array(probs_seq), axis=1)
129
+ remove_blank_in_pos = None if keep_blank_in_idxs else blank
130
+ dedup_str, keep_idx_list = get_keep_pos_idxs(
131
+ raw_str, remove_blank=remove_blank_in_pos)
132
+ dst_str = remove_blank(dedup_str, blank=blank)
133
+ return dst_str, keep_idx_list
134
+
135
+
136
+ def instance_ctc_greedy_decoder(gather_info,
137
+ logits_map,
138
+ keep_blank_in_idxs=True):
139
+ """
140
+ gather_info: [[x, y], [x, y] ...]
141
+ logits_map: H x W X (n_chars + 1)
142
+ """
143
+ _, _, C = logits_map.shape
144
+ ys, xs = zip(*gather_info)
145
+ logits_seq = logits_map[list(ys), list(xs)] # n x 96
146
+ probs_seq = softmax(logits_seq)
147
+ dst_str, keep_idx_list = ctc_greedy_decoder(
148
+ probs_seq, blank=C - 1, keep_blank_in_idxs=keep_blank_in_idxs)
149
+ keep_gather_list = [gather_info[idx] for idx in keep_idx_list]
150
+ return dst_str, keep_gather_list
151
+
152
+
153
+ def ctc_decoder_for_image(gather_info_list, logits_map,
154
+ keep_blank_in_idxs=True):
155
+ """
156
+ CTC decoder using multiple processes.
157
+ """
158
+ decoder_results = []
159
+ for gather_info in gather_info_list:
160
+ res = instance_ctc_greedy_decoder(
161
+ gather_info, logits_map, keep_blank_in_idxs=keep_blank_in_idxs)
162
+ decoder_results.append(res)
163
+ return decoder_results
164
+
165
+
166
+ def sort_with_direction(pos_list, f_direction):
167
+ """
168
+ f_direction: h x w x 2
169
+ pos_list: [[y, x], [y, x], [y, x] ...]
170
+ """
171
+
172
+ def sort_part_with_direction(pos_list, point_direction):
173
+ pos_list = np.array(pos_list).reshape(-1, 2)
174
+ point_direction = np.array(point_direction).reshape(-1, 2)
175
+ average_direction = np.mean(point_direction, axis=0, keepdims=True)
176
+ pos_proj_leng = np.sum(pos_list * average_direction, axis=1)
177
+ sorted_list = pos_list[np.argsort(pos_proj_leng)].tolist()
178
+ sorted_direction = point_direction[np.argsort(pos_proj_leng)].tolist()
179
+ return sorted_list, sorted_direction
180
+
181
+ pos_list = np.array(pos_list).reshape(-1, 2)
182
+ point_direction = f_direction[pos_list[:, 0], pos_list[:, 1]] # x, y
183
+ point_direction = point_direction[:, ::-1] # x, y -> y, x
184
+ sorted_point, sorted_direction = sort_part_with_direction(pos_list,
185
+ point_direction)
186
+
187
+ point_num = len(sorted_point)
188
+ if point_num >= 16:
189
+ middle_num = point_num // 2
190
+ first_part_point = sorted_point[:middle_num]
191
+ first_point_direction = sorted_direction[:middle_num]
192
+ sorted_fist_part_point, sorted_fist_part_direction = sort_part_with_direction(
193
+ first_part_point, first_point_direction)
194
+
195
+ last_part_point = sorted_point[middle_num:]
196
+ last_point_direction = sorted_direction[middle_num:]
197
+ sorted_last_part_point, sorted_last_part_direction = sort_part_with_direction(
198
+ last_part_point, last_point_direction)
199
+ sorted_point = sorted_fist_part_point + sorted_last_part_point
200
+ sorted_direction = sorted_fist_part_direction + sorted_last_part_direction
201
+
202
+ return sorted_point, np.array(sorted_direction)
203
+
204
+
205
+ def add_id(pos_list, image_id=0):
206
+ """
207
+ Add id for gather feature, for inference.
208
+ """
209
+ new_list = []
210
+ for item in pos_list:
211
+ new_list.append((image_id, item[0], item[1]))
212
+ return new_list
213
+
214
+
215
+ def sort_and_expand_with_direction(pos_list, f_direction):
216
+ """
217
+ f_direction: h x w x 2
218
+ pos_list: [[y, x], [y, x], [y, x] ...]
219
+ """
220
+ h, w, _ = f_direction.shape
221
+ sorted_list, point_direction = sort_with_direction(pos_list, f_direction)
222
+
223
+ # expand along
224
+ point_num = len(sorted_list)
225
+ sub_direction_len = max(point_num // 3, 2)
226
+ left_direction = point_direction[:sub_direction_len, :]
227
+ right_dirction = point_direction[point_num - sub_direction_len:, :]
228
+
229
+ left_average_direction = -np.mean(left_direction, axis=0, keepdims=True)
230
+ left_average_len = np.linalg.norm(left_average_direction)
231
+ left_start = np.array(sorted_list[0])
232
+ left_step = left_average_direction / (left_average_len + 1e-6)
233
+
234
+ right_average_direction = np.mean(right_dirction, axis=0, keepdims=True)
235
+ right_average_len = np.linalg.norm(right_average_direction)
236
+ right_step = right_average_direction / (right_average_len + 1e-6)
237
+ right_start = np.array(sorted_list[-1])
238
+
239
+ append_num = max(
240
+ int((left_average_len + right_average_len) / 2.0 * 0.15), 1)
241
+ left_list = []
242
+ right_list = []
243
+ for i in range(append_num):
244
+ ly, lx = (np.round(left_start + left_step * (i + 1)).flatten()
245
+ .astype("int32").tolist())
246
+ if ly < h and lx < w and (ly, lx) not in left_list:
247
+ left_list.append((ly, lx))
248
+ ry, rx = (np.round(right_start + right_step * (i + 1)).flatten()
249
+ .astype("int32").tolist())
250
+ if ry < h and rx < w and (ry, rx) not in right_list:
251
+ right_list.append((ry, rx))
252
+
253
+ all_list = left_list[::-1] + sorted_list + right_list
254
+ return all_list
255
+
256
+
257
+ def sort_and_expand_with_direction_v2(pos_list, f_direction, binary_tcl_map):
258
+ """
259
+ f_direction: h x w x 2
260
+ pos_list: [[y, x], [y, x], [y, x] ...]
261
+ binary_tcl_map: h x w
262
+ """
263
+ h, w, _ = f_direction.shape
264
+ sorted_list, point_direction = sort_with_direction(pos_list, f_direction)
265
+
266
+ # expand along
267
+ point_num = len(sorted_list)
268
+ sub_direction_len = max(point_num // 3, 2)
269
+ left_direction = point_direction[:sub_direction_len, :]
270
+ right_dirction = point_direction[point_num - sub_direction_len:, :]
271
+
272
+ left_average_direction = -np.mean(left_direction, axis=0, keepdims=True)
273
+ left_average_len = np.linalg.norm(left_average_direction)
274
+ left_start = np.array(sorted_list[0])
275
+ left_step = left_average_direction / (left_average_len + 1e-6)
276
+
277
+ right_average_direction = np.mean(right_dirction, axis=0, keepdims=True)
278
+ right_average_len = np.linalg.norm(right_average_direction)
279
+ right_step = right_average_direction / (right_average_len + 1e-6)
280
+ right_start = np.array(sorted_list[-1])
281
+
282
+ append_num = max(
283
+ int((left_average_len + right_average_len) / 2.0 * 0.15), 1)
284
+ max_append_num = 2 * append_num
285
+
286
+ left_list = []
287
+ right_list = []
288
+ for i in range(max_append_num):
289
+ ly, lx = (np.round(left_start + left_step * (i + 1)).flatten()
290
+ .astype("int32").tolist())
291
+ if ly < h and lx < w and (ly, lx) not in left_list:
292
+ if binary_tcl_map[ly, lx] > 0.5:
293
+ left_list.append((ly, lx))
294
+ else:
295
+ break
296
+
297
+ for i in range(max_append_num):
298
+ ry, rx = (np.round(right_start + right_step * (i + 1)).flatten()
299
+ .astype("int32").tolist())
300
+ if ry < h and rx < w and (ry, rx) not in right_list:
301
+ if binary_tcl_map[ry, rx] > 0.5:
302
+ right_list.append((ry, rx))
303
+ else:
304
+ break
305
+
306
+ all_list = left_list[::-1] + sorted_list + right_list
307
+ return all_list
308
+
309
+
310
+ def generate_pivot_list_curved(
311
+ p_score,
312
+ p_char_maps,
313
+ f_direction,
314
+ score_thresh=0.5,
315
+ is_expand=True,
316
+ is_backbone=False,
317
+ image_id=0, ):
318
+ """
319
+ return center point and end point of TCL instance; filter with the char maps;
320
+ """
321
+ p_score = p_score[0]
322
+ f_direction = f_direction.transpose(1, 2, 0)
323
+ p_tcl_map = (p_score > score_thresh) * 1.0
324
+ skeleton_map = thin(p_tcl_map)
325
+ instance_count, instance_label_map = cv2.connectedComponents(
326
+ skeleton_map.astype(np.uint8), connectivity=8)
327
+
328
+ # get TCL Instance
329
+ all_pos_yxs = []
330
+ center_pos_yxs = []
331
+ end_points_yxs = []
332
+ instance_center_pos_yxs = []
333
+ pred_strs = []
334
+ if instance_count > 0:
335
+ for instance_id in range(1, instance_count):
336
+ pos_list = []
337
+ ys, xs = np.where(instance_label_map == instance_id)
338
+ pos_list = list(zip(ys, xs))
339
+
340
+ ### FIX-ME, eliminate outlier
341
+ if len(pos_list) < 3:
342
+ continue
343
+
344
+ if is_expand:
345
+ pos_list_sorted = sort_and_expand_with_direction_v2(
346
+ pos_list, f_direction, p_tcl_map)
347
+ else:
348
+ pos_list_sorted, _ = sort_with_direction(pos_list, f_direction)
349
+ all_pos_yxs.append(pos_list_sorted)
350
+
351
+ # use decoder to filter backgroud points.
352
+ p_char_maps = p_char_maps.transpose([1, 2, 0])
353
+ decode_res = ctc_decoder_for_image(
354
+ all_pos_yxs, logits_map=p_char_maps, keep_blank_in_idxs=True)
355
+ for decoded_str, keep_yxs_list in decode_res:
356
+ if is_backbone:
357
+ keep_yxs_list_with_id = add_id(keep_yxs_list, image_id=image_id)
358
+ instance_center_pos_yxs.append(keep_yxs_list_with_id)
359
+ pred_strs.append(decoded_str)
360
+ else:
361
+ end_points_yxs.extend((keep_yxs_list[0], keep_yxs_list[-1]))
362
+ center_pos_yxs.extend(keep_yxs_list)
363
+
364
+ if is_backbone:
365
+ return pred_strs, instance_center_pos_yxs
366
+ else:
367
+ return center_pos_yxs, end_points_yxs
368
+
369
+
370
+ def generate_pivot_list_horizontal(p_score,
371
+ p_char_maps,
372
+ f_direction,
373
+ score_thresh=0.5,
374
+ is_backbone=False,
375
+ image_id=0):
376
+ """
377
+ return center point and end point of TCL instance; filter with the char maps;
378
+ """
379
+ p_score = p_score[0]
380
+ f_direction = f_direction.transpose(1, 2, 0)
381
+ p_tcl_map_bi = (p_score > score_thresh) * 1.0
382
+ instance_count, instance_label_map = cv2.connectedComponents(
383
+ p_tcl_map_bi.astype(np.uint8), connectivity=8)
384
+
385
+ # get TCL Instance
386
+ all_pos_yxs = []
387
+ center_pos_yxs = []
388
+ end_points_yxs = []
389
+ instance_center_pos_yxs = []
390
+
391
+ if instance_count > 0:
392
+ for instance_id in range(1, instance_count):
393
+ pos_list = []
394
+ ys, xs = np.where(instance_label_map == instance_id)
395
+ pos_list = list(zip(ys, xs))
396
+
397
+ ### FIX-ME, eliminate outlier
398
+ if len(pos_list) < 5:
399
+ continue
400
+
401
+ # add rule here
402
+ main_direction = extract_main_direction(pos_list,
403
+ f_direction) # y x
404
+ reference_directin = np.array([0, 1]).reshape([-1, 2]) # y x
405
+ is_h_angle = abs(np.sum(
406
+ main_direction * reference_directin)) < math.cos(math.pi / 180 *
407
+ 70)
408
+
409
+ point_yxs = np.array(pos_list)
410
+ max_y, max_x = np.max(point_yxs, axis=0)
411
+ min_y, min_x = np.min(point_yxs, axis=0)
412
+ is_h_len = (max_y - min_y) < 1.5 * (max_x - min_x)
413
+
414
+ pos_list_final = []
415
+ if is_h_len:
416
+ xs = np.unique(xs)
417
+ for x in xs:
418
+ ys = instance_label_map[:, x].copy().reshape((-1, ))
419
+ y = int(np.where(ys == instance_id)[0].mean())
420
+ pos_list_final.append((y, x))
421
+ else:
422
+ ys = np.unique(ys)
423
+ for y in ys:
424
+ xs = instance_label_map[y, :].copy().reshape((-1, ))
425
+ x = int(np.where(xs == instance_id)[0].mean())
426
+ pos_list_final.append((y, x))
427
+
428
+ pos_list_sorted, _ = sort_with_direction(pos_list_final,
429
+ f_direction)
430
+ all_pos_yxs.append(pos_list_sorted)
431
+
432
+ # use decoder to filter backgroud points.
433
+ p_char_maps = p_char_maps.transpose([1, 2, 0])
434
+ decode_res = ctc_decoder_for_image(
435
+ all_pos_yxs, logits_map=p_char_maps, keep_blank_in_idxs=True)
436
+ for decoded_str, keep_yxs_list in decode_res:
437
+ if is_backbone:
438
+ keep_yxs_list_with_id = add_id(keep_yxs_list, image_id=image_id)
439
+ instance_center_pos_yxs.append(keep_yxs_list_with_id)
440
+ else:
441
+ end_points_yxs.extend((keep_yxs_list[0], keep_yxs_list[-1]))
442
+ center_pos_yxs.extend(keep_yxs_list)
443
+
444
+ if is_backbone:
445
+ return instance_center_pos_yxs
446
+ else:
447
+ return center_pos_yxs, end_points_yxs
448
+
449
+
450
+ def generate_pivot_list_slow(
451
+ p_score,
452
+ p_char_maps,
453
+ f_direction,
454
+ score_thresh=0.5,
455
+ is_backbone=False,
456
+ is_curved=True,
457
+ image_id=0, ):
458
+ """
459
+ Warp all the function together.
460
+ """
461
+ if is_curved:
462
+ return generate_pivot_list_curved(
463
+ p_score,
464
+ p_char_maps,
465
+ f_direction,
466
+ score_thresh=score_thresh,
467
+ is_expand=True,
468
+ is_backbone=is_backbone,
469
+ image_id=image_id, )
470
+ else:
471
+ return generate_pivot_list_horizontal(
472
+ p_score,
473
+ p_char_maps,
474
+ f_direction,
475
+ score_thresh=score_thresh,
476
+ is_backbone=is_backbone,
477
+ image_id=image_id, )
478
+
479
+
480
+ # for refine module
481
+ def extract_main_direction(pos_list, f_direction):
482
+ """
483
+ f_direction: h x w x 2
484
+ pos_list: [[y, x], [y, x], [y, x] ...]
485
+ """
486
+ pos_list = np.array(pos_list)
487
+ point_direction = f_direction[pos_list[:, 0], pos_list[:, 1]]
488
+ point_direction = point_direction[:, ::-1] # x, y -> y, x
489
+ average_direction = np.mean(point_direction, axis=0, keepdims=True)
490
+ average_direction = average_direction / (
491
+ np.linalg.norm(average_direction) + 1e-6)
492
+ return average_direction
493
+
494
+
495
+ def sort_by_direction_with_image_id_deprecated(pos_list, f_direction):
496
+ """
497
+ f_direction: h x w x 2
498
+ pos_list: [[id, y, x], [id, y, x], [id, y, x] ...]
499
+ """
500
+ pos_list_full = np.array(pos_list).reshape(-1, 3)
501
+ pos_list = pos_list_full[:, 1:]
502
+ point_direction = f_direction[pos_list[:, 0], pos_list[:, 1]] # x, y
503
+ point_direction = point_direction[:, ::-1] # x, y -> y, x
504
+ average_direction = np.mean(point_direction, axis=0, keepdims=True)
505
+ pos_proj_leng = np.sum(pos_list * average_direction, axis=1)
506
+ sorted_list = pos_list_full[np.argsort(pos_proj_leng)].tolist()
507
+ return sorted_list
508
+
509
+
510
+ def sort_by_direction_with_image_id(pos_list, f_direction):
511
+ """
512
+ f_direction: h x w x 2
513
+ pos_list: [[y, x], [y, x], [y, x] ...]
514
+ """
515
+
516
+ def sort_part_with_direction(pos_list_full, point_direction):
517
+ pos_list_full = np.array(pos_list_full).reshape(-1, 3)
518
+ pos_list = pos_list_full[:, 1:]
519
+ point_direction = np.array(point_direction).reshape(-1, 2)
520
+ average_direction = np.mean(point_direction, axis=0, keepdims=True)
521
+ pos_proj_leng = np.sum(pos_list * average_direction, axis=1)
522
+ sorted_list = pos_list_full[np.argsort(pos_proj_leng)].tolist()
523
+ sorted_direction = point_direction[np.argsort(pos_proj_leng)].tolist()
524
+ return sorted_list, sorted_direction
525
+
526
+ pos_list = np.array(pos_list).reshape(-1, 3)
527
+ point_direction = f_direction[pos_list[:, 1], pos_list[:, 2]] # x, y
528
+ point_direction = point_direction[:, ::-1] # x, y -> y, x
529
+ sorted_point, sorted_direction = sort_part_with_direction(pos_list,
530
+ point_direction)
531
+
532
+ point_num = len(sorted_point)
533
+ if point_num >= 16:
534
+ middle_num = point_num // 2
535
+ first_part_point = sorted_point[:middle_num]
536
+ first_point_direction = sorted_direction[:middle_num]
537
+ sorted_fist_part_point, sorted_fist_part_direction = sort_part_with_direction(
538
+ first_part_point, first_point_direction)
539
+
540
+ last_part_point = sorted_point[middle_num:]
541
+ last_point_direction = sorted_direction[middle_num:]
542
+ sorted_last_part_point, sorted_last_part_direction = sort_part_with_direction(
543
+ last_part_point, last_point_direction)
544
+ sorted_point = sorted_fist_part_point + sorted_last_part_point
545
+ sorted_direction = sorted_fist_part_direction + sorted_last_part_direction
546
+
547
+ return sorted_point
548
+
549
+
550
+ def generate_pivot_list_tt_inference(
551
+ p_score,
552
+ p_char_maps,
553
+ f_direction,
554
+ score_thresh=0.5,
555
+ is_backbone=False,
556
+ is_curved=True,
557
+ image_id=0, ):
558
+ """
559
+ return center point and end point of TCL instance; filter with the char maps;
560
+ """
561
+ p_score = p_score[0]
562
+ f_direction = f_direction.transpose(1, 2, 0)
563
+ p_tcl_map = (p_score > score_thresh) * 1.0
564
+ skeleton_map = thin(p_tcl_map)
565
+ instance_count, instance_label_map = cv2.connectedComponents(
566
+ skeleton_map.astype(np.uint8), connectivity=8)
567
+
568
+ # get TCL Instance
569
+ all_pos_yxs = []
570
+ if instance_count > 0:
571
+ for instance_id in range(1, instance_count):
572
+ pos_list = []
573
+ ys, xs = np.where(instance_label_map == instance_id)
574
+ pos_list = list(zip(ys, xs))
575
+ ### FIX-ME, eliminate outlier
576
+ if len(pos_list) < 3:
577
+ continue
578
+ pos_list_sorted = sort_and_expand_with_direction_v2(
579
+ pos_list, f_direction, p_tcl_map)
580
+ pos_list_sorted_with_id = add_id(pos_list_sorted, image_id=image_id)
581
+ all_pos_yxs.append(pos_list_sorted_with_id)
582
+ return all_pos_yxs