Showing preview only (1,205K chars total). Download the full file or copy to clipboard to get everything.
Repository: GXYM/TextBPN-Plus-Plus
Branch: main
Commit: 87617c7529e4
Files: 180
Total size: 1.1 MB
Directory structure:
gitextract_9_0bdakf/
├── .gitignore
├── README.md
├── cache/
│ └── README.md
├── cfglib/
│ ├── config.py
│ └── option.py
├── data/
│ ├── ArT/
│ │ └── README.md
│ ├── CTW-1500/
│ │ └── README.md
│ ├── Icdar2015/
│ │ └── README.md
│ ├── LSVT/
│ │ └── README.md
│ ├── MLT-2019/
│ │ └── README.md
│ ├── MLT2017/
│ │ └── README.md
│ ├── README.md
│ ├── SynthText/
│ │ ├── README.md
│ │ └── findPath.sh
│ ├── TD500/
│ │ └── README.md
│ ├── Total-Text/
│ │ └── README.md
│ ├── ctw1500/
│ │ └── README.md
│ └── total-text-mat/
│ └── README.md
├── dataset/
│ ├── CTW1500_Text_New.py
│ ├── Icdar15_Text.py
│ ├── Icdar17_Text.py
│ ├── Icdar19ArT_Json.py
│ ├── Icdar19ArT_Text.py
│ ├── Icdar19LSVT_Json.py
│ ├── Icdar19_Text.py
│ ├── README.md
│ ├── TD500/
│ │ ├── 075eval.sh
│ │ ├── Evaluation_Protocol/
│ │ │ ├── readme.txt
│ │ │ ├── rrc_evaluation_funcs.py
│ │ │ ├── script.py
│ │ │ └── script075.py
│ │ ├── batch_eval.sh
│ │ ├── eval.sh
│ │ └── submit/
│ │ └── res_img_1.txt
│ ├── TD500_Text.py
│ ├── Total_Text.py
│ ├── Total_Text_New.py
│ ├── __init__.py
│ ├── ctw1500/
│ │ ├── Evaluation_Protocol/
│ │ │ ├── ctw1500_eval.py
│ │ │ └── voc_eval_polygon.py
│ │ ├── Evaluation_sort/
│ │ │ └── detections_text0.5.txt
│ │ ├── Readme.md
│ │ └── annots.pkl
│ ├── ctw1500_text.py
│ ├── data_util.py
│ ├── dataload.py
│ ├── deploy.py
│ ├── icdar15/
│ │ ├── 075eval.sh
│ │ ├── Evaluation_Protocol/
│ │ │ ├── readme.txt
│ │ │ ├── rrc_evaluation_funcs.py
│ │ │ ├── script.py
│ │ │ └── script075.py
│ │ ├── batch_eval.sh
│ │ ├── eval.sh
│ │ └── submit/
│ │ └── res_img_1.txt
│ ├── synth-text/
│ │ ├── README.md
│ │ └── make_list.py
│ ├── synth_text.py
│ └── total_text/
│ ├── .gitignore
│ ├── Evaluation_Protocol/
│ │ ├── ComputePrecisionRecall.m
│ │ ├── Eval.m
│ │ ├── Examples/
│ │ │ ├── Groundtruth/
│ │ │ │ ├── poly_gt_img1.mat
│ │ │ │ ├── poly_gt_img2.mat
│ │ │ │ ├── poly_gt_img3.mat
│ │ │ │ ├── poly_gt_img4.mat
│ │ │ │ └── poly_gt_img5.mat
│ │ │ ├── Prediction/
│ │ │ │ ├── img1.mat
│ │ │ │ ├── img2.mat
│ │ │ │ ├── img3.mat
│ │ │ │ ├── img4.mat
│ │ │ │ └── img5.mat
│ │ │ └── Result.txt
│ │ ├── Python_scripts/
│ │ │ ├── Deteval.py
│ │ │ ├── Pascal_VOC.py
│ │ │ ├── __init__.py
│ │ │ ├── polygon_fast.py
│ │ │ └── polygon_wrapper.py
│ │ ├── README.md
│ │ └── __init__.py
│ ├── README.md
│ ├── download.sh
│ └── gdrivedl.sh
├── demo.py
├── demo.sh
├── eval.sh
├── eval_textBPN.py
├── eval_textBPN_speed.py
├── model/
│ └── README.md
├── network/
│ ├── Reg_loss.py
│ ├── Seg_loss.py
│ ├── __init__.py
│ ├── backbone/
│ │ ├── __init__.py
│ │ ├── assets/
│ │ │ └── dcn/
│ │ │ ├── Makefile
│ │ │ ├── Makefile.sh
│ │ │ ├── __init__.py
│ │ │ ├── functions/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deform_conv.py
│ │ │ │ └── deform_pool.py
│ │ │ ├── modules/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deform_conv.py
│ │ │ │ └── deform_pool.py
│ │ │ ├── setup.py
│ │ │ └── src/
│ │ │ ├── deform_conv_cuda.cpp
│ │ │ ├── deform_conv_cuda_kernel.cu
│ │ │ ├── deform_pool_cuda.cpp
│ │ │ └── deform_pool_cuda_kernel.cu
│ │ ├── resnet.py
│ │ └── vgg.py
│ ├── layers/
│ │ ├── Adaptive_Deformation.py
│ │ ├── CircConv.py
│ │ ├── GCN.py
│ │ ├── GraphConv.py
│ │ ├── RNN.py
│ │ ├── Transformer.py
│ │ ├── Transformer_old.py
│ │ ├── __init__.py
│ │ ├── gcn_utils.py
│ │ ├── model_block.py
│ │ ├── position_encoding.py
│ │ ├── resnet.py
│ │ ├── resnet_dcn.py
│ │ └── vgg.py
│ ├── loss.py
│ ├── loss_org.py
│ └── textnet.py
├── output/
│ ├── Analysis/
│ │ ├── ctw1500_eval.txt
│ │ └── totalText_eval.txt
│ └── README.md
├── requirements.txt
├── scripts-eval/
│ ├── Eval_ArT.sh
│ ├── Eval_CTW1500.sh
│ ├── Eval_MLT2017.sh
│ ├── Eval_TD500.sh
│ └── Eval_Totaltext.sh
├── scripts-train/
│ ├── train_ALL_res50_dcn_1s.sh
│ ├── train_Art_res50_1s_fine_mlt.sh
│ ├── train_Art_res50_dcn_1s_fine_mlt.sh
│ ├── train_CTW1500_res18_4s_fine_mlt.sh
│ ├── train_CTW1500_res50_1s.sh
│ ├── train_CTW1500_res50_1s_fine_mlt.sh
│ ├── train_CTW1500_res50_dcn_1s_fine_mlt.sh
│ ├── train_MLT2017_res18_4s.sh
│ ├── train_MLT2017_res50_1s.sh
│ ├── train_MLT2017_res50_dcn_1s.sh
│ ├── train_MLT2019_res50_1s.sh
│ ├── train_SynText_res18_4s.sh
│ ├── train_SynText_res50_1s.sh
│ ├── train_SynText_res50_dcn_1s.sh
│ ├── train_TD500_res18_4s_fine_mlt.sh
│ ├── train_TD500_res50_1s.sh
│ ├── train_TD500_res50_1s_fine_mlt.sh
│ ├── train_TD500_res50_dcn_1s_fine_mlt.sh
│ ├── train_Totaltext_res18_1s.sh
│ ├── train_Totaltext_res18_2s.sh
│ ├── train_Totaltext_res18_4s.sh
│ ├── train_Totaltext_res18_4s_fine_mlt.sh
│ ├── train_Totaltext_res50_1s.sh
│ ├── train_Totaltext_res50_1s_fine_mlt.sh
│ ├── train_Totaltext_res50_4s.sh
│ └── train_Totaltext_res50_dcn_1s_fine_mlt.sh
├── train_textBPN.py
├── train_textBPN_DDP.py
├── util/
│ ├── __init__.py
│ ├── augmentation.py
│ ├── canvas.py
│ ├── detection.py
│ ├── eval.py
│ ├── graph.py
│ ├── io.py
│ ├── logging.py
│ ├── meters.py
│ ├── misc.py
│ ├── pbox.py
│ ├── serialization.py
│ ├── shedule.py
│ ├── strs.py
│ ├── summary.py
│ ├── vis_flux.py
│ └── visualize.py
└── vis/
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.idea
**/__pycache__
*.so
output/TD500/*
vis/TD500_test/
================================================
FILE: README.md
================================================
# TextBPN-Puls-Plus
This is a Pytorch implementation of TextBPN++: [Arbitrary Shape Text Detection via Boundary Transformer](https://arxiv.org/abs/2205.05320); This project is based on [TextBPN](https://github.com/GXYM/TextBPN)

*Please light up the stars, thank you! Your encouragement is the energy for us to constantly update!*
## News
- [x] 2025.06.30 Our model [TextBPN-MLOCR](https://github.com/GXYM/TextBPN-MLOCR) achieved first place on [ArT2019](https://rrc.cvc.uab.es/?ch=14&com=evaluation&task=1)_ and [MLT2019](https://rrc.cvc.uab.es/?ch=15&com=evaluation&task=1)
- [x] 2025.05.16 We are excited to announce the release of our **TextBPN-MLOCR: Advanced Multi-Lingual Scene Text Detection** ([**TextBPN-MLOCR
**](https://github.com/GXYM/TextBPN-MLOCR))! Designed for robust performance in complex, multilingual environments, this model excels at detecting text of various shapes in any scene. Leveraging a powerful architecture based on DCN and ResNet50, it has been trained on 1.5 million synthetic images and over 0.5 million real-world scene samples. Despite its strong detection capabilities, the model remains lightweight and efficient, making it ideal for a wide range of applications.
- [x] 2025.03.13 Added a script for multi-GPU training [train_textBPN_DDP.py](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/train_textBPN_DDP.py)
- [x] 2023.06.14 Our paper of TextBPN++ has been accepted by IEEE Transactions on Multimedia (T-MM 2023), which can be obtained at [IEEE Xplore](https://ieeexplore.ieee.org/document/10153666).
- [x] 2022.11.19 Displayed the visualization results of Reading Order Module.
- [x] 2022.11.18 **Important update! Fixed some bugs in training code.** These bugs make it difficult to reproduce the perfromance in the paper without pre-training. The updated code has more stable training and better performance. Thanks to the developers who made me aware of these bugs, and push us to fix these bugs. The description of the code change and the details of the reproduction are [here](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/output).
- [x] 2022.10.18 The performance of our TextBPN++ on Document OCR have been proved by the paper ["Text Detection Forgot About Document OCR"](https://arxiv.org/pdf/2210.07903.pdf) with University of Oxford, which also reported the compared results for other text detection methods, such as PAN, DBNet, DBNet++, DCLNet, CRAFT etc. The comparison experiments is very detailed and very referential!
- [x] 2022.06.20 Updated the illustration of framework.
- [x] 2022.06.16 Uploaded the missing file because of the naming problem([CTW1500_Text_New](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/dataset/CTW1500_Text_New.py), [Total_Text_New](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/dataset/Total_Text_New.py)), which support the new label formats for Total_Text (mat) and CTW1500 (xml).
- [x] 2022.06.16 We updated the Google cloud links so that it can be downloaded without permission.
## ToDo List
- [x] Release code
- [x] scripts for training and testing
- [x] Demo script
- [x] Evaluation
- [x] Release pre-trained models
- [x] Release trained models on each benchmarks
- [ ] The reading order module will be released at a certain time
- [ ] Prepare TextSpotter codes based on TextBPN++
<!-- - [ ] The number of control points is determined adaptively -->
## Prerequisites
Python 3.8 – 3.12;
PyTorch >= 2.1 (validated with 2.9.0);
TorchVision matching the PyTorch release;
NumPy >=1.20;
CUDA toolkit >=11.8 (tested with CUDA 12.x);
GCC >=10.0;
*opencv-python < 4.5.0*
NVIDIA GPU (Turing/Volta class or newer);
NOTE: We currently validate builds on Arch Linux + Python 3.9 and Ubuntu 20.04/22.04 with Python 3.10–3.12, using PyTorch 2.9.0 and CUDA 12.x. Other environments may require minor adjustments but should behave similarly in performance.
## Makefile
If DCN is used, some CUDA files need to be compiled
```
# make sure that the PATH of CUDA in setup.py is set properly with the right environment
# Set the GPU you need in setup.py, if If you have different GPUs in your machine.
cd network/backbone/assets/dcn
sh Makefile.sh
# setup.py
import os
PATH ="{}:{}".format(os.environ['PATH'], "/opt/cuda/bin")
# os.environ['CUDA_VISIBLE_DEVICES'] = "1"
os.environ['PATH'] = PATH
from setuptools import setup
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
```
## Dataset Links
1. [CTW1500](https://drive.google.com/file/d/1A2s3FonXq4dHhD64A2NCWc8NQWMH2NFR/view?usp=sharing) (new version dataset at https://github.com/Yuliang-Liu/Curve-Text-Detector)
2. [TD500](https://drive.google.com/file/d/1ByluLnyd8-Ltjo9AC-1m7omZnI-FA1u0/view?usp=sharing)
3. [Total-Text](https://drive.google.com/file/d/17_7T_-2Bu3KSSg2OkXeCxj97TBsjvueC/view?usp=sharing) (new version dataset at: https://github.com/cs-chan/Total-Text-Dataset)
NOTE: The images of each dataset can be obtained from their official website.
## Training
### Prepar dataset
We provide a simple example for each dataset in data, such as [Total-Text](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/data/Total-Text), [CTW-1500](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/data/CTW-1500), and [ArT](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/data/ArT) ...
### Pre-training models
We provide some pre-tarining models on SynText [Baidu Drive](https://pan.baidu.com/s/1PsLrQWAVLDy0fSVp5HL9Ng) (download code: r1ff), [Google Drive](https://drive.google.com/file/d/1x64Lu_dMnQqs9gORQOMFL2wnXUzPWWGT/view?usp=sharing) and MLT-2017 [Baidu Drive](https://pan.baidu.com/s/19V9zqSMdgCHMvPTFngz8Fg) (download code: srym), [Google Drive](https://drive.google.com/file/d/1seVzFT657YzP-lc--yUqsVUek2mpw9tP/view?usp=sharing)
```
├── pretrain
│ ├──Syn
│ ├── TextBPN_resnet50_0.pth #1s
│ ├── TextBPN_resnet18_0.pth #4s
│ ├── TextBPN_deformable_resnet50_0.pth #1s
│ ├── MLT
│ ├── TextBPN_resnet50_300.pth #1s
│ ├── TextBPN_resnet18_300.pth #4s
│ ├── TextBPN_deformable_resnet50_300.pth #1s
```
NOTE: we also provide the pre-tarining scripts for [SynText](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/scripts-train).
### Runing the training scripts
We provide training scripts for each dataset in scripts-train, such as [Total-Text](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/scripts-train), [CTW-1500](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/scripts-train), and [ArT](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/scripts-train) ...
```
# train_Totaltext_res50_1s.sh
#!/bin/bash
cd ../
CUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet50 --scale 1 --max_epoch 660 --batch_size 12 --gpu 0 --input_size 640 --optim Adam --lr 0.001 --num_workers 30
# train_Totaltext_res50_1s_fine_mlt.sh
#!/bin/bash
cd ../
CUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet50 --scale 1 --max_epoch 660 --batch_size 12 --gpu 0 --input_size 640 --optim Adam --lr 0.0001 --num_workers 30 --load_memory True --resume model/pretrain/MLT/TextBPN_resnet50_300.pth
```
## Testing
### Runing the Testing scripts
We provide testing scripts for each dataset in scripts-eval, such as [Total-Text](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/scripts-eval/Eval_Totaltext.sh), [CTW-1500](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/scripts-eval/Eval_CTW1500.sh), and [ArT](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/scripts-eval/Eval_ArT.sh) ...
```
# Eval_ArT.sh
#!/bin/bash
cd ../
##################### eval for ArT with ResNet50 1s ###################################
#CUDA_LAUNCH_BLOCKING=1 python3 eval_textBPN.py --net resnet50 --scale 1 --exp_name ArT --checkepoch 605 --test_size 960 2880 --dis_threshold 0.4 --cls_threshold 0.4 --gpu 0;
##################### eval for ArT with ResNet50-DCN 1s ###################################
CUDA_LAUNCH_BLOCKING=1 python3 eval_textBPN.py --net deformable_resnet50 --scale 1 --exp_name ArT --checkepoch 480 --test_size 960 2880 --dis_threshold 0.4 --cls_threshold 0.8 --gpu 0;
##################### batch eval for ArT ###################################
#for ((i=660; i>=300; i=i-5));
#do
#CUDA_LAUNCH_BLOCKING=1 python3 eval_textBPN.py --exp_name ArT --net deformable_resnet50 --checkepoch $i --test_size 960 2880 --dis_threshold 0.45 --cls_threshold 0.8 --gpu 0;
#done
```
NOTE:If you want to save the visualization results, you need to open “--viz”. Here is an example:
```
CUDA_LAUNCH_BLOCKING=1 python3 eval_textBPN.py --net resnet18 --scale 4 --exp_name TD500 --checkepoch 1135 --test_size 640 960 --dis_threshold 0.35 --cls_threshold 0.9 --gpu 0 --viz;
```
### Demo
You can also run prediction on your own dataset without annotations. Here is an example:
```
#demo.sh
#!/bin/bash
CUDA_LAUNCH_BLOCKING=1 python3 demo.py --net resnet18 --scale 4 --exp_name TD500 --checkepoch 1135 --test_size 640 960 --dis_threshold 0.35 --cls_threshold 0.9 --gpu 0 --viz --img_root /path/to/image
```
### Evaluate the performance
Note that we provide some the protocols for benchmarks ([Total-Text](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/dataset/total_text), [CTW-1500](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/dataset/ctw1500), [MSRA-TD500](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/dataset/TD500), [ICDAR2015](https://github.com/GXYM/TextBPN-Plus-Plus/tree/main/dataset/icdar15)). The embedded evaluation protocol in the code are obtatined from the official protocols. You don't need to run these protocols alone, because our test code will automatically call these scripts, please refer to "[util/eval.py](https://github.com/GXYM/TextBPN-Plus-Plus/blob/main/util/eval.py)"
### Evaluate the speed
We refer to the speed testing scheme of DB. The speed is evaluated by performing a testing image for 50 times to exclude extra IO time.
```
CUDA_LAUNCH_BLOCKING=1 python3 eval_textBPN_speed.py --net resnet18 --scale 4 --exp_name TD500 --checkepoch 1135 --test_size 640 960 --dis_threshold 0.35 --cls_threshold 0.9 --gpu 1;
```
Note that the speed is related to both to the GPU and the CPU.
### Model performance
Our replicated performance (without extra data for pre-training) by using the updated codes:
| Datasets | pre-training | Model |recall | precision |F-measure| FPS |
|:----------: |:-----------: |:-----------: |:-------:|:-----:|:-------:|:---:|
| Total-Text | - | [Res50-1s](https://drive.google.com/file/d/1wZOXGrM74CbrGY_lo4yF907VpbwnLf9d/view?usp=sharing) | 84.22 |91.88 |87.88 |13|
| CTW-1500 | - | [Res50-1s](https://drive.google.com/file/d/1wZOXGrM74CbrGY_lo4yF907VpbwnLf9d/view?usp=sharing) | 82.69 |86.53 |84.57 |14|
The results are reported in our paper as follows:
| Datasets | Model |recall | precision |F-measure| FPS |
|:----------: |:-----------: |:-------:|:-----:|:-------:|:---:|
| Total-Text | [Res18-4s](https://drive.google.com/file/d/11AtAA429JCha8AZLrp3xVURYZOcCC2s1/view?usp=sharing) | 81.90 |89.88 |85.70 |**32.5**|
| Total-Text | [Res50-1s](https://drive.google.com/file/d/11AtAA429JCha8AZLrp3xVURYZOcCC2s1/view?usp=sharing) | 85.34 |91.81 |88.46 |13.3|
| Total-Text | [Res50-1s+DCN](https://drive.google.com/file/d/11AtAA429JCha8AZLrp3xVURYZOcCC2s1/view?usp=sharing) | **87.93** |**92.44** |**90.13** |13.2|
| CTW-1500 | [Res18-4s](https://drive.google.com/file/d/1pEaY7eU7esq5p_ZKcAfDA-fNqQskroUH/view?usp=sharing) | 81.62 |87.55 |84.48 |**35.3**|
| CTW-1500 | [Res50-1s](https://drive.google.com/file/d/1pEaY7eU7esq5p_ZKcAfDA-fNqQskroUH/view?usp=sharing) | 83.77 |87.30 |85.50 |14.1|
| CTW-1500 | [Res50-1s+DCN](https://drive.google.com/file/d/1pEaY7eU7esq5p_ZKcAfDA-fNqQskroUH/view?usp=sharing) | **84.71** |**88.34** |**86.49** |16.5|
| MSRA-TD500 | [Res18-4s](https://drive.google.com/file/d/1zNdqcXwplor3T6yQuw1f2euYZex63K0b/view?usp=sharing) | 87.46 |92.38 |89.85 |**38.5**|
| MSRA-TD500 | [Res50-1s](https://drive.google.com/file/d/1zNdqcXwplor3T6yQuw1f2euYZex63K0b/view?usp=sharing) | 85.40 |89.23 |87.27 |15.2|
| MSRA-TD500 | [Res50-1s+DCN](https://drive.google.com/file/d/1zNdqcXwplor3T6yQuw1f2euYZex63K0b/view?usp=sharing) | **86.77** |**93.69** |**90.10** |15.3|
| MLT-2017 | [Res50-1s](https://drive.google.com/file/d/12_umKAo-eM0NYbAAuJBABlkIbyr5QNCy/view?usp=sharing) | 65.67 |80.49 |72.33 | - |
| MLT-2017 | [Res50-1s+DCN](https://drive.google.com/file/d/12_umKAo-eM0NYbAAuJBABlkIbyr5QNCy/view?usp=sharing) | **72.10** |**83.74** |**77.48** | - |
| ICDAR-ArT | [Res50-1s](https://drive.google.com/file/d/1rn8_YKI9B0JO52uA_4nL4TQE0jjgqm9i/view?usp=sharing) | 71.07 |81.14 |75.77 | - |
| ICDAR-ArT | [Res50-1s+DCN](https://drive.google.com/file/d/1rn8_YKI9B0JO52uA_4nL4TQE0jjgqm9i/view?usp=sharing) | **77.05** |**84.48** |**80.59** | - |
NOTE: The results on ICDAR-ArT and MLT-2017 are aslo can be found on the official competition website ([ICDAR-ArT](https://rrc.cvc.uab.es/?ch=14&com=evaluation&task=1) and [MLT-2017](https://rrc.cvc.uab.es/?ch=8&com=evaluation&task=1)). You can also download the models for each benchmarks
from [Baidu Drive](https://pan.baidu.com/s/1lFgRE_qiAv8ww8pbRTTh6w) (download code: wct1)
### Visual comparison

Qualitative comparisons with [TextRay](https://github.com/LianaWang/TextRay), [ABCNet](https://github.com/aim-uofa/AdelaiDet), and [FCENet](https://github.com/open-mmlab/mmocr) on selected challenging samples from CTW-1500. The images (a)-(d) are borrowed from [FCENet](https://arxiv.org/abs/2104.10442).
## Reading Order Model

**Using the Reading Order Model to predict four key corners on the boundary proposal in turn. The reading order module will be released at a certain time.**
## Citing the related works
Please cite the related works in your publications if it helps your research:
```
@inproceedings{DBLP:conf/iccv/Zhang0YWY21,
author = {Shi{-}Xue Zhang and
Xiaobin Zhu and
Chun Yang and
Hongfa Wang and
Xu{-}Cheng Yin},
title = {Adaptive Boundary Proposal Network for Arbitrary Shape Text Detection},
booktitle = {2021 {IEEE/CVF} International Conference on Computer Vision, {ICCV} 2021, Montreal, QC, Canada, October 10-17, 2021},
pages = {1285--1294},
publisher = {{IEEE}},
year = {2021},
}
@article{zhang2023arbitrary,
title={Arbitrary shape text detection via boundary transformer},
author={Zhang, Shi-Xue and Yang, Chun and Zhu, Xiaobin and Yin, Xu-Cheng},
journal={IEEE Transactions on Multimedia},
year={2023},
publisher={IEEE}
}
@article{DBLP:journals/pami/ZhangZCHY23,
author = {Shi{-}Xue Zhang and
Xiaobin Zhu and
Lei Chen and
Jie{-}Bo Hou and
Xu{-}Cheng Yin},
title = {Arbitrary Shape Text Detection via Segmentation With Probability Maps},
journal = {{IEEE} Trans. Pattern Anal. Mach. Intell.},
volume = {45},
number = {3},
pages = {2736--2750},
year = {2023},
url = {https://doi.org/10.1109/TPAMI.2022.3176122},
doi = {10.1109/TPAMI.2022.3176122},
}
@article{zhang2022kernel,
title={Kernel proposal network for arbitrary shape text detection},
author={Zhang, Shi-Xue and Zhu, Xiaobin and Hou, Jie-Bo and Yang, Chun and Yin, Xu-Cheng},
journal={IEEE Transactions on Neural Networks and Learning Systems},
year={2022},
publisher={IEEE}
}
@inproceedings{DBLP:conf/cvpr/ZhangZHLYWY20,
author = {Shi{-}Xue Zhang and
Xiaobin Zhu and
Jie{-}Bo Hou and
Chang Liu and
Chun Yang and
Hongfa Wang and
Xu{-}Cheng Yin},
title = {Deep Relational Reasoning Graph Network for Arbitrary Shape Text Detection},
booktitle = {2020 {IEEE/CVF} Conference on Computer Vision and Pattern Recognition,
{CVPR} 2020, Seattle, WA, USA, June 13-19, 2020},
pages = {9696--9705},
publisher = {Computer Vision Foundation / {IEEE}},
year = {2020},
doi = {10.1109/CVPR42600.2020.00972},
}
```
## License
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/GXYM/DRRG/blob/master/LICENSE.md) file for details
<!---->
## ✨ Star History
[](https://star-history.com/#GXYM/TextBPN-Plus-Plus&Date)
================================================
FILE: cache/README.md
================================================
Download the pre-training weights on ImgNet for ResNet18 or ResNet50 ...
================================================
FILE: cfglib/config.py
================================================
from easydict import EasyDict
import torch
import os
config = EasyDict()
# Normalize image
config.means = (0.485, 0.456, 0.406)
config.stds = (0.229, 0.224, 0.225)
config.gpu = "1"
# Experiment name #
config.exp_name = "Synthtext"
# dataloader jobs number
config.num_workers = 24
# batch_size
config.batch_size = 12
# training epoch number
config.max_epoch = 200
config.start_epoch = 0
# learning rate
config.lr = 1e-4
# using GPU
config.cuda = True
config.output_dir = 'output'
config.input_size = 640
# max polygon per image
# synText, total-text:64; CTW1500: 64; icdar: 64; MLT: 32; TD500: 64.
config.max_annotation = 64
# adj num for graph
config.adj_num = 4
# control points number
config.num_points = 20
# use hard examples (annotated as '#')
config.use_hard = True
# Load data into memory at one time
config.load_memory = False
# prediction on 1/scale feature map
config.scale = 1
# # clip gradient of loss
config.grad_clip = 25
# demo tcl threshold
config.dis_threshold = 0.3
config.cls_threshold = 0.8
# Contour approximation factor
config.approx_factor = 0.004
def update_config(config, extra_config):
for k, v in vars(extra_config).items():
config[k] = v
# print(config.gpu)
config.device = torch.device('cuda') if config.cuda else torch.device('cpu')
def print_config(config):
print('==========Options============')
for k, v in config.items():
print('{}: {}'.format(k, v))
print('=============End=============')
================================================
FILE: cfglib/option.py
================================================
import argparse
import torch
import os
import torch.backends.cudnn as cudnn
from datetime import datetime
def str2bool(v):
return v.lower() in ("yes", "true", "t", "1")
def arg2str(args):
args_dict = vars(args)
option_str = datetime.now().strftime('%b%d_%H-%M-%S') + '\n'
for k, v in sorted(args_dict.items()):
option_str += ('{}: {}\n'.format(str(k), str(v)))
return option_str
class BaseOptions(object):
def __init__(self):
self.parser = argparse.ArgumentParser()
# basic opts
self.parser.add_argument('--exp_name', default="TD500", type=str,
choices=['Synthtext', 'Totaltext', 'Ctw1500','Icdar2015',
"MLT2017", 'TD500', "MLT2019", "ArT", "ALL"], help='Experiment name')
self.parser.add_argument("--gpu", default="1", help="set gpu id", type=str)
self.parser.add_argument('--resume', default=None, type=str, help='Path to target resume checkpoint')
self.parser.add_argument('--num_workers', default=24, type=int, help='Number of workers used in dataloading')
self.parser.add_argument('--cuda', default=True, type=str2bool, help='Use cuda to train model')
self.parser.add_argument('--mgpu', action='store_true', help='Use multi-gpu to train model')
self.parser.add_argument('--save_dir', default='./model/', help='Path to save checkpoint models')
self.parser.add_argument('--vis_dir', default='./vis/', help='Path to save visualization images')
self.parser.add_argument('--log_dir', default='./logs/', help='Path to tensorboard log')
self.parser.add_argument('--loss', default='CrossEntropyLoss', type=str, help='Training Loss')
# self.parser.add_argument('--input_channel', default=1, type=int, help='number of input channels' )
self.parser.add_argument('--pretrain', default=False, type=str2bool, help='Pretrained AutoEncoder model')
self.parser.add_argument('--verbose', '-v', default=True, type=str2bool, help='Whether to output debug info')
self.parser.add_argument('--viz', action='store_true', help='Whether to output debug info')
# self.parser.add_argument('--viz', default=True, type=str2bool, help='Whether to output debug info')
# train opts
self.parser.add_argument('--max_epoch', default=250, type=int, help='Max epochs')
self.parser.add_argument('--lr', '--learning-rate', default=1e-3, type=float, help='initial learning rate')
self.parser.add_argument('--lr_adjust', default='fix',
choices=['fix', 'poly'], type=str, help='Learning Rate Adjust Strategy')
self.parser.add_argument('--stepvalues', default=[], nargs='+', type=int, help='# of iter to change lr')
self.parser.add_argument('--weight_decay', '--wd', default=0., type=float, help='Weight decay for SGD')
self.parser.add_argument('--gamma', default=0.1, type=float, help='Gamma update for SGD lr')
self.parser.add_argument('--momentum', default=0.9, type=float, help='momentum')
self.parser.add_argument('--batch_size', default=6, type=int, help='Batch size for training')
self.parser.add_argument('--optim', default='Adam', type=str, choices=['SGD', 'Adam'], help='Optimizer')
self.parser.add_argument('--save_freq', default=5, type=int, help='save weights every # epoch')
self.parser.add_argument('--display_freq', default=10, type=int, help='display training metrics every # iter')
self.parser.add_argument('--viz_freq', default=50, type=int, help='visualize training process every # iter')
self.parser.add_argument('--log_freq', default=10000, type=int, help='log to tensorboard every # iterations')
self.parser.add_argument('--val_freq', default=1000, type=int, help='do validation every # iterations')
# backbone
self.parser.add_argument('--scale', default=1, type=int, help='prediction on 1/scale feature map')
self.parser.add_argument('--net', default='resnet50', type=str,
choices=['vgg', 'resnet50', 'resnet18',
"deformable_resnet18", "deformable_resnet50"],
help='Network architecture')
# data args
self.parser.add_argument('--load_memory', default=False, type=str2bool, help='Load data into memory')
self.parser.add_argument('--rescale', type=float, default=255.0, help='rescale factor')
self.parser.add_argument('--input_size', default=640, type=int, help='model input size')
self.parser.add_argument('--test_size', default=[640, 960], type=int, nargs='+', help='test size')
# eval args00
self.parser.add_argument('--checkepoch', default=1070, type=int, help='Load checkpoint number')
self.parser.add_argument('--start_epoch', default=0, type=int, help='start epoch number')
self.parser.add_argument('--cls_threshold', default=0.875, type=float, help='threshold of pse')
self.parser.add_argument('--dis_threshold', default=0.35, type=float, help='filter the socre < score_i')
# demo args
self.parser.add_argument('--img_root', default=None, type=str, help='Path to deploy images')
def parse(self, fixed=None):
if fixed is not None:
args = self.parser.parse_args(fixed)
else:
args = self.parser.parse_args()
return args
def initialize(self, fixed=None):
# Parse options
self.args = self.parse(fixed)
os.environ['CUDA_VISIBLE_DEVICES'] = self.args.gpu
# Setting default torch Tensor type
if self.args.cuda and torch.cuda.is_available():
torch.set_default_tensor_type('torch.cuda.FloatTensor')
cudnn.benchmark = True
else:
torch.set_default_tensor_type('torch.FloatTensor')
# Create weights saving directory
if not os.path.exists(self.args.save_dir):
os.mkdir(self.args.save_dir)
# Create weights saving directory of target model
model_save_path = os.path.join(self.args.save_dir, self.args.exp_name)
if not os.path.exists(model_save_path):
os.mkdir(model_save_path)
return self.args
def update(self, args, extra_options):
for k, v in extra_options.items():
setattr(args, k, v)
================================================
FILE: data/ArT/README.md
================================================
## ArT
An example of the path of ArT dataset:
```
├── ArT
│ ├──Images
│ ├── Train
│ ├── Test
│ ├── gt
│ ├── train_labels.json
│ ├── Train # convert the "train_labels.json" to ".txt"
```
================================================
FILE: data/CTW-1500/README.md
================================================
## CTW-1500 (new)
An example of the path of CTW-1500 dataset:
```
├── CTW-1500
│ ├──Images
│ ├── Train
│ ├── Test
│ ├── gt
│ ├── train_labels # gt with ".xml"
│ ├── test_labels
```
================================================
FILE: data/Icdar2015/README.md
================================================
## ICDAR 2015
An example of the path of ICDAR2015 dataset:
```
├── Icdar2015
│ ├──Train (include img and gt files)
│ ├──Test (include img and gt files)
│
```
================================================
FILE: data/LSVT/README.md
================================================
## LSVT
An example of the path of LSVT dataset:
```
├── LSVT
│ ├──Images
│ ├── Train
│ ├── ...
│ ├── gt
│ ├── train_full_labels.json
│ ├── ...
```
`
================================================
FILE: data/MLT-2019/README.md
================================================
## MLT-2019
An example of the path of MLT-2019 dataset:
```
├── MLT-2019
│ ├──TrainImages
│ ├──Train_gt # gt with ".txt"
│ ├──TestImages
│
│ ├──train_list.txt
│ ├──test_list.txt
```
================================================
FILE: data/MLT2017/README.md
================================================
## MLT2017
An example of the path of MLT2017 dataset:
```
├── MLT2017
│ ├──mlt_train
│ ├──mlt_val
│ ├──mlt_test
│
│ ├──train_list.txt
│ ├──val_list.txt
│ ├──test_list.txt
```
================================================
FILE: data/README.md
================================================
Put the datasets here
================================================
FILE: data/SynthText/README.md
================================================
## SynthText
An example of the path of SynthText dataset:
```
├── SynthText
│ ├──1
│ ├──...
│ ├──200
│
│ ├──gt # gt with ".txt"
│ ├──image_list.txt
```
================================================
FILE: data/SynthText/findPath.sh
================================================
#!/bin/bash
root_dir="./gt_e2e/"
fn="/*.txt"
out_fn="gt_e2e.txt"
for element in `ls $root_dir`
do
echo $root_dir$element$fn
`ls $root_dir$element$fn >>$out_fn`
done
================================================
FILE: data/TD500/README.md
================================================
## TD500
An example of the path of TD500 dataset:
```
├── TD500
│ ├──Train (include img and gt(".txt") files)
│ ├──Test (include img and gt(".txt") files)
│
```
================================================
FILE: data/Total-Text/README.md
================================================
## Total-Text (new)
An example of the path of Total-Text dataset:
```
├── Total-Text
│ ├──Images
│ ├── Train
│ ├── Test
│ ├── gt
│ ├──Rectangular
│ ├── Train # gt with ".mat"
│ ├── Test # gt with ".mat"
│ ├──Polygon
│ ├── Train # gt with ".mat"
│ ├── Test # gt with ".mat"
│ ├──gt_pixel
│ ├── Train # gt with binary img
│ ├── Test # gt with binary img
```
================================================
FILE: data/ctw1500/README.md
================================================
## CTW-1500 (old)
An example of the path of CTW-1500 dataset:
```
├── ctw1500
│ ├──train
│ ├── text_image
│ ├── text_label_circum # gt with ".txt"
│ ├── test
│ ├── text_image
│ ├── text_label_circum
```
================================================
FILE: data/total-text-mat/README.md
================================================
## Total-Text (old)
An example of the path of Total-Text dataset:
```
├── total-text-mat
│ ├──Images
│ ├── Train
│ ├── Test
│ ├── gt
│ ├── Train # gt with ".mat"
│ ├── Test
```
================================================
FILE: dataset/CTW1500_Text_New.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = '古溪'
import os
import cv2
import numpy as np
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines
from lxml import etree as ET
class Ctw1500Text_New(TextDataset):
def __init__(self, data_root, is_training=True, load_memory=False, transform=None, ignore_list=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
self.image_root = os.path.join(data_root, 'Images', 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root, 'gt', 'train_labels' if is_training else 'test_labels')
self.image_list = os.listdir(self.image_root)
self.annotation_list = ['{}'.format(img_name.replace('.jpg', '')) for img_name in self.image_list]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_carve_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = read_lines(gt_path + ".txt")
polygons = []
for line in lines:
line = line.split(",")
gt = list(map(int, line[:-1]))
pts = np.stack([gt[0::2], gt[1::2]]).T.astype(np.int32)
label = line[-1].split("###")[-1].replace("###", "#")
polygons.append(TextInstance(pts, 'c', label))
return polygons
@staticmethod
def parse_carve_xml(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
root = ET.parse(gt_path + ".xml").getroot()
polygons = []
for tag in root.findall('image/box'):
label = tag.find("label").text.replace("###", "#")
gt = list(map(int, tag.find("segs").text.split(",")))
pts = np.stack([gt[0::2], gt[1::2]]).T.astype(np.int32)
polygons.append(TextInstance(pts, 'c', label))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
try:
h, w, c = image.shape
assert (c == 3)
except:
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
# Read annotation
if self.is_training:
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
polygons = self.parse_carve_xml(annotation_path)
pass
else:
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, "000" + annotation_id)
polygons = self.parse_carve_txt(annotation_path)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id.split("/")[-1]
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
from util.augmentation import Augmentation
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = Ctw1500Text_New(
data_root='../data/CTW-1500',
is_training=True,
transform=transform
)
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[idx]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags\
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
boundary_point = ctrl_points[np.where(ignore_tags != 0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
# from util.misc import split_edge_seqence
# from cfglib.config import config as cfg
#
# ret, labels = cv2.connectedComponents(np.array(distance_field >0.35, dtype=np.uint8), connectivity=4)
# for idx in range(1, ret):
# text_mask = labels == idx
# ist_id = int(np.sum(text_mask*tr_mask)/np.sum(text_mask))-1
# contours, _ = cv2.findContours(text_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# epsilon = 0.007 * cv2.arcLength(contours[0], True)
# approx = cv2.approxPolyDP(contours[0], epsilon, True).reshape((-1, 2))
#
# pts_num = approx.shape[0]
# e_index = [(i, (i + 1) % pts_num) for i in range(pts_num)]
# control_points = split_edge_seqence(approx, e_index, cfg.num_points)
# control_points = np.array(control_points[:cfg.num_points, :]).astype(np.int32)
#
# cv2.drawContours(img, [ctrl_points[ist_id].astype(np.int32)], -1, (0, 255, 0), 1)
# cv2.drawContours(img, [control_points.astype(np.int32)], -1, (0, 0, 255), 1)
# for j, pp in enumerate(control_points):
# if j == 0:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
# elif j == 1:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
# else:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 0), -1)
#
# cv2.imshow('imgs', img)
# cv2.waitKey(0)
================================================
FILE: dataset/Icdar15_Text.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = '古溪'
import re
import os
import numpy as np
from util import strs
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines
from util.misc import norm2
class Icdar15Text(TextDataset):
def __init__(self, data_root, is_training=True, load_memory=False, transform=None, ignore_list=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
self.image_root = os.path.join(data_root, 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root,'Train' if is_training else 'Test')
self.image_list = os.listdir(self.image_root)
p = re.compile('.rar|.txt')
self.image_list = [x for x in self.image_list if not p.findall(x)]
p = re.compile('(.jpg|.JPG|.PNG|.JPEG)')
self.annotation_list = ['{}'.format(p.sub("", img_name)) for img_name in self.image_list]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = read_lines(gt_path+".txt")
polygons = []
for line in lines:
line = strs.remove_all(line.strip('\ufeff'), '\xef\xbb\xbf')
gt = line.split(',')
x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, gt[:8]))
xx = [x1, x2, x3, x4]
yy = [y1, y2, y3, y4]
label = gt[-1].strip().replace("###", "#")
pts = np.stack([xx, yy]).T.astype(np.int32)
# d1 = norm2(pts[0] - pts[1])
# d2 = norm2(pts[1] - pts[2])
# d3 = norm2(pts[2] - pts[3])
# d4 = norm2(pts[3] - pts[0])
# if min([d1, d2, d3, d4]) < 2:
# continue
polygons.append(TextInstance(pts, 'c', label))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
try:
# Read annotation
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
polygons = self.parse_txt(annotation_path)
except Exception as e:
print(e)
polygons = None
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id.split("/")[-1]
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
import cv2
from util.augmentation import Augmentation
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = Icdar15Text(
data_root='../data/Icdar2015',
is_training=True,
transform=transform
)
# img, train_mask, tr_mask, tcl_mask, radius_map, sin_map, cos_map, meta = trainset[944]
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask = trainset[idx]
img, train_mask, tr_mask = map(lambda x: x.cpu().numpy(), (img, train_mask, tr_mask))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
print(idx, img.shape)
for i in range(tr_mask.shape[2]):
cv2.imshow("tr_mask_{}".format(i),
cav.heatmap(np.array(tr_mask[:, :, i] * 255 / np.max(tr_mask[:, :, i]), dtype=np.uint8)))
cv2.imshow("train_mask", cav.heatmap(np.array(train_mask * 255 / np.max(train_mask), dtype=np.uint8)))
cv2.imshow('imgs', img)
cv2.waitKey(0)
================================================
FILE: dataset/Icdar17_Text.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import os
import numpy as np
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines
from util.misc import norm2
from util import strs
import cv2
class Mlt2017Text(TextDataset):
def __init__(self, data_root, is_training=True, load_memory=False, transform=None, ignore_list=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
if is_training:
with open(os.path.join(data_root, 'train_list.txt')) as f:
self.img_train_list = [line.strip() for line in f.readlines()]
with open(os.path.join(data_root, 'val_list.txt')) as f:
self.img_val_list = [line.strip() for line in f.readlines()]
# with open(os.path.join(data_root, 'ic15_list.txt')) as f:
# self.img_15_list = [line.strip() for line in f.readlines()]
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.img_list = self.img_val_list + self.img_train_list #+self.img_15_list
# self.img_list = list(filter(lambda img: img.replace('', '') not in ignore_list, self.img_list))
else:
with open(os.path.join(data_root, 'test_list.txt')) as f:
self.img_list = [line.strip() for line in f.readlines()]\
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = read_lines(gt_path + ".txt")
polygons = []
for line in lines:
line = strs.remove_all(line.strip('\ufeff'), '\xef\xbb\xbf')
gt = line.split(',')
x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, gt[:8]))
xx = [x1, x2, x3, x4]
yy = [y1, y2, y3, y4]
if gt[-1].strip() == "###":
label = gt[-1].strip().replace("###", "#")
else:
label = "GG"
pts = np.stack([xx, yy]).T.astype(np.int32)
polygons.append(TextInstance(pts, 'c', label))
return polygons
def load_img_gt(self, item):
image_id = self.img_list[item]
if self.is_training:
# Read annotation
annotation_id = "{}/gt_{}".format("/".join(image_id.split("/")[0:-1]),
image_id.split("/")[-1].replace(".jpg", ''))
annotation_path = os.path.join(self.data_root, annotation_id)
polygons = self.parse_txt(annotation_path)
else:
polygons = None
# Read image data
image_path = os.path.join(self.data_root, image_id)
image = pil_load_img(image_path)
try:
h, w, c = image.shape
assert (c == 3)
except:
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id.split("/")[-1]
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.img_list)
if __name__ == '__main__':
import os
from util.augmentation import BaseTransform, Augmentation
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = Mlt2017Text(
data_root='../data/MLT2017',
is_training=True,
transform=transform
)
# img, train_mask, tr_mask, tcl_mask, radius_map, sin_map, cos_map, meta = trainset[944]
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask = trainset[idx]
img, train_mask, tr_mask = map(lambda x: x.cpu().numpy(), (img, train_mask, tr_mask))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
print(idx, img.shape)
for i in range(tr_mask.shape[2]):
cv2.imshow("tr_mask_{}".format(i),
cav.heatmap(np.array(tr_mask[:, :, i] * 255 / np.max(tr_mask[:, :, i]), dtype=np.uint8)))
cv2.imshow("tr_mask",
cav.heatmap(np.array(train_mask * 255 / np.max(train_mask), dtype=np.uint8)))
cv2.imshow('imgs', img)
cv2.waitKey(0)
================================================
FILE: dataset/Icdar19ArT_Json.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import os
import numpy as np
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines, load_json
import cv2
class ArtTextJson(TextDataset):
def __init__(self, data_root, is_training=True, ignore_list=None, load_memory=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.image_root = os.path.join(data_root, "Images", "Train" if is_training else "Test")
self.image_list = os.listdir(self.image_root)
self.image_list = list(filter(lambda img: img.replace(".jpg", "") not in ignore_list, self.image_list))
if self.is_training:
annotation_file = os.path.join(data_root, "gt", "train_labels.json" if is_training else "None")
self.annotation_data = load_json(annotation_file)
self.image_list, self.annotationdata_list = self.preprocess(self.image_list, self.annotation_data)
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def preprocess(image_list: list, annotation_data: dict):
"""
Decompose the all in one annotation_dict into seperate list element(annotation_list).
The order of the annotation_list will be the same with image_list. To keep it simple,
here both image_list and annotationdata_list will be sorted following the same criteria.
"""
annotationdata_list = [
v for _, v in sorted(annotation_data.items(), key=lambda item: item[0])
]
image_list = sorted(image_list)
return image_list, annotationdata_list
def parse_curve_txt(self, gt_data):
polygons = []
for candidate in gt_data:
text = candidate.get("transcription").strip().replace("###", "#")
pts = candidate.get("points")
pts = np.array(pts).astype(np.int32)
if pts.shape[0] < 4:
continue
polygons.append(TextInstance(pts, "c", text))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
image = pil_load_img(image_path)
try:
assert image.shape[-1] == 3
except:
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
if self.is_training:
# Read annotation
annotation_data = self.annotationdata_list[item]
polygons = self.parse_curve_txt(annotation_data)
else:
polygons = None
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == "__main__":
# execute in base dir `PYTHONPATH=.:$PYTHONPATH python dataset/Icdar19ArT_Text.py`
from util.augmentation import Augmentation
from util.misc import regularize_sin_cos
from util.pbox import bbox_transfor_inv, minConnectPath
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(size=640, mean=means, std=stds)
trainset = ArtTextJson(
data_root="/home/prir1005/pubdata/ArT",
is_training=True,
transform=transform,
)
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[1000]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags \
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
distance_map = cav.heatmap(np.array(distance_field * 255 / np.max(distance_field), dtype=np.uint8))
cv2.imshow("distance_map", distance_map)
cv2.waitKey(0)
direction_map = cav.heatmap(np.array(direction_field[0] * 255 / np.max(direction_field[0]), dtype=np.uint8))
cv2.imshow("direction_field", direction_map)
cv2.waitKey(0)
from util.vis_flux import vis_direction_field
vis_direction_field(direction_field)
weight_map = cav.heatmap(np.array(weight_matrix * 255 / np.max(weight_matrix), dtype=np.uint8))
cv2.imshow("weight_matrix", weight_map)
# cv2.waitKey(0)
boundary_point = ctrl_points[np.where(ignore_tags != 0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
================================================
FILE: dataset/Icdar19ArT_Text.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import warnings
warnings.filterwarnings("ignore")
import os
import re
import numpy as np
import scipy.io as io
from util import strs
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
import cv2
from util import io as libio
class ArtText(TextDataset):
def __init__(self, data_root, ignore_list=None, is_training=True, load_memory=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.image_root = os.path.join(data_root, 'Images', 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root, 'gt', 'Train' if is_training else 'Test')
self.image_list = os.listdir(self.image_root)
self.image_list = list(filter(lambda img: img.replace('.jpg', '') not in ignore_list, self.image_list))
self.annotation_list = ['{}'.format(img_name.replace('.jpg', '')) for img_name in self.image_list]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_carve_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = libio.read_lines(gt_path + ".txt")
polygons = []
for line in lines:
line = strs.remove_all(line, '\xef\xbb\xbf')
gt = line.split(',')
gt_corrdinate = gt[:-3]
if len(gt_corrdinate) < 6:
continue
pts = np.stack([gt_corrdinate[0::2], gt_corrdinate[1::2]]).T.astype(np.int32)
text = gt[-1].replace("\n","")
polygons.append(TextInstance(pts, 'c', text))
# print(polygon)
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
try:
h, w, c = image.shape
assert (c == 3)
except:
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
# Read annotation
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
# polygons = self.parse_mat(annotation_path)
polygons = self.parse_carve_txt(annotation_path)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
import time
from util.augmentation import Augmentation, BaseTransformNresize
from util import canvas as cav
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = ArtText(
data_root="/home/prir1005/pubdata/ArT",
is_training=True,
transform=transform,
)
t0 = time.time()
image, tr_mask, train_mask, label_mask, gt_points, ignore_tags = trainset[30]
image, tr_mask, train_mask, label_mask, gt_points, ignore_tags = \
map(lambda x: x.cpu().numpy(), (image, tr_mask, train_mask, label_mask, gt_points, ignore_tags))
img = image.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
for i in range(tr_mask.shape[0]):
heatmap = cav.heatmap(np.array(tr_mask[i, :, :] * 255 / np.max(tr_mask[i, :, :]), dtype=np.uint8))
cv2.imshow("tr_mask_{}".format(i), heatmap)
cv2.imshow('train_mask_{}'.format(i), cav.heatmap(np.array(train_mask[i] * 255 / np.max(train_mask[i]), dtype=np.uint8)))
boundary_points = gt_points[np.where(ignore_tags != 0)[0]]
ignore_points = gt_points[np.where(ignore_tags == -1)[0]]
for i in range(tr_mask.shape[0]):
im = img.copy()
gt_point = boundary_points[:, i, :, :]
ignore_point = ignore_points[:, i, :, :]
cv2.drawContours(im, gt_point.astype(np.int32), -1, (0, 255, 0), 1)
cv2.drawContours(im, ignore_point.astype(np.int32), -1, (0, 0, 255), 1)
cv2.imshow('imgs_{}'.format(i), im)
cv2.waitKey(0)
================================================
FILE: dataset/Icdar19LSVT_Json.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import os
import numpy as np
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines, load_json
import cv2
class LsvtTextJson(TextDataset):
def __init__(self, data_root, is_training=True, ignore_list=None,
care_flag=True, load_memory=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.care_flag = care_flag
self.load_memory = load_memory
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.image_root = os.path.join(data_root, "Images", "Train" if is_training else "Test")
self.image_list = os.listdir(self.image_root)
self.image_list = list(filter(lambda img: img.replace(".jpg", "") not in ignore_list, self.image_list))
if self.is_training:
annotation_file = os.path.join(data_root, "gt", "train_full_labels.json" if is_training else "None")
self.annotation_data = load_json(annotation_file)
self.image_list, self.annotationdata_list = self.preprocess(self.image_list, self.annotation_data)
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def preprocess(image_list: list, annotation_data: dict):
"""
Decompose the all in one annotation_dict into seperate list element(annotation_list).
The order of the annotation_list will be the same with image_list. To keep it simple,
here both image_list and annotationdata_list will be sorted following the same criteria.
"""
annotationdata_list = [
v for _, v in sorted(annotation_data.items(), key=lambda item: item[0])
]
image_list = sorted(image_list)
return image_list, annotationdata_list
def parse_curve_txt(self, gt_data):
polygons = []
for candidate in gt_data:
text = candidate.get("transcription").strip().replace("###", "#")
pts = candidate.get("points")
pts = np.array(pts).astype(np.int32)
if pts.shape[0] < 4:
continue
polygons.append(TextInstance(pts, "c", text))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
image = pil_load_img(image_path)
try:
assert image.shape[-1] == 3
except:
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
if self.is_training:
# Read annotation
annotation_data = self.annotationdata_list[item]
polygons = self.parse_curve_txt(annotation_data)
else:
polygons = None
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == "__main__":
# execute in base dir `PYTHONPATH=.:$PYTHONPATH python dataset/Icdar19ArT_Text.py`
from util.augmentation import Augmentation
from util.misc import regularize_sin_cos
from util.pbox import bbox_transfor_inv, minConnectPath
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(size=640, mean=means, std=stds)
trainset = LsvtTextJson(
data_root="/home/prir1005/pubdata/LSVT",
is_training=True,
transform=transform,
)
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[1567]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags \
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
distance_map = cav.heatmap(np.array(distance_field * 255 / np.max(distance_field), dtype=np.uint8))
cv2.imshow("distance_map", distance_map)
cv2.waitKey(0)
direction_map = cav.heatmap(np.array(direction_field[0] * 255 / np.max(direction_field[0]), dtype=np.uint8))
cv2.imshow("direction_field", direction_map)
cv2.waitKey(0)
from util.vis_flux import vis_direction_field
vis_direction_field(direction_field)
weight_map = cav.heatmap(np.array(weight_matrix * 255 / np.max(weight_matrix), dtype=np.uint8))
cv2.imshow("weight_matrix", weight_map)
# cv2.waitKey(0)
boundary_point = ctrl_points[np.where(ignore_tags != 0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
================================================
FILE: dataset/Icdar19_Text.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import os
import numpy as np
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines
from util.misc import norm2
from util import strs
import cv2
class Mlt2019Text(TextDataset):
def __init__(self, data_root, is_training=True, transform=None, load_memory=False, ignore_list=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
self.image_root = os.path.join(data_root, 'TrainImages' if is_training else 'TestImages')
self.annotation_root = os.path.join(data_root, 'Train_gt' if is_training else None)
if is_training:
with open(os.path.join(data_root, 'train_list.txt')) as f:
self.img_list = [line.strip() for line in f.readlines()]
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
else:
with open(os.path.join(data_root, 'test_list.txt')) as f:
self.img_list = [line.strip() for line in f.readlines()]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = read_lines(gt_path + ".txt")
polygons = []
for line in lines:
line = strs.remove_all(line.strip('\ufeff'), '\xef\xbb\xbf')
gt = line.split(',')
x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, gt[:8]))
xx = [x1, x2, x3, x4]
yy = [y1, y2, y3, y4]
if gt[-1].strip() == "###":
label = gt[-1].strip().replace("###", "#")
else:
label = "GG"
pts = np.stack([xx, yy]).T.astype(np.int32)
polygons.append(TextInstance(pts, 'c', label))
return polygons
def load_img_gt(self, item):
image_id = self.img_list[item]
if self.is_training:
# Read annotation
annotation_path = os.path.join(self.annotation_root, image_id.split(".")[0])
polygons = self.parse_txt(annotation_path)
else:
polygons = None
# Read image data
image_path = os.path.join(self.image_root, image_id)
image = pil_load_img(image_path)
try:
h, w, c = image.shape
assert (c == 3)
except:
# print(image_path)
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = np.array(image)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id.split("/")[-1]
data["image_path"] = image_path
return data
def __getitem__(self, item):
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.img_list)
if __name__ == '__main__':
import os
from util.augmentation import BaseTransform, Augmentation
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = Mlt2019Text(
data_root='../data/MLT-2019',
is_training=True,
transform=transform
)
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[idx]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags \
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
distance_map = cav.heatmap(np.array(distance_field * 255 / np.max(distance_field), dtype=np.uint8))
cv2.imshow("distance_map", distance_map)
cv2.waitKey(0)
direction_map = cav.heatmap(np.array(direction_field[0] * 255 / np.max(direction_field[0]), dtype=np.uint8))
cv2.imshow("direction_field", direction_map)
cv2.waitKey(0)
from util.vis_flux import vis_direction_field
vis_direction_field(direction_field)
weight_map = cav.heatmap(np.array(weight_matrix * 255 / np.max(weight_matrix), dtype=np.uint8))
cv2.imshow("weight_matrix", weight_map)
# cv2.waitKey(0)
boundary_point = ctrl_points[np.where(ignore_tags != 0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j == 0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j == 1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
# from util.misc import split_edge_seqence
# from cfglib.config import config as cfg
#
# ret, labels = cv2.connectedComponents(np.array(distance_field >0.35, dtype=np.uint8), connectivity=4)
# for idx in range(1, ret):
# text_mask = labels == idx
# ist_id = int(np.sum(text_mask*tr_mask)/np.sum(text_mask))-1
# contours, _ = cv2.findContours(text_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# epsilon = 0.007 * cv2.arcLength(contours[0], True)
# approx = cv2.approxPolyDP(contours[0], epsilon, True).reshape((-1, 2))
#
# control_points = split_edge_seqence(approx, cfg.num_points)
# control_points = np.array(control_points[:cfg.num_points, :]).astype(np.int32)
#
# cv2.drawContours(img, [ctrl_points[ist_id].astype(np.int32)], -1, (0, 255, 0), 1)
# cv2.drawContours(img, [control_points.astype(np.int32)], -1, (0, 0, 255), 1)
# for j, pp in enumerate(control_points):
# if j == 0:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
# elif j == 1:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
# else:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 0), -1)
#
# cv2.imshow('imgs', img)
# cv2.waitKey(0)
================================================
FILE: dataset/README.md
================================================
You can add your dataset load scripts here, and details you refer to the loading script of other datasets, such as CTW1500, Total-Text, and MLT2017 ...
================================================
FILE: dataset/TD500/075eval.sh
================================================
rm submit/*
cp $1/*.txt submit
cd submit/;zip -r submit.zip *;mv submit.zip ../; cd ../
python2 script075.py -g=gt.zip -s=submit.zip
================================================
FILE: dataset/TD500/Evaluation_Protocol/readme.txt
================================================
INSTRUCTIONS FOR THE STANDALONE SCRIPTS
Requirements:
- Python version 2.7.
- Each Task requires different Python modules. When running the script, if some module is not installed you will see a notification and installation instructions.
Procedure:
Download the ZIP file for the requested script and unzip it to a directory.
Open a terminal in the directory and run the command:
python script.py –g=gt.zip –s=submit.zip
If you have already installed all the required modules, then you will see the method’s results or an error message if the submitted file is not correct.
parameters:
-g: Path of the Ground Truth file. In most cases, the Ground Truth will be included in the same Zip file named 'gt.zip', gt.txt' or 'gt.json'. If not, you will be able to get it on the Downloads page of the Task.
-s: Path of your method's results file.
Optional parameters:
-o: Path to a directory where to copy the file ‘results.zip’ that contains per-sample results.
-p: JSON string parameters to override the script default parameters. The parameters that can be overrided are inside the function 'default_evaluation_params' located at the begining of the evaluation Script.
Example: python script.py –g=gt.zip –s=submit.zip –o=./ -p='{" IOU_CONSTRAINT" = 0.8}'
================================================
FILE: dataset/TD500/Evaluation_Protocol/rrc_evaluation_funcs.py
================================================
#!/usr/bin/env python2
#encoding: UTF-8
import json
import sys;sys.path.append('./')
import zipfile
import re
import sys
import os
import codecs
import importlib
# from StringIO import StringIO
def print_help():
sys.stdout.write('Usage: python %s.py -g=<gtFile> -s=<submFile> [-o=<outputFolder> -p=<jsonParams>]' %sys.argv[0])
sys.exit(2)
def load_zip_file_keys(file,fileNameRegExp=''):
"""
Returns an array with the entries of the ZIP file that match with the regular expression.
The key's are the names or the file or the capturing group definied in the fileNameRegExp
"""
try:
archive=zipfile.ZipFile(file, mode='r', allowZip64=True)
except :
raise Exception('Error loading the ZIP archive.')
pairs = []
for name in archive.namelist():
addFile = True
keyName = name
if fileNameRegExp!="":
m = re.match(fileNameRegExp,name)
if m == None:
addFile = False
else:
if len(m.groups())>0:
keyName = m.group(1)
if addFile:
pairs.append( keyName )
return pairs
def load_zip_file(file,fileNameRegExp='',allEntries=False):
"""
Returns an array with the contents (filtered by fileNameRegExp) of a ZIP file.
The key's are the names or the file or the capturing group definied in the fileNameRegExp
allEntries validates that all entries in the ZIP file pass the fileNameRegExp
"""
try:
archive=zipfile.ZipFile(file, mode='r', allowZip64=True)
except :
raise Exception('Error loading the ZIP archive')
pairs = []
for name in archive.namelist():
addFile = True
keyName = name
if fileNameRegExp!="":
m = re.match(fileNameRegExp,name)
if m == None:
addFile = False
else:
if len(m.groups())>0:
keyName = m.group(1)
if addFile:
pairs.append( [ keyName , archive.read(name)] )
else:
if allEntries:
raise Exception('ZIP entry not valid: %s' %name)
return dict(pairs)
def decode_utf8(raw):
"""
Returns a Unicode object on success, or None on failure
"""
try:
raw = codecs.decode(raw,'utf-8', 'replace')
#extracts BOM if exists
raw = raw.encode('utf8')
if raw.startswith(codecs.BOM_UTF8):
raw = raw.replace(codecs.BOM_UTF8, '', 1)
return raw.decode('utf-8')
except:
return None
def validate_lines_in_file(fileName,file_contents,CRLF=True,LTRB=True,withTranscription=False,withConfidence=False,imWidth=0,imHeight=0):
"""
This function validates that all lines of the file calling the Line validation function for each line
"""
utf8File = decode_utf8(file_contents)
if (utf8File is None) :
raise Exception("The file %s is not UTF-8" %fileName)
lines = utf8File.split( "\r\n" if CRLF else "\n" )
for line in lines:
line = line.replace("\r","").replace("\n","")
if(line != ""):
try:
validate_tl_line(line,LTRB,withTranscription,withConfidence,imWidth,imHeight)
except Exception as e:
raise Exception(("Line in sample not valid. Sample: %s Line: %s Error: %s" %(fileName,line,str(e))).encode('utf-8', 'replace'))
def validate_tl_line(line,LTRB=True,withTranscription=True,withConfidence=True,imWidth=0,imHeight=0):
"""
Validate the format of the line. If the line is not valid an exception will be raised.
If maxWidth and maxHeight are specified, all points must be inside the imgage bounds.
Posible values are:
LTRB=True: xmin,ymin,xmax,ymax[,confidence][,transcription]
LTRB=False: x1,y1,x2,y2,x3,y3,x4,y4[,confidence][,transcription]
"""
get_tl_line_values(line,LTRB,withTranscription,withConfidence,imWidth,imHeight)
def get_tl_line_values(line,LTRB=True,withTranscription=False,withConfidence=False,imWidth=0,imHeight=0,withAngel=True):
"""
Validate the format of the line. If the line is not valid an exception will be raised.
If maxWidth and maxHeight are specified, all points must be inside the imgage bounds.
Posible values are:
LTRB=True: xmin,ymin,xmax,ymax[,confidence][,transcription]
LTRB=False: x1,y1,x2,y2,x3,y3,x4,y4[,confidence][,transcription]
Returns values from a textline. Points , [Confidences], [Transcriptions]
"""
confidence = 0.0
transcription = "";
points = []
numPoints = 4;
if LTRB:
numPoints = 4;
if withAngel:
if withTranscription and withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*(-?[0-1].?[0-9]*)\s*,\s*([0-1].?[0-9]*)\s*,(.*)$',line)
if m == None :
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*(-?[0-1].?[0-9]*)\s*,\s*([0-1].?[0-9]*)\s*,(.*)$',line)
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,angle,confidence,transcription")
elif withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*(-?[0-1].?[0-9]*)\s*,\s*([0-1].?[0-9]*)\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,angle,confidence")
elif withTranscription:
# print('---------------')
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*(-?[0-1].?[0-9]*)\s*,(.*)$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,angle,transcription")
else:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*(-?[0-1].?[0-9]*)\s*,?\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,angle")
elif withTranscription and withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-1].?[0-9]*)\s*,(.*)$',line)
if m == None :
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-1].?[0-9]*)\s*,(.*)$',line)
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,confidence,transcription")
elif withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-1].?[0-9]*)\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,confidence")
elif withTranscription:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,(.*)$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax,transcription")
else:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,?\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: xmin,ymin,xmax,ymax")
xmin = int(m.group(1))
ymin = int(m.group(2))
xmax = int(m.group(3))
ymax = int(m.group(4))
# print(m.group(5))
angle = float(m.group(5))
if(xmax<xmin):
raise Exception("Xmax value (%s) not valid (Xmax < Xmin)." %(xmax))
if(ymax<ymin):
raise Exception("Ymax value (%s) not valid (Ymax < Ymin)." %(ymax))
points = [ float(m.group(i)) for i in range(1, (numPoints+1) ) ]
if (imWidth>0 and imHeight>0):
validate_point_inside_bounds(xmin,ymin,imWidth,imHeight);
validate_point_inside_bounds(xmax,ymax,imWidth,imHeight);
else:
numPoints = 8;
if withTranscription and withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-1].?[0-9]*)\s*,(.*)$',line)
if m == None :
raise Exception("Format incorrect. Should be: x1,y1,x2,y2,x3,y3,x4,y4,confidence,transcription")
elif withConfidence:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*([0-1].?[0-9]*)\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: x1,y1,x2,y2,x3,y3,x4,y4,confidence")
elif withTranscription:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,(.*)$',line)
if m == None :
raise Exception("Format incorrect. Should be: x1,y1,x2,y2,x3,y3,x4,y4,transcription")
else:
m = re.match(r'^\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*,\s*(-?[0-9]+)\s*$',line)
if m == None :
raise Exception("Format incorrect. Should be: x1,y1,x2,y2,x3,y3,x4,y4")
points = [ float(m.group(i)) for i in range(1, (numPoints+1) ) ]
validate_clockwise_points(points)
if (imWidth>0 and imHeight>0):
validate_point_inside_bounds(points[0],points[1],imWidth,imHeight);
validate_point_inside_bounds(points[2],points[3],imWidth,imHeight);
validate_point_inside_bounds(points[4],points[5],imWidth,imHeight);
validate_point_inside_bounds(points[6],points[7],imWidth,imHeight);
if withConfidence:
try:
confidence = float(m.group(numPoints+1+1))
except ValueError:
raise Exception("Confidence value must be a float")
if withTranscription:
posTranscription = numPoints + 1 + (2 if withConfidence else 1)
transcription = m.group(posTranscription)
m2 = re.match(r'^\s*\"(.*)\"\s*$',transcription)
if m2 != None : #Transcription with double quotes, we extract the value and replace escaped characters
transcription = m2.group(1).replace("\\\\", "\\").replace("\\\"", "\"")
return points,confidence,transcription, angle
def validate_point_inside_bounds(x,y,imWidth,imHeight):
if(x<0 or x>imWidth):
raise Exception("X value (%s) not valid. Image dimensions: (%s,%s)" %(x,imWidth,imHeight))
if(y<0 or y>imHeight):
raise Exception("Y value (%s) not valid. Image dimensions: (%s,%s) Sample: %s Line:%s" %(y,imWidth,imHeight))
def validate_clockwise_points(points):
"""
Validates that the points that the 4 points that dlimite a polygon are in clockwise order.
"""
if len(points) != 8:
raise Exception("Points list not valid." + str(len(points)))
point = [
[int(points[0]) , int(points[1])],
[int(points[2]) , int(points[3])],
[int(points[4]) , int(points[5])],
[int(points[6]) , int(points[7])]
]
edge = [
( point[1][0] - point[0][0])*( point[1][1] + point[0][1]),
( point[2][0] - point[1][0])*( point[2][1] + point[1][1]),
( point[3][0] - point[2][0])*( point[3][1] + point[2][1]),
( point[0][0] - point[3][0])*( point[0][1] + point[3][1])
]
summatory = edge[0] + edge[1] + edge[2] + edge[3];
if summatory>0:
raise Exception("Points are not clockwise. The coordinates of bounding quadrilaterals have to be given in clockwise order. Regarding the correct interpretation of 'clockwise' remember that the image coordinate system used is the standard one, with the image origin at the upper left, the X axis extending to the right and Y axis extending downwards.")
def get_tl_line_values_from_file_contents(content,CRLF=True,LTRB=True,withTranscription=False,withConfidence=False,imWidth=0,imHeight=0,sort_by_confidences=True):
"""
Returns all points, confindences and transcriptions of a file in lists. Valid line formats:
xmin,ymin,xmax,ymax,[confidence],[transcription]
x1,y1,x2,y2,x3,y3,x4,y4,[confidence],[transcription]
"""
pointsList = []
transcriptionsList = []
confidencesList = []
angleList = []
lines = content.split( "\r\n" if CRLF else "\n" )
for line in lines:
line = line.replace("\r","").replace("\n","")
if(line != "") :
points, confidence, transcription, angle = get_tl_line_values(line,LTRB,withTranscription,withConfidence,imWidth,imHeight);
pointsList.append(points)
transcriptionsList.append(transcription)
angleList.append(angle)
confidencesList.append(confidence)
if withConfidence and len(confidencesList)>0 and sort_by_confidences:
import numpy as np
sorted_ind = np.argsort(-np.array(confidencesList))
confidencesList = [confidencesList[i] for i in sorted_ind]
pointsList = [pointsList[i] for i in sorted_ind]
transcriptionsList = [transcriptionsList[i] for i in sorted_ind]
return pointsList,confidencesList,transcriptionsList,angleList
def main_evaluation(p,default_evaluation_params_fn,validate_data_fn,evaluate_method_fn,show_result=True,per_sample=True):
"""
This process validates a method, evaluates it and if it succed generates a ZIP file with a JSON entry for each sample.
Params:
p: Dictionary of parmeters with the GT/submission locations. If None is passed, the parameters send by the system are used.
default_evaluation_params_fn: points to a function that returns a dictionary with the default parameters used for the evaluation
validate_data_fn: points to a method that validates the corrct format of the submission
evaluate_method_fn: points to a function that evaluated the submission and return a Dictionary with the results
"""
if (p == None):
p = dict([s[1:].split('=') for s in sys.argv[1:]])
if(len(sys.argv)<3):
print_help()
evalParams = default_evaluation_params_fn()
if 'p' in p.keys():
evalParams.update( p['p'] if isinstance(p['p'], dict) else json.loads(p['p'][1:-1]) )
resDict={'calculated':True,'Message':'','method':'{}','per_sample':'{}'}
try:
validate_data_fn(p['g'], p['s'], evalParams)
evalData = evaluate_method_fn(p['g'], p['s'], evalParams)
resDict.update(evalData)
except Exception as e:
resDict['Message']= str(e)
resDict['calculated']=False
if 'o' in p:
if not os.path.exists(p['o']):
os.makedirs(p['o'])
resultsOutputname = p['o'] + '/results.zip'
outZip = zipfile.ZipFile(resultsOutputname, mode='w', allowZip64=True)
del resDict['per_sample']
if 'output_items' in resDict.keys():
del resDict['output_items']
outZip.writestr('method.json',json.dumps(resDict))
if not resDict['calculated']:
if show_result:
sys.stderr.write('Error!\n'+ resDict['Message']+'\n\n')
if 'o' in p:
outZip.close()
return resDict
if 'o' in p:
if per_sample == True:
for k,v in evalData['per_sample']:
outZip.writestr( k + '.json',json.dumps(v))
if 'output_items' in evalData.keys():
for k, v in evalData['output_items']:
outZip.writestr( k,v)
outZip.close()
if show_result:
sys.stdout.write("Calculated:\n")
sys.stdout.write(json.dumps(resDict['method']))
print("\n")
return resDict
def main_validation(default_evaluation_params_fn,validate_data_fn):
"""
This process validates a method
Params:
default_evaluation_params_fn: points to a function that returns a dictionary with the default parameters used for the evaluation
validate_data_fn: points to a method that validates the corrct format of the submission
"""
try:
p = dict([s[1:].split('=') for s in sys.argv[1:]])
evalParams = default_evaluation_params_fn()
if 'p' in p.keys():
evalParams.update( p['p'] if isinstance(p['p'], dict) else json.loads(p['p'][1:-1]) )
validate_data_fn(p['g'], p['s'], evalParams)
print('SUCCESS')
sys.exit(0)
except Exception as e:
print(str(e))
sys.exit(101)
================================================
FILE: dataset/TD500/Evaluation_Protocol/script.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import namedtuple
import rrc_evaluation_funcs
import importlib
import numpy as np
import Polygon as plg
from tqdm import tqdm
eval_result_dir = "../../output/Analysis/output_eval"
fid_path = '{}/Eval_TD500.txt'.format(eval_result_dir)
def evaluation_imports():
"""
evaluation_imports: Dictionary ( key = module name , value = alias ) with python modules used in the evaluation.
"""
return {
'Polygon':'plg',
'numpy':'np'
}
def default_evaluation_params():
"""
default_evaluation_params: Default parameters to use for the validation and evaluation.
"""
return {
'IOU_CONSTRAINT' :0.5,
'AREA_PRECISION_CONSTRAINT' :0.5,
'GT_SAMPLE_NAME_2_ID':'gt_img_([0-9]+).txt',
'DET_SAMPLE_NAME_2_ID':'res_img_([0-9]+).txt',
'LTRB':True, #LTRB:2points(left,top,right,bottom) or 4 points(x1,y1,x2,y2,x3,y3,x4,y4)
'CRLF':False, # Lines are delimited by Windows CRLF format
'CONFIDENCES':False, #Detections must include confidence value. AP will be calculated
'PER_SAMPLE_RESULTS':True #Generate per sample results and produce data for visualization
}
def validate_data(gtFilePath, submFilePath,evaluationParams):
"""
Method validate_data: validates that all files in the results folder are correct (have the correct name contents).
Validates also that there are no missing files in the folder.
If some error detected, the method raises the error
"""
gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
#Validate format of GroundTruth
for k in gt:
rrc_evaluation_funcs.validate_lines_in_file(k,gt[k],evaluationParams['CRLF'],evaluationParams['LTRB'],True)
#Validate format of results
for k in subm:
if (k in gt) == False :
raise Exception("The sample %s not present in GT" %k)
rrc_evaluation_funcs.validate_lines_in_file(k,subm[k],evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
def evaluate_method(gtFilePath, submFilePath, evaluationParams):
"""
Method evaluate_method: evaluate method and returns the results
Results. Dictionary with the following values:
- method (required) Global method metrics. Ex: { 'Precision':0.8,'Recall':0.9 }
- samples (optional) Per sample metrics. Ex: {'sample1' : { 'Precision':0.8,'Recall':0.9 } , 'sample2' : { 'Precision':0.8,'Recall':0.9 }
"""
for module,alias in evaluation_imports().items():
globals()[alias] = importlib.import_module(module)
def polygon_from_points(points):
"""
Returns a Polygon object to use with the Polygon2 class from a list of 8 points: x1,y1,x2,y2,x3,y3,x4,y4
"""
resBoxes=np.empty([1,8],dtype='int32')
resBoxes[0,0]=int(points[0])
resBoxes[0,4]=int(points[1])
resBoxes[0,1]=int(points[2])
resBoxes[0,5]=int(points[3])
resBoxes[0,2]=int(points[4])
resBoxes[0,6]=int(points[5])
resBoxes[0,3]=int(points[6])
resBoxes[0,7]=int(points[7])
pointMat = resBoxes[0].reshape([2,4]).T
return plg.Polygon( pointMat)
def rectangle_to_polygon(rect):
resBoxes=np.empty([1,8],dtype='int32')
resBoxes[0,0]=int(rect.xmin)
resBoxes[0,4]=int(rect.ymax)
resBoxes[0,1]=int(rect.xmin)
resBoxes[0,5]=int(rect.ymin)
resBoxes[0,2]=int(rect.xmax)
resBoxes[0,6]=int(rect.ymin)
resBoxes[0,3]=int(rect.xmax)
resBoxes[0,7]=int(rect.ymax)
pointMat = resBoxes[0].reshape([2,4]).T
return plg.Polygon( pointMat)
def rectangle_to_points(rect):
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)]
return points
def get_union(pD,pG):
areaA = pD.area();
areaB = pG.area();
return areaA + areaB - get_intersection(pD, pG);
def get_intersection_over_union(pD,pG):
try:
return get_intersection(pD, pG) / get_union(pD, pG);
except:
return 0
def get_intersection(pD,pG):
pInt = pD & pG
if len(pInt) == 0:
return 0
return pInt.area()
def compute_ap(confList, matchList,numGtCare):
correct = 0
AP = 0
if len(confList)>0:
confList = np.array(confList)
matchList = np.array(matchList)
sorted_ind = np.argsort(-confList)
confList = confList[sorted_ind]
matchList = matchList[sorted_ind]
for n in range(len(confList)):
match = matchList[n]
if match:
correct += 1
AP += float(correct)/(n + 1)
if numGtCare>0:
AP /= numGtCare
return AP
perSampleMetrics = {}
matchedSum = 0
Rectangle = namedtuple('Rectangle', 'xmin ymin xmax ymax')
gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
numGlobalCareGt = 0;
numGlobalCareDet = 0;
arrGlobalConfidences = [];
arrGlobalMatches = [];
with open(fid_path, 'w') as f:
for resFile in tqdm(gt):
gtFile = rrc_evaluation_funcs.decode_utf8(gt[resFile])
recall = 0
precision = 0
hmean = 0
detMatched = 0
iouMat = np.empty([1,1])
gtPols = []
detPols = []
gtPolPoints = []
detPolPoints = []
gtAngle = []
detAngle = []
#Array of Ground Truth Polygons' keys marked as don't Care
gtDontCarePolsNum = []
#Array of Detected Polygons' matched with a don't Care GT
detDontCarePolsNum = []
pairs = []
detMatchedNums = []
arrSampleConfidences = [];
arrSampleMatch = [];
sampleAP = 0;
evaluationLog = ""
pointsList,_,transcriptionsList,angleList = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(gtFile,evaluationParams['CRLF'],evaluationParams['LTRB'],True,False)
for n in range(len(pointsList)):
points = pointsList[n]
angle = angleList[n]
transcription = transcriptionsList[n]
dontCare = transcription == "###"
if evaluationParams['LTRB']:
gtRect = Rectangle(*points)
gtPol = rectangle_to_polygon(gtRect)
else:
gtPol = polygon_from_points(points)
gtPols.append(gtPol)
gtPolPoints.append(points)
gtAngle.append(angle)
if dontCare:
gtDontCarePolsNum.append(len(gtPols)-1)
evaluationLog += "GT polygons: " + str(len(gtPols)) + (" (" + str(len(gtDontCarePolsNum)) + " don't care)\n" if len(gtDontCarePolsNum)>0 else "\n")
if resFile in subm:
detFile = rrc_evaluation_funcs.decode_utf8(subm[resFile])
pointsList,confidencesList,_,angleList = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(detFile,evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
for n in range(len(pointsList)):
points = pointsList[n]
angle = angleList[n]
if evaluationParams['LTRB']:
detRect = Rectangle(*points)
detPol = rectangle_to_polygon(detRect)
else:
detPol = polygon_from_points(points)
detPols.append(detPol)
detPolPoints.append(points)
detAngle.append(angle)
if len(gtDontCarePolsNum)>0 :
for dontCarePol in gtDontCarePolsNum:
dontCarePol = gtPols[dontCarePol]
intersected_area = get_intersection(dontCarePol,detPol)
pdDimensions = detPol.area()
precision = 0 if pdDimensions == 0 else intersected_area / pdDimensions
if (precision > evaluationParams['AREA_PRECISION_CONSTRAINT'] ):
detDontCarePolsNum.append(len(detPols)-1)
break
evaluationLog += "DET polygons: " + str(len(detPols)) + (" (" + str(len(detDontCarePolsNum)) + " don't care)\n" if len(detDontCarePolsNum)>0 else "\n")
if len(gtPols)>0 and len(detPols)>0:
#Calculate IoU and precision matrixs
outputShape=[len(gtPols),len(detPols)]
iouMat = np.empty(outputShape)
gtRectMat = np.zeros(len(gtPols),np.int8)
detRectMat = np.zeros(len(detPols),np.int8)
for gtNum in range(len(gtPols)):
for detNum in range(len(detPols)):
pG = gtPols[gtNum]
pD = detPols[detNum]
iouMat[gtNum,detNum] = get_intersection_over_union(pD,pG)
for gtNum in range(len(gtPols)):
for detNum in range(len(detPols)):
if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and gtNum not in gtDontCarePolsNum and detNum not in detDontCarePolsNum :
if iouMat[gtNum,detNum]>evaluationParams['IOU_CONSTRAINT'] and abs(gtAngle[gtNum]-detAngle[detNum]) < np.pi / 8:
gtRectMat[gtNum] = 1
detRectMat[detNum] = 1
detMatched += 1
pairs.append({'gt':gtNum,'det':detNum})
detMatchedNums.append(detNum)
evaluationLog += "Match GT #" + str(gtNum) + " with Det #" + str(detNum) + "\n"
if evaluationParams['CONFIDENCES']:
for detNum in range(len(detPols)):
if detNum not in detDontCarePolsNum :
#we exclude the don't care detections
match = detNum in detMatchedNums
arrSampleConfidences.append(confidencesList[detNum])
arrSampleMatch.append(match)
arrGlobalConfidences.append(confidencesList[detNum]);
arrGlobalMatches.append(match);
numGtCare = (len(gtPols) - len(gtDontCarePolsNum))
numDetCare = (len(detPols) - len(detDontCarePolsNum))
if numGtCare == 0:
recall = float(1)
precision = float(0) if numDetCare >0 else float(1)
sampleAP = precision
else:
recall = float(detMatched) / numGtCare
precision = 0 if numDetCare==0 else float(detMatched) / numDetCare
if evaluationParams['CONFIDENCES'] and evaluationParams['PER_SAMPLE_RESULTS']:
sampleAP = compute_ap(arrSampleConfidences, arrSampleMatch, numGtCare )
hmean = 0 if (precision + recall)==0 else 2.0 * precision * recall / (precision + recall)
# write result
f.write('%s :: Precision=%.4f - Recall=%.4f\n' % ("img_"+str(resFile) + ".txt", recall, precision))
matchedSum += detMatched
numGlobalCareGt += numGtCare
numGlobalCareDet += numDetCare
if evaluationParams['PER_SAMPLE_RESULTS']:
perSampleMetrics[resFile] = {
'precision':precision,
'recall':recall,
'hmean':hmean,
'pairs':pairs,
'AP':sampleAP,
'iouMat':[] if len(detPols)>100 else iouMat.tolist(),
'gtPolPoints':gtPolPoints,
'detPolPoints':detPolPoints,
'gtDontCare':gtDontCarePolsNum,
'detDontCare':detDontCarePolsNum,
'evaluationParams': evaluationParams,
'evaluationLog': evaluationLog
}
# Compute MAP and MAR
AP = 0
if evaluationParams['CONFIDENCES']:
AP = compute_ap(arrGlobalConfidences, arrGlobalMatches, numGlobalCareGt)
methodRecall = 0 if numGlobalCareGt == 0 else float(matchedSum)/numGlobalCareGt
methodPrecision = 0 if numGlobalCareDet == 0 else float(matchedSum)/numGlobalCareDet
methodHmean = 0 if methodRecall + methodPrecision==0 else 2* methodRecall * methodPrecision / (methodRecall + methodPrecision)
methodMetrics = {'precision':methodPrecision, 'recall':methodRecall,'hmean': methodHmean, 'AP': AP}
resDict = {'calculated':True,'Message':'','method': methodMetrics,'per_sample': perSampleMetrics}
f.write('ALL :: AP=%.4f - Precision=%.4f - Recall=%.4f - Fscore=%.4f'
% (AP, methodPrecision, methodRecall, methodHmean))
return resDict;
if __name__=='__main__':
rrc_evaluation_funcs.main_evaluation(None,default_evaluation_params,validate_data,evaluate_method)
================================================
FILE: dataset/TD500/Evaluation_Protocol/script075.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import namedtuple
import rrc_evaluation_funcs
import importlib
def evaluation_imports():
"""
evaluation_imports: Dictionary ( key = module name , value = alias ) with python modules used in the evaluation.
"""
return {
'Polygon':'plg',
'numpy':'np'
}
def default_evaluation_params():
"""
default_evaluation_params: Default parameters to use for the validation and evaluation.
"""
return {
'IOU_CONSTRAINT' :0.75,
'AREA_PRECISION_CONSTRAINT' :0.5,
'GT_SAMPLE_NAME_2_ID':'gt_img_([0-9]+).txt',
'DET_SAMPLE_NAME_2_ID':'res_img_([0-9]+).txt',
'LTRB':False, #LTRB:2points(left,top,right,bottom) or 4 points(x1,y1,x2,y2,x3,y3,x4,y4)
'CRLF':False, # Lines are delimited by Windows CRLF format
'CONFIDENCES':False, #Detections must include confidence value. AP will be calculated
'PER_SAMPLE_RESULTS':True #Generate per sample results and produce data for visualization
}
def validate_data(gtFilePath, submFilePath,evaluationParams):
"""
Method validate_data: validates that all files in the results folder are correct (have the correct name contents).
Validates also that there are no missing files in the folder.
If some error detected, the method raises the error
"""
gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
#Validate format of GroundTruth
for k in gt:
rrc_evaluation_funcs.validate_lines_in_file(k,gt[k],evaluationParams['CRLF'],evaluationParams['LTRB'],True)
#Validate format of results
for k in subm:
if (k in gt) == False :
raise Exception("The sample %s not present in GT" %k)
rrc_evaluation_funcs.validate_lines_in_file(k,subm[k],evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
def evaluate_method(gtFilePath, submFilePath, evaluationParams):
"""
Method evaluate_method: evaluate method and returns the results
Results. Dictionary with the following values:
- method (required) Global method metrics. Ex: { 'Precision':0.8,'Recall':0.9 }
- samples (optional) Per sample metrics. Ex: {'sample1' : { 'Precision':0.8,'Recall':0.9 } , 'sample2' : { 'Precision':0.8,'Recall':0.9 }
"""
for module,alias in evaluation_imports().iteritems():
globals()[alias] = importlib.import_module(module)
def polygon_from_points(points):
"""
Returns a Polygon object to use with the Polygon2 class from a list of 8 points: x1,y1,x2,y2,x3,y3,x4,y4
"""
resBoxes=np.empty([1,8],dtype='int32')
resBoxes[0,0]=int(points[0])
resBoxes[0,4]=int(points[1])
resBoxes[0,1]=int(points[2])
resBoxes[0,5]=int(points[3])
resBoxes[0,2]=int(points[4])
resBoxes[0,6]=int(points[5])
resBoxes[0,3]=int(points[6])
resBoxes[0,7]=int(points[7])
pointMat = resBoxes[0].reshape([2,4]).T
return plg.Polygon( pointMat)
def rectangle_to_polygon(rect):
resBoxes=np.empty([1,8],dtype='int32')
resBoxes[0,0]=int(rect.xmin)
resBoxes[0,4]=int(rect.ymax)
resBoxes[0,1]=int(rect.xmin)
resBoxes[0,5]=int(rect.ymin)
resBoxes[0,2]=int(rect.xmax)
resBoxes[0,6]=int(rect.ymin)
resBoxes[0,3]=int(rect.xmax)
resBoxes[0,7]=int(rect.ymax)
pointMat = resBoxes[0].reshape([2,4]).T
return plg.Polygon( pointMat)
def rectangle_to_points(rect):
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)]
return points
def get_union(pD,pG):
areaA = pD.area();
areaB = pG.area();
return areaA + areaB - get_intersection(pD, pG);
def get_intersection_over_union(pD,pG):
try:
return get_intersection(pD, pG) / get_union(pD, pG);
except:
return 0
def get_intersection(pD,pG):
pInt = pD & pG
if len(pInt) == 0:
return 0
return pInt.area()
def compute_ap(confList, matchList,numGtCare):
correct = 0
AP = 0
if len(confList)>0:
confList = np.array(confList)
matchList = np.array(matchList)
sorted_ind = np.argsort(-confList)
confList = confList[sorted_ind]
matchList = matchList[sorted_ind]
for n in range(len(confList)):
match = matchList[n]
if match:
correct += 1
AP += float(correct)/(n + 1)
if numGtCare>0:
AP /= numGtCare
return AP
perSampleMetrics = {}
matchedSum = 0
Rectangle = namedtuple('Rectangle', 'xmin ymin xmax ymax')
gt = rrc_evaluation_funcs.load_zip_file(gtFilePath,evaluationParams['GT_SAMPLE_NAME_2_ID'])
subm = rrc_evaluation_funcs.load_zip_file(submFilePath,evaluationParams['DET_SAMPLE_NAME_2_ID'],True)
numGlobalCareGt = 0;
numGlobalCareDet = 0;
arrGlobalConfidences = [];
arrGlobalMatches = [];
for resFile in gt:
gtFile = rrc_evaluation_funcs.decode_utf8(gt[resFile])
recall = 0
precision = 0
hmean = 0
detMatched = 0
iouMat = np.empty([1,1])
gtPols = []
detPols = []
gtPolPoints = []
detPolPoints = []
#Array of Ground Truth Polygons' keys marked as don't Care
gtDontCarePolsNum = []
#Array of Detected Polygons' matched with a don't Care GT
detDontCarePolsNum = []
pairs = []
detMatchedNums = []
arrSampleConfidences = [];
arrSampleMatch = [];
sampleAP = 0;
evaluationLog = ""
pointsList,_,transcriptionsList = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(gtFile,evaluationParams['CRLF'],evaluationParams['LTRB'],True,False)
for n in range(len(pointsList)):
points = pointsList[n]
transcription = transcriptionsList[n]
dontCare = transcription == "###"
if evaluationParams['LTRB']:
gtRect = Rectangle(*points)
gtPol = rectangle_to_polygon(gtRect)
else:
gtPol = polygon_from_points(points)
gtPols.append(gtPol)
gtPolPoints.append(points)
if dontCare:
gtDontCarePolsNum.append( len(gtPols)-1 )
evaluationLog += "GT polygons: " + str(len(gtPols)) + (" (" + str(len(gtDontCarePolsNum)) + " don't care)\n" if len(gtDontCarePolsNum)>0 else "\n")
if resFile in subm:
detFile = rrc_evaluation_funcs.decode_utf8(subm[resFile])
pointsList,confidencesList,_ = rrc_evaluation_funcs.get_tl_line_values_from_file_contents(detFile,evaluationParams['CRLF'],evaluationParams['LTRB'],False,evaluationParams['CONFIDENCES'])
for n in range(len(pointsList)):
points = pointsList[n]
if evaluationParams['LTRB']:
detRect = Rectangle(*points)
detPol = rectangle_to_polygon(detRect)
else:
detPol = polygon_from_points(points)
detPols.append(detPol)
detPolPoints.append(points)
if len(gtDontCarePolsNum)>0 :
for dontCarePol in gtDontCarePolsNum:
dontCarePol = gtPols[dontCarePol]
intersected_area = get_intersection(dontCarePol,detPol)
pdDimensions = detPol.area()
precision = 0 if pdDimensions == 0 else intersected_area / pdDimensions
if (precision > evaluationParams['AREA_PRECISION_CONSTRAINT'] ):
detDontCarePolsNum.append( len(detPols)-1 )
break
evaluationLog += "DET polygons: " + str(len(detPols)) + (" (" + str(len(detDontCarePolsNum)) + " don't care)\n" if len(detDontCarePolsNum)>0 else "\n")
if len(gtPols)>0 and len(detPols)>0:
#Calculate IoU and precision matrixs
outputShape=[len(gtPols),len(detPols)]
iouMat = np.empty(outputShape)
gtRectMat = np.zeros(len(gtPols),np.int8)
detRectMat = np.zeros(len(detPols),np.int8)
for gtNum in range(len(gtPols)):
for detNum in range(len(detPols)):
pG = gtPols[gtNum]
pD = detPols[detNum]
iouMat[gtNum,detNum] = get_intersection_over_union(pD,pG)
for gtNum in range(len(gtPols)):
for detNum in range(len(detPols)):
if gtRectMat[gtNum] == 0 and detRectMat[detNum] == 0 and gtNum not in gtDontCarePolsNum and detNum not in detDontCarePolsNum :
if iouMat[gtNum,detNum]>evaluationParams['IOU_CONSTRAINT']:
gtRectMat[gtNum] = 1
detRectMat[detNum] = 1
detMatched += 1
pairs.append({'gt':gtNum,'det':detNum})
detMatchedNums.append(detNum)
evaluationLog += "Match GT #" + str(gtNum) + " with Det #" + str(detNum) + "\n"
if evaluationParams['CONFIDENCES']:
for detNum in range(len(detPols)):
if detNum not in detDontCarePolsNum :
#we exclude the don't care detections
match = detNum in detMatchedNums
arrSampleConfidences.append(confidencesList[detNum])
arrSampleMatch.append(match)
arrGlobalConfidences.append(confidencesList[detNum]);
arrGlobalMatches.append(match);
numGtCare = (len(gtPols) - len(gtDontCarePolsNum))
numDetCare = (len(detPols) - len(detDontCarePolsNum))
if numGtCare == 0:
recall = float(1)
precision = float(0) if numDetCare >0 else float(1)
sampleAP = precision
else:
recall = float(detMatched) / numGtCare
precision = 0 if numDetCare==0 else float(detMatched) / numDetCare
if evaluationParams['CONFIDENCES'] and evaluationParams['PER_SAMPLE_RESULTS']:
sampleAP = compute_ap(arrSampleConfidences, arrSampleMatch, numGtCare )
hmean = 0 if (precision + recall)==0 else 2.0 * precision * recall / (precision + recall)
matchedSum += detMatched
numGlobalCareGt += numGtCare
numGlobalCareDet += numDetCare
if evaluationParams['PER_SAMPLE_RESULTS']:
perSampleMetrics[resFile] = {
'precision':precision,
'recall':recall,
'hmean':hmean,
'pairs':pairs,
'AP':sampleAP,
'iouMat':[] if len(detPols)>100 else iouMat.tolist(),
'gtPolPoints':gtPolPoints,
'detPolPoints':detPolPoints,
'gtDontCare':gtDontCarePolsNum,
'detDontCare':detDontCarePolsNum,
'evaluationParams': evaluationParams,
'evaluationLog': evaluationLog
}
# Compute MAP and MAR
AP = 0
if evaluationParams['CONFIDENCES']:
AP = compute_ap(arrGlobalConfidences, arrGlobalMatches, numGlobalCareGt)
methodRecall = 0 if numGlobalCareGt == 0 else float(matchedSum)/numGlobalCareGt
methodPrecision = 0 if numGlobalCareDet == 0 else float(matchedSum)/numGlobalCareDet
methodHmean = 0 if methodRecall + methodPrecision==0 else 2* methodRecall * methodPrecision / (methodRecall + methodPrecision)
methodMetrics = {'precision':methodPrecision, 'recall':methodRecall,'hmean': methodHmean, 'AP': AP }
resDict = {'calculated':True,'Message':'','method': methodMetrics,'per_sample': perSampleMetrics}
return resDict;
if __name__=='__main__':
rrc_evaluation_funcs.main_evaluation(None,default_evaluation_params,validate_data,evaluate_method)
================================================
FILE: dataset/TD500/batch_eval.sh
================================================
for ((i=490000;i<=510000;i+=1000)); do echo $i;sh eval.sh $1/submit-${i}_1.5|grep Calc;done
================================================
FILE: dataset/TD500/eval.sh
================================================
cd dataset/TD500
rm submit.zip
cp $1/*.txt submit
cd submit/;zip -r submit.zip * &> ../log.txt ; mv submit.zip ../; cd ../
rm log.txt
python Evaluation_Protocol/script.py -g=gt.zip -s=submit.zip
================================================
FILE: dataset/TD500/submit/res_img_1.txt
================================================
637,679,749,723,0.08314135922921725
================================================
FILE: dataset/TD500_Text.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = '古溪'
import re
import os
import numpy as np
from util import strs
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
from util.io import read_lines
from util.misc import norm2
class TD500Text(TextDataset):
def __init__(self, data_root, is_training=True, ignore_list=None, load_memory=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
self.image_root = os.path.join(data_root, 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root,'Train' if is_training else 'Test')
self.image_list = os.listdir(self.image_root)
p = re.compile('.rar|.txt')
self.image_list = [x for x in self.image_list if not p.findall(x)]
p = re.compile('(.jpg|.JPG|.PNG|.JPEG)')
self.annotation_list = ['{}'.format(p.sub("", img_name)) for img_name in self.image_list]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = read_lines(gt_path+".txt")
polygons = []
for line in lines:
line = strs.remove_all(line.strip('\ufeff'), '\xef\xbb\xbf')
gt = line.split(',')
x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, gt[:8]))
xx = [x1, x2, x3, x4]
yy = [y1, y2, y3, y4]
label = gt[-1].strip().replace("###", "#")
pts = np.stack([xx, yy]).T.astype(np.int32)
# d1 = norm2(pts[0] - pts[1])
# d2 = norm2(pts[1] - pts[2])
# d3 = norm2(pts[2] - pts[3])
# d4 = norm2(pts[3] - pts[0])
# if min([d1, d2, d3, d4]) < 2:
# continue
polygons.append(TextInstance(pts, 'c', label))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
try:
# Read annotation
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
polygons = self.parse_txt(annotation_path)
except:
polygons = None
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
# image_id = self.image_list[item]
# image_path = os.path.join(self.image_root, image_id)
#
# # Read image data
# image = pil_load_img(image_path)
#
# try:
# # Read annotation
# annotation_id = self.annotation_list[item]
# annotation_path = os.path.join(self.annotation_root, annotation_id)
# polygons = self.parse_txt(annotation_path)
# except:
# polygons = None
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
import os
import cv2
from util.augmentation import Augmentation
from util import canvas as cav
import time
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = TD500Text(
data_root='../data/TD500',
is_training=False,
transform=transform
)
# img, train_mask, tr_mask, tcl_mask, radius_map, sin_map, cos_map, meta = trainset[944]
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask = trainset[idx]
img, train_mask, tr_mask = map(lambda x: x.cpu().numpy(), (img, train_mask, tr_mask))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
print(idx, img.shape)
for i in range(tr_mask.shape[2]):
cv2.imshow("tr_mask_{}".format(i),
cav.heatmap(np.array(tr_mask[:, :, i] * 255 / np.max(tr_mask[:, :, i]), dtype=np.uint8)))
cv2.imshow('imgs', img)
cv2.waitKey(0)
================================================
FILE: dataset/Total_Text.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import warnings
warnings.filterwarnings("ignore")
import os
import re
import numpy as np
import scipy.io as io
from util import strs
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
import cv2
from util import io as libio
class TotalText(TextDataset):
def __init__(self, data_root, ignore_list=None, is_training=True, load_memory=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.load_memory = load_memory
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.image_root = os.path.join(data_root, 'Images', 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root, 'gt', 'Train' if is_training else 'Test')
self.image_list = os.listdir(self.image_root)
self.image_list = list(filter(lambda img: img.replace('.jpg', '') not in ignore_list, self.image_list))
self.annotation_list = ['poly_gt_{}'.format(img_name.replace('.jpg', '')) for img_name in self.image_list]
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_mat(mat_path):
"""
.mat file parser
:param mat_path: (str), mat file path
:return: (list), TextInstance
"""
annot = io.loadmat(mat_path + ".mat")
polygons = []
for cell in annot['polygt']:
x = cell[1][0]
y = cell[3][0]
text = cell[4][0] if len(cell[4]) > 0 else '#'
ori = cell[5][0] if len(cell[5]) > 0 else 'c'
if len(x) < 4: # too few points
continue
pts = np.stack([x, y]).T.astype(np.int32)
polygons.append(TextInstance(pts, ori, text))
return polygons
@staticmethod
def parse_carve_txt(gt_path):
"""
.mat file parser
:param gt_path: (str), mat file path
:return: (list), TextInstance
"""
lines = libio.read_lines(gt_path + ".txt")
polygons = []
for line in lines:
line = strs.remove_all(line, '\xef\xbb\xbf')
gt = line.split(',')
xx = gt[0].replace("x: ", "").replace("[[", "").replace("]]", "").lstrip().rstrip()
yy = gt[1].replace("y: ", "").replace("[[", "").replace("]]", "").lstrip().rstrip()
try:
xx = [int(x) for x in re.split(r" *", xx)]
yy = [int(y) for y in re.split(r" *", yy)]
except:
xx = [int(x) for x in re.split(r" +", xx)]
yy = [int(y) for y in re.split(r" +", yy)]
if len(xx) < 4 or len(yy) < 4: # too few points
continue
text = gt[-1].split('\'')[1]
try:
ori = gt[-2].split('\'')[1]
except:
ori = 'c'
pts = np.stack([xx, yy]).T.astype(np.int32)
polygons.append(TextInstance(pts, ori, text))
# print(polygon)
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
# Read annotation
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
polygons = self.parse_mat(annotation_path)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
# image_id = self.image_list[item]
# image_path = os.path.join(self.image_root, image_id)
#
# # Read image data
# image = pil_load_img(image_path)
#
# # Read annotation
# annotation_id = self.annotation_list[item]
# annotation_path = os.path.join(self.annotation_root, annotation_id)
# polygons = self.parse_mat(annotation_path)
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
import time
from util.augmentation import Augmentation
from util import canvas as cav
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
# transform = BaseTransformNresize(
# mean=means, std=stds
# )
trainset = TotalText(
data_root='../data/total-text-mat',
ignore_list=None,
is_training=True,
transform=transform
)
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[idx]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags\
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
distance_map = cav.heatmap(np.array(distance_field * 255 / np.max(distance_field), dtype=np.uint8))
cv2.imshow("distance_map", distance_map)
cv2.waitKey(0)
direction_map = cav.heatmap(np.array(direction_field[0] * 255 / np.max(direction_field[0]), dtype=np.uint8))
cv2.imshow("direction_field", direction_map)
cv2.waitKey(0)
from util.vis_flux import vis_direction_field
vis_direction_field(direction_field)
weight_map = cav.heatmap(np.array(weight_matrix * 255 / np.max(weight_matrix), dtype=np.uint8))
cv2.imshow("weight_matrix", weight_map)
# cv2.waitKey(0)
boundary_point = ctrl_points[np.where(ignore_tags!=0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j==0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j==1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j==0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j==1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
# from util.misc import split_edge_seqence
# from cfglib.config import config as cfg
#
# ret, labels = cv2.connectedComponents(np.array(distance_field >0.35, dtype=np.uint8), connectivity=4)
# for idx in range(1, ret):
# text_mask = labels == idx
# ist_id = int(np.sum(text_mask*tr_mask)/np.sum(text_mask))-1
# contours, _ = cv2.findContours(text_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# epsilon = 0.007 * cv2.arcLength(contours[0], True)
# approx = cv2.approxPolyDP(contours[0], epsilon, True).reshape((-1, 2))
#
# control_points = split_edge_seqence(approx, cfg.num_points)
# control_points = np.array(control_points[:cfg.num_points, :]).astype(np.int32)
#
# cv2.drawContours(img, [ctrl_points[ist_id].astype(np.int32)], -1, (0, 255, 0), 1)
# cv2.drawContours(img, [control_points.astype(np.int32)], -1, (0, 0, 255), 1)
# for j, pp in enumerate(control_points):
# if j == 0:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
# elif j == 1:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
# else:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 0), -1)
#
# cv2.imshow('imgs', img)
# cv2.waitKey(0)
================================================
FILE: dataset/Total_Text_New.py
================================================
# -*- coding: utf-8 -*-
__author__ = "S.X.Zhang"
import warnings
warnings.filterwarnings("ignore")
import os
import cv2
import numpy as np
import scipy.io as io
from dataset.data_util import pil_load_img
from dataset.dataload import TextDataset, TextInstance
class TotalText_New(TextDataset):
def __init__(self, data_root, ignore_list=None, is_training=True,
load_memory=False, pix_mask=False, transform=None):
super().__init__(transform, is_training)
self.data_root = data_root
self.is_training = is_training
self.pix_mask = pix_mask
self.load_memory = load_memory
if ignore_list:
with open(ignore_list) as f:
ignore_list = f.readlines()
ignore_list = [line.strip() for line in ignore_list]
else:
ignore_list = []
self.image_root = os.path.join(data_root, 'Images', 'Train' if is_training else 'Test')
self.annotation_root = os.path.join(data_root, 'gt/Polygon', 'Train' if is_training else 'Test')
self.image_list = os.listdir(self.image_root)
self.image_list = list(filter(lambda img: img.replace('.jpg', '') not in ignore_list, self.image_list))
self.annotation_list = ['gt_{}'.format(img_name.replace('.jpg', '')) for img_name in self.image_list]
if self.pix_mask:
self.mask_root = os.path.join(data_root, 'gt_pixel', 'Train' if is_training else 'Test')
self.mask_list = os.listdir(self.mask_root)
self.mask_list = list(filter(lambda img: img.replace('.jpg', '') not in ignore_list, self.mask_list))
if self.load_memory:
self.datas = list()
for item in range(len(self.image_list)):
self.datas.append(self.load_img_gt(item))
@staticmethod
def parse_mat(mat_path):
"""
.mat file parser
:param mat_path: (str), mat file path
:return: (list), TextInstance
"""
annot = io.loadmat(mat_path + ".mat")
polygons = []
for cell in annot['gt']:
x = cell[1][0]
y = cell[3][0]
text = cell[4][0] if len(cell[4]) > 0 else '#'
ori = cell[5][0] if len(cell[5]) > 0 else 'c'
pts = np.stack([x, y]).T.astype(np.int32)
polygons.append(TextInstance(pts, ori, text))
return polygons
def load_img_gt(self, item):
image_id = self.image_list[item]
image_path = os.path.join(self.image_root, image_id)
# Read image data
image = pil_load_img(image_path)
# Read annotation
annotation_id = self.annotation_list[item]
annotation_path = os.path.join(self.annotation_root, annotation_id)
polygons = self.parse_mat(annotation_path)
data = dict()
data["image"] = image
data["polygons"] = polygons
data["image_id"] = image_id
data["image_path"] = image_path
return data
def __getitem__(self, item):
# image_id = self.image_list[item]
# image_path = os.path.join(self.image_root, image_id)
#
# # Read image data
# image = pil_load_img(image_path)
#
# # Read annotation
# annotation_id = self.annotation_list[item]
# annotation_path = os.path.join(self.annotation_root, annotation_id)
# polygons = self.parse_mat(annotation_path)
if self.load_memory:
data = self.datas[item]
else:
data = self.load_img_gt(item)
if self.is_training:
return self.get_training_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
else:
return self.get_test_data(data["image"], data["polygons"],
image_id=data["image_id"], image_path=data["image_path"])
def __len__(self):
return len(self.image_list)
if __name__ == '__main__':
import time
from util.augmentation import Augmentation
from util import canvas as cav
means = (0.485, 0.456, 0.406)
stds = (0.229, 0.224, 0.225)
transform = Augmentation(
size=640, mean=means, std=stds
)
trainset = TotalText_New(
data_root='../data/Total-Text',
ignore_list=None,
is_training=True,
transform=transform
)
for idx in range(0, len(trainset)):
t0 = time.time()
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags = trainset[idx]
img, train_mask, tr_mask, distance_field, \
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags\
= map(lambda x: x.cpu().numpy(),
(img, train_mask, tr_mask, distance_field,
direction_field, weight_matrix, ctrl_points, proposal_points, ignore_tags))
img = img.transpose(1, 2, 0)
img = ((img * stds + means) * 255).astype(np.uint8)
distance_map = cav.heatmap(np.array(distance_field * 255 / np.max(distance_field), dtype=np.uint8))
cv2.imshow("distance_map", distance_map)
cv2.waitKey(0)
direction_map = cav.heatmap(np.array(direction_field[0] * 255 / np.max(direction_field[0]), dtype=np.uint8))
cv2.imshow("direction_field", direction_map)
cv2.waitKey(0)
#
from util.vis_flux import vis_direction_field
vis_direction_field(direction_field)
weight_map = cav.heatmap(np.array(weight_matrix * 255 / np.max(weight_matrix), dtype=np.uint8))
cv2.imshow("weight_matrix", weight_map)
cv2.waitKey(0)
boundary_point = ctrl_points[np.where(ignore_tags!=0)[0]]
for i, bpts in enumerate(boundary_point):
cv2.drawContours(img, [bpts.astype(np.int32)], -1, (0, 255, 0), 1)
for j, pp in enumerate(bpts):
if j==0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j==1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
ppts = proposal_points[i]
cv2.drawContours(img, [ppts.astype(np.int32)], -1, (0, 0, 255), 1)
for j, pp in enumerate(ppts):
if j==0:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
elif j==1:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
else:
cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 0, 255), -1)
cv2.imshow('imgs', img)
cv2.waitKey(0)
# from util.misc import split_edge_seqence
# from cfglib.config import config as cfg
#
# ret, labels = cv2.connectedComponents(np.array(distance_field >0.35, dtype=np.uint8), connectivity=4)
# for idx in range(1, ret):
# text_mask = labels == idx
# ist_id = int(np.sum(text_mask*tr_mask)/np.sum(text_mask))-1
# contours, _ = cv2.findContours(text_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# epsilon = 0.007 * cv2.arcLength(contours[0], True)
# approx = cv2.approxPolyDP(contours[0], epsilon, True).reshape((-1, 2))
#
# pts_num = approx.shape[0]
# e_index = [(i, (i + 1) % pts_num) for i in range(pts_num)]
# control_points = split_edge_seqence(approx, e_index, cfg.num_points)
# control_points = np.array(control_points[:cfg.num_points, :]).astype(np.int32)
#
# cv2.drawContours(img, [ctrl_points[ist_id].astype(np.int32)], -1, (0, 255, 0), 1)
# cv2.drawContours(img, [control_points.astype(np.int32)], -1, (0, 0, 255), 1)
# for j, pp in enumerate(control_points):
# if j == 0:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (255, 0, 255), -1)
# elif j == 1:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 255), -1)
# else:
# cv2.circle(img, (int(pp[0]), int(pp[1])), 2, (0, 255, 0), -1)
#
# cv2.imshow('imgs', img)
# cv2.waitKey(0)
================================================
FILE: dataset/__init__.py
================================================
from .dataload import *
from .Total_Text import TotalText
from .synth_text import SynthText
from .ctw1500_text import Ctw1500Text
from .Icdar15_Text import Icdar15Text
from .Icdar17_Text import Mlt2017Text
from .TD500_Text import TD500Text
from .Icdar19ArT_Json import ArtTextJson
from .Icdar19ArT_Text import ArtText
from .Icdar19_Text import Mlt2019Text
from .CTW1500_Text_New import Ctw1500Text_New
from .Total_Text_New import TotalText_New
from .Icdar19LSVT_Json import LsvtTextJson
from .deploy import DeployDataset
================================================
FILE: dataset/ctw1500/Evaluation_Protocol/ctw1500_eval.py
================================================
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import os, shutil, sys
from voc_eval_polygon import voc_eval_polygon
from collections import Counter
import numpy as np
import argparse
parser = argparse.ArgumentParser()
# basic opts
parser.add_argument('exp_name', type=str, help='Model output directory')
args = parser.parse_args()
input_dir = 'output/{}'.format(args.exp_name)
eval_result_dir = "output/Analysis/output_eval"
anno_path = 'data/ctw1500/test/test_label_curve.txt'
imagesetfile = 'data/ctw1500/test/test.txt'
outputstr = "dataset/ctw1500/Evaluation_sort/detections_text"
# score_thresh_list=[0.2, 0.3, 0.4, 0.5, 0.6, 0.62, 0.65, 0.7, 0.75, 0.8, 0.9]
score_thresh_list = [0.5]
files = os.listdir(input_dir)
files.sort()
for iscore in score_thresh_list:
fpath = outputstr + str(iscore) + '.txt'
with open(fpath, "w") as f1:
for ix, filename in enumerate(files):
imagename = filename[:-4]
with open(os.path.join(input_dir, filename), "r") as f:
lines = f.readlines()
for line in lines:
box = line.strip().split(",")
assert (len(box) % 2 == 0), 'mismatch xy'
out_str = "{} {}".format(str(int(imagename[:]) - 1001), 0.999)
for i in box:
out_str = out_str + ' ' + str(i)
f1.writelines(out_str + '\n')
rec, prec, AP, FP, TP, image_ids, num_gt = voc_eval_polygon(fpath, anno_path, imagesetfile, 'text', ovthresh=0.5)
fid_path = '{}/Eval_ctw1500_{}.txt'.format(eval_result_dir, iscore)
F = lambda x, y: 2 * x * y * 1.0 / (x + y)
img_dict = dict(Counter(image_ids))
with open(fid_path, 'w') as f:
count = 0
for k, v in zip(img_dict.keys(), img_dict.values()):
fp = np.sum(FP[count:count+v])
tp = np.sum(TP[count:count+v])
count += v
recall = tp / float(num_gt[k])
precision = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)
f.write('%s :: Precision=%.4f - Recall=%.4f\n' % (str(int(k)+1001)+".txt", recall, precision))
Recall = rec[-1]
Precision = prec[-1]
F_score = F(Recall, Precision)
f.write('ALL :: AP=%.4f - Precision=%.4f - Recall=%.4f - Fscore=%.4f' % (AP, Precision, Recall, F_score))
print('AP: {:.4f}, recall: {:.4f}, pred: {:.4f}, '
'FM: {:.4f}\n'.format(AP, Recall, Precision, F_score))
================================================
FILE: dataset/ctw1500/Evaluation_Protocol/voc_eval_polygon.py
================================================
# --------------------------------------------------------
# Fast/er R-CNN
# Licensed under The MIT License [see LICENSE for details]
# Written by Bharath Hariharan
# Modified by yl
# --------------------------------------------------------
import os
try:
import cPickle
except:
import _pickle as cPickle
import numpy as np
from shapely.geometry import *
from tqdm import tqdm
def parse_rec_txt(filename):
with open(filename.strip(),'r') as f:
gts = f.readlines()
objects = []
for obj in gts:
cors = obj.strip().split(',')
obj_struct = {}
obj_struct['name'] = 'text'
obj_struct['difficult'] = 0
obj_struct['bbox'] = [int(cors[0]),
int(cors[1]),
int(cors[2]),
int(cors[3])]
objects.append(obj_struct)
return objects
def curve_parse_rec_txt(filename):
with open(filename.strip(),'r') as f:
gts = f.readlines()
objects = []
for obj in gts:
cors = obj.strip().split(',')
obj_struct = {}
obj_struct['name'] = 'text'
obj_struct['difficult'] = 0
obj_struct['bbox'] = [int(cors[0]), int(cors[1]),int(cors[2]),int(cors[3]),
int(cors[4]), int(cors[5]),int(cors[6]),int(cors[7]),
int(cors[8]), int(cors[9]),int(cors[10]),int(cors[11]),
int(cors[12]), int(cors[13]),int(cors[14]),int(cors[15]),int(cors[16]), int(cors[17]),int(cors[18]),int(cors[19]),int(cors[20]), int(cors[21]),
int(cors[22]), int(cors[23]),int(cors[24]),int(cors[25]),int(cors[26]), int(cors[27]),int(cors[28]),int(cors[29]),int(cors[30]), int(cors[31])]
objects.append(obj_struct)
return objects
def voc_ap(rec, prec, use_07_metric=False):
""" ap = voc_ap(rec, prec, [use_07_metric])
Compute VOC AP given precision and recall.
If use_07_metric is true, uses the
VOC 07 11 point method (default:False).
"""
if use_07_metric:
# 11 point metric
ap = 0.
for t in np.arange(0., 1.1, 0.1):
if np.sum(rec >= t) == 0:
p = 0
else:
p = np.max(prec[rec >= t])
ap = ap + p / 11.
else:
# correct AP calculation
# first append sentinel values at the end
mrec = np.concatenate(([0.], rec, [1.]))
mpre = np.concatenate(([0.], prec, [0.]))
# compute the precision envelope
for i in range(mpre.size - 1, 0, -1):
mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i])
# to calculate area under PR curve, look for points
# where X axis (recall) changes value
i = np.where(mrec[1:] != mrec[:-1])[0]
# and sum (\Delta recall) * prec
ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])
return ap
def voc_eval_polygon(detpath,
annopath,
imagesetfile,
classname,
ovthresh=0.5,
use_07_metric=False):
# first load gt
cachefile = 'dataset/ctw1500/annots.pkl'
# read list of images
with open(imagesetfile, 'r') as f, open(annopath, 'r') as fa:
lines = f.readlines()
anno_lines = fa.readlines()
imagenames = [x.strip() for x in lines]
anno_names = [y.strip() for y in anno_lines]
assert(len(imagenames) == len(anno_names)), 'each image should correspond to one label file'
if not os.path.isfile(cachefile):
# load annots
recs = {}
for i, imagename in enumerate(imagenames):
print(anno_names[i].strip())
recs[imagename] = curve_parse_rec_txt(anno_names[i])
if i % 100 == 0:
print('Reading annotation for {:d}/{:d}'.format(
i + 1, len(imagenames)))
# save
print('Saving cached annotations to {:s}'.format(cachefile))
with open(cachefile, 'wb') as f:
cPickle.dump(recs, f)
else:
# load
with open(cachefile, 'rb') as f:
recs = cPickle.load(f)
class_recs = {}
npos = 0
num_gt = {}
for ix, imagename in enumerate(imagenames):
R = [obj for obj in recs[imagename] if obj['name'] == classname] # text
# assert(R), 'Can not find any object in '+ classname+' class.'
if not R: continue
bbox = np.array([x['bbox'] for x in R])
difficult = np.array([x['difficult'] for x in R]).astype(np.bool)
det = [False] * len(R)
npos = npos + sum(~difficult)
num_gt[str(ix)] = sum(~difficult)
class_recs[str(ix)] = {'bbox': bbox, 'difficult': difficult, 'det': det}
# read dets
detfile = detpath.format(classname)
with open(detfile, 'r') as f:
lines = f.readlines()
splitlines = [x.strip().split(' ') for x in lines]
image_ids = [x[0] for x in splitlines]
confidence = np.array([float(x[1]) for x in splitlines])
BB = np.array([[float(z) for z in x[2:]] for x in splitlines])
# sort by confidence
sorted_ind = np.argsort(-confidence)
sorted_scores = np.sort(-confidence)
# BB = BB[sorted_ind, :]
# image_ids = [image_ids[x] for x in sorted_ind]
# go down dets and mark TPs and FPs
nd = len(image_ids)
tp = np.zeros(nd)
fp = np.zeros(nd)
# for d in range(nd):
for d in tqdm(range(nd)):
R = class_recs[image_ids[d]]
bb = BB[d] # mask rcnn
det_bbox = bb[:]
pts = [(det_bbox[j], det_bbox[j+1]) for j in range(0,len(bb),2)]
try:
pdet = Polygon(pts)
except Exception as e:
print(e)
continue
if not pdet.is_valid:
# print('{} img predicted polygon has intersecting sides.'.format(d))
# print(pts, image_ids[d])
continue
ovmax = -np.inf
BBGT = R['bbox'].astype(float)
gt_bbox = BBGT[:, :4]
info_bbox_gt = BBGT[:, 4:32]
ls_pgt = []
overlaps = np.zeros(BBGT.shape[0])
for iix in range(BBGT.shape[0]):
pts = [(int(gt_bbox[iix, 0]) + info_bbox_gt[iix, j],
int(gt_bbox[iix, 1]) + info_bbox_gt[iix, j+1]) for j in range(0,28,2)]
pgt = Polygon(pts)
if not pgt.is_valid:
print('GT polygon has intersecting sides.')
continue
try:
sec = pdet.intersection(pgt)
except Exception as e:
print('intersect invalid',e)
continue
try:
assert sec.is_valid, 'polygon has intersection sides.' # for mask rcnn
except Exception as e:
print(e)
continue
inters = sec.area
uni = pgt.area + pdet.area - inters
if uni <= 0.00001: uni = 0.00001
overlaps[iix] = inters*1.0 / uni
ovmax = np.max(overlaps)
jmax = np.argmax(overlaps)
if ovmax > ovthresh:
if not R['difficult'][jmax]:
if not R['det'][jmax]:
tp[d] = 1.
R['det'][jmax] = 1
else:
fp[d] = 1.
else:
fp[d] = 1.
# compute precision recall
fpp = fp
tpp = tp
fp = np.cumsum(fp)
tp = np.cumsum(tp)
rec = tp / float(npos)
# ground truth
prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)
ap = voc_ap(rec, prec, use_07_metric)
return rec, prec, ap, fpp, tpp, image_ids, num_gt
================================================
FILE: dataset/ctw1500/Evaluation_sort/detections_text0.5.txt
================================================
0 0.999 44 73 49 83 59 80 68 75 78 71 87 69 98 70 106 74 115 78 123 82 131 79 130 71 120 66 111 63 101 59 91 56 80 57 70 61 61 65 53 69
0 0.999 99 117 92 117 84 117 78 117 71 117 64 117 57 117 50 118 50 124 50 130 50 136 56 136 64 136 71 136 77 136 84 137 90 137 99 137 98 129 98 125
0 0.999 40 136 39 143 39 151 44 155 50 155 57 155 63 155 70 155 76 156 82 156 89 156 89 148 89 140 86 137 79 137 72 137 64 136 57 136 51 136 46 136
0 0.999 40 183 42 192 55 193 70 193 84 193 98 194 110 195 124 195 137 197 141 188 143 178 139 168 125 167 111 167 99 166 86 166 72 165 59 165 47 164 40 168
1 0.999 52 58 59 91 67 124 76 152 124 149 137 148 165 146 194 147 219 149 248 151 277 155 283 132 286 108 257 101 226 95 199 91 166 93 138 95 110 87 82 68
1 0.999 277 204 267 203 258 204 249 204 242 204 228 206 217 206 207 206 197 206 194 214 196 224 204 226 214 225 225 225 234 224 244 224 253 224 264 224 274 224 277 215
1 0.999 167 258 157 259 148 259 139 260 134 260 121 261 111 261 101 262 92 264 93 273 94 281 103 281 112 280 122 280 131 280 140 279 148 279 158 279 167 276 167 268
2 0.999 57 102 63 116 72 119 85 114 99 111 112 110 125 110 138 112 151 115 163 120 173 116 175 103 163 97 151 93 137 90 123 88 109 88 95 90 82 93 69 97
2 0.999 154 132 141 133 120 133 101 133 87 134 75 135 72 149 71 165 72 181 72 195 73 208 84 208 103 208 120 207 136 206 153 206 153 193 154 177 155 163 155 149
2 0.999 78 228 78 238 79 247 91 248 100 248 111 248 120 248 130 248 139 248 149 248 159 248 159 237 156 227 148 227 137 227 126 227 117 227 106 227 97 227 87 227
3 0.999 153 77 159 98 171 107 193 103 216 100 238 99 261 100 283 102 304 106 325 112 340 109 347 88 329 78 305 70 282 67 261 64 240 63 217 64 195 65 172 70
3 0.999 238 121 237 124 237 128 238 130 242 132 244 132 248 132 251 133 254 133 256 133 260 130 260 127 260 122 258 121 255 120 253 120 249 120 246 120 243 120 239 121
3 0.999 102 156 101 166 102 179 107 183 118 183 129 184 140 184 151 185 161 185 171 185 180 186 181 174 182 159 175 157 164 156 154 156 143 156 132 155 122 155 110 155
3 0.999 301 163 301 176 301 189 311 190 324 191 336 191 348 191 359 192 371 192 382 192 393 193 393 178 392 165 382 164 370 164 358 163 347 163 335 163 323 162 310 161
3 0.999 165 221 179 227 194 232 213 236 230 238 248 240 266 239 284 237 300 232 315 228 322 213 309 212 293 216 276 220 258 222 241 223 224 221 207 217 190 212 172 206
4 0.999 19 169 63 179 109 185 160 192 210 199 266 207 328 216 380 225 431 231 481 239 489 185 445 166 396 152 346 144 299 137 248 128 191 116 137 104 82 92 33 99
4 0.999 279 226 289 246 310 249 332 250 353 253 375 256 399 258 420 260 442 263 465 266 487 266 475 248 453 244 431 241 410 239 388 236 365 233 343 231 322 228 299 226
4 0.999 76 338 105 345 135 339 167 338 198 345 229 358 265 363 298 364 329 365 360 364 391 359 368 337 334 334 301 332 268 332 234 332 203 326 171 320 138 320 105 327
5 0.999 54 58 67 64 82 62 91 57 104 52 119 51 134 54 148 59 160 70 172 67 185 58 176 48 163 40 148 33 134 30 119 28 104 29 89 32 76 38 66 45
5 0.999 23 110 37 114 56 114 78 114 99 114 123 114 146 114 167 113 189 113 210 113 210 94 196 82 172 81 154 82 131 81 110 81 88 82 67 81 45 81 25 81
5 0.999 84 122 84 125 84 128 84 131 85 132 88 133 90 133 92 132 95 132 98 132 100 131 100 128 100 125 100 121 98 121 95 121 93 121 90 121 87 121 85 121
5 0.999 100 122 99 127 99 135 100 139 104 141 110 141 116 141 122 141 127 141 133 141 137 141 138 134 137 125 137 121 132 121 126 121 121 121 115 121 109 121 103 121
5 0.999 47 141 57 153 71 163 85 171 99 174 115 177 131 176 146 172 160 165 171 157 182 144 170 131 155 131 143 141 128 149 114 151 99 148 85 139 73 126 60 130
5 0.999 95 206 95 217 100 223 108 223 117 223 125 223 134 223 143 223 151 223 160 224 168 223 168 209 164 206 155 206 146 205 138 206 129 206 121 205 112 205 103 205
6 0.999 118 42 109 41 101 43 93 46 85 49 77 52 68 56 61 61 54 66 48 70 51 77 59 81 66 75 73 70 81 66 88 62 96 58 104 56 112 53 119 49
6 0.999 168 46 165 54 173 57 181 60 189 63 198 67 206 71 213 75 220 80 227 85 236 86 239 79 232 74 224 68 216 63 209 59 201 55 192 52 184 49 176 46
6 0.999 18 121 17 150 34 161 64 161 93 161 124 161 153 162 183 163 212 164 242 165 271 165 270 138 254 124 224 124 193 123 164 122 134 121 105 121 73 120 44 120
6 0.999 39 176 42 200 66 198 90 198 114 198 138 199 161 200 185 201 209 201 233 202 255 202 251 179 229 178 205 177 181 177 158 176 133 176 109 175 86 175 61 174
6 0.999 86 204 86 221 102 221 120 222 136 222 152 222 169 223 185 223 202 224 219 224 235 223 234 207 218 206 202 206 185 205 168 205 151 205 134 205 118 204 102 204
6 0.999 84 235 83 254 98 257 115 257 131 257 148 258 166 258 183 258 201 259 220 259 234 257 235 239 221 236 203 235 185 235 168 235 150 234 132 234 116 234 96 233
6 0.999 126 277 128 280 131 280 134 281 137 281 141 282 144 283 148 283 151 284 155 284 158 280 155 278 151 278 147 277 144 277 141 276 138 276 134 275 131 274 128 274
6 0.999 201 275 197 275 194 276 190 276 187 277 184 278 181 278 177 278 174 278 171 278 170 282 172 284 176 284 180 284 183 283 186 283 190 282 193 282 197 281 200 279
7 0.999 434 130 426 69 384 70 343 69 302 69 267 70 217 72 177 81 138 86 95 87 52 89 57 140 96 142 137 141 178 142 224 149 270 146 313 140 353 138 391 133
7 0.999 276 162 270 152 263 153 256 156 249 158 240 159 233 159 226 157 218 155 210 153 206 161 209 167 217 170 225 173 232 174 240 175 248 175 256 173 263 171 270 168
8 0.999 199 152 207 160 216 161 227 161 240 161 254 161 271 162 283 160 287 161 300 163 314 155 305 148 294 145 285 141 272 139 257 138 243 139 228 140 215 144 207 148
8 0.999 304 226 296 225 283 222 272 223 260 224 250 226 242 227 234 227 219 227 212 232 209 240 219 243 230 244 242 243 251 241 261 240 271 238 280 237 290 239 300 239
9 0.999 200 25 200 35 203 43 214 43 225 43 236 43 246 43 261 44 274 43 282 43 291 43 292 31 286 24 275 24 265 24 254 24 243 24 233 24 221 24 209 24
9 0.999 390 62 357 63 325 72 293 83 261 94 231 104 201 115 173 121 140 128 104 138 111 173 143 171 176 164 206 155 236 144 268 131 297 120 327 108 361 100 388 92
9 0.999 405 107 367 113 328 123 289 138 251 153 215 168 176 181 146 189 102 195 79 220 84 256 128 255 169 247 207 237 244 223 279 207 317 191 355 179 396 169 409 145
9 0.999 328 281 310 281 292 281 275 281 256 282 239 283 222 283 206 283 188 283 171 289 171 307 189 307 207 307 225 307 243 306 260 305 279 305 297 305 315 305 328 298
10 0.999 443 20 443 25 447 27 452 27 456 27 461 27 466 28 472 28 476 28 480 28 484 23 482 18 479 17 474 17 469 17 464 17 459 17 455 16 450 16 446 16
10 0.999 84 78 87 81 96 82 106 84 117 85 126 86 137 89 149 90 156 90 166 91 168 81 164 74 155 73 145 71 136 70 126 68 117 67 107 65 97 63 88 64
10 0.999 427 109 427 116 428 122 435 123 441 122 447 122 454 122 461 122 466 122 474 122 479 120 479 113 477 106 470 106 463 106 457 106 451 107 444 107 438 107 432 107
10 0.999 372 105 355 109 339 114 323 117 307 119 291 120 277 120 260 119 241 117 234 122 233 142 250 145 265 147 283 146 300 145 316 143 333 142 349 138 364 135 371 123
10 0.999 429 125 430 132 434 137 441 137 449 138 454 142 460 144 467 147 473 147 480 145 480 139 481 134 481 125 477 121 470 121 463 121 456 121 449 121 442 122 436 123
10 0.999 204 114 186 116 167 120 151 120 132 120 113 119 98 119 79 124 82 140 83 162 83 177 103 178 122 178 139 178 161 179 182 180 200 180 211 170 210 152 207 136
10 0.999 383 129 366 134 349 138 333 142 315 144 299 146 283 147 265 148 247 147 231 147 230 166 247 168 264 169 280 168 298 167 316 166 333 164 351 160 368 156 384 147
10 0.999 379 176 372 158 356 160 340 165 323 168 305 170 290 170 270 169 251 169 236 168 229 176 228 193 249 195 263 194 282 194 299 193 316 191 332 188 348 185 364 181
10 0.999 86 180 89 193 102 194 116 194 129 194 142 195 156 195 170 196 181 196 196 197 207 196 203 183 190 182 177 182 164 182 151 181 138 181 125 181 112 180 99 180
10 0.999 395 205 373 195 346 196 319 200 293 203 268 206 244 206 219 206 189 206 168 206 150 216 170 230 196 231 222 231 250 230 275 229 302 227 331 223 356 219 376 216
11 0.999 372 219 346 216 325 214 301 213 275 213 247 214 222 214 195 215 168 218 140 221 143 248 163 248 191 245 218 245 242 244 268 244 294 244 320 245 348 247 368 245
11 0.999 281 366 281 388 305 391 331 391 353 391 372 391 398 391 423 391 443 391 463 391 480 388 478 366 457 366 436 365 413 365 390 364 369 363 346 363 321 363 300 364
12 0.999 105 46 103 36 96 33 89 33 81 34 74 34 66 35 60 34 54 36 46 36 44 39 43 48 49 50 56 51 65 51 73 51 80 51 88 50 95 49 102 48
12 0.999 101 52 95 49 90 51 85 54 78 56 72 56 66 56 60 54 53 52 48 51 45 54 49 60 55 63 61 64 66 65 73 66 79 65 85 63 91 61 97 58
12 0.999 376 50 376 58 378 67 387 67 396 66 405 66 414 67 423 68 432 69 440 71 448 70 450 61 445 53 437 53 428 52 419 51 410 51 401 50 393 50 385 50
12 0.999 212 56 215 69 228 72 243 72 258 72 273 72 287 74 303 75 316 77 330 80 342 79 340 65 326 62 312 60 298 58 283 57 269 56 255 56 240 56 226 56
12 0.999 393 73 395 75 398 76 403 76 407 77 413 77 417 77 422 77 426 77 431 75 431 70 428 68 423 67 419 67 414 67 410 66 405 66 401 66 396 66 393 68
12 0.999 381 77 381 84 386 86 393 86 400 86 407 86 415 87 422 88 430 88 436 89 442 87 441 78 435 76 428 77 420 77 413 77 406 76 400 75 392 74 386 73
12 0.999 230 75 229 86 236 92 248 93 260 94 271 95 283 96 296 97 308 98 319 98 330 98 330 85 321 81 310 80 299 79 286 79 275 78 263 77 251 76 240 75
12 0.999 395 87 395 91 396 95 401 96 405 96 410 97 414 97 420 97 423 97 427 97 431 95 432 89 429 88 425 87 420 87 416 87 412 86 407 86 402 86 399 86
12 0.999 245 98 245 104 251 106 258 106 265 106 271 107 278 109 286 109 292 109 298 110 305 107 303 99 297 98 290 98 283 97 276 97 270 97 263 96 256 96 250 95
12 0.999 385 96 385 103 388 107 395 107 401 107 408 107 415 107 422 107 428 108 433 108 440 107 440 100 435 96 428 97 422 97 416 97 410 96 404 96 397 95 391 95
12 0.999 231 109 233 118 242 119 252 119 262 120 272 121 282 121 293 122 302 123 311 123 321 121 318 113 309 112 299 112 289 111 280 110 270 110 260 109 250 109 240 108
12 0.999 21 155 31 158 45 158 60 159 75 159 88 160 103 161 119 162 133 163 148 164 151 149 140 148 126 147 112 147 98 145 83 145 69 144 55 142 40 142 24 141
12 0.999 335 157 345 164 358 165 373 165 388 165 404 167 420 167 436 167 451 168 466 168 473 156 462 152 448 152 433 152 418 151 403 151 388 150 373 149 358 148 343 147
12 0.999 18 157 19 171 34 173 49 174 65 174 80 174 95 176 111 176 127 177 141 177 155 177 152 164 138 162 123 162 108 161 93 161 78 160 63 159 47 158 33 158
12 0.999 336 182 336 190 345 192 353 193 364 193 374 194 383 195 394 197 403 196 405 190 409 181 407 173 398 171 390 171 381 170 371 170 361 170 352 169 341 168 338 175
12 0.999 236 196 236 205 237 214 246 214 256 214 266 215 276 215 286 215 297 215 305 216 313 215 313 203 310 197 301 197 292 196 282 196 273 196 263 196 253 195 245 195
12 0.999 266 219 266 223 266 227 270 230 274 230 278 230 282 230 288 230 291 230 296 230 299 227 299 223 296 219 293 219 289 218 286 218 281 218 276 218 273 218 269 218
12 0.999 385 220 383 226 386 229 393 229 398 229 404 229 410 229 416 230 421 230 426 230 431 229 431 221 427 220 421 220 416 219 410 219 405 219 399 219 394 218 389 218
12 0.999 376 229 375 238 374 247 377 253 387 255 396 255 405 255 415 255 427 255 433 255 441 252 443 244 444 234 437 230 429 230 420 230 410 229 400 229 391 229 384 228
12 0.999 261 232 261 237 262 243 267 243 272 243 277 243 282 243 288 243 293 243 296 244 301 242 301 237 299 232 295 232 290 231 285 231 280 231 275 231 270 231 266 231
12 0.999 241 244 241 252 247 256 256 256 265 256 274 257 283 257 292 257 301 258 309 258 317 256 317 246 309 246 301 246 292 245 283 245 275 245 266 245 258 244 249 244
12 0.999 260 261 260 265 263 269 269 268 275 269 280 269 285 269 291 269 297 269 302 268 305 262 304 258 300 257 294 257 289 257 284 257 278 257 273 257 267 257 263 257
12 0.999 263 271 263 276 265 280 268 281 273 281 277 281 281 281 286 281 291 281 296 281 301 280 301 275 300 270 295 270 290 270 286 269 281 269 276 269 271 269 266 269
12 0.999 262 317 262 329 271 334 283 334 296 334 308 334 320 334 334 334 347 332 359 331 370 328 368 318 357 317 346 317 334 317 322 317 310 317 297 317 285 317 272 317
12 0.999 428 320 407 321 387 325 369 329 349 332 330 334 311 334 293 334 275 334 261 337 265 352 286 353 304 354 323 354 343 354 363 354 384 354 407 354 426 354 428 338
13 0.999 58 46 70 66 85 73 107 62 134 54 158 48 180 47 202 54 225 65 255 78 262 69 267 44 246 35 223 28 199 22 172 18 146 21 124 24 100 27 76 36
13 0.999 19 81 19 94 19 107 19 119 30 120 45 119 58 119 71 120 85 121 105 117 105 120 105 108 105 94 105 84 94 80 79 76 65 75 52 74 39 76 20 79
13 0.999 216 84 215 96 215 108 215 119 222 125 238 126 250 127 263 128 277 128 297 128 298 129 299 117 299 103 299 93 289 90 275 89 262 88 249 86 237 84 217 84
13 0.999 136 177 137 182 143 182 150 182 156 182 163 182 169 182 175 182 183 182 190 179 190 173 189 169 182 169 176 169 170 169 162 169 156 169 150 169 143 169 136 171
13 0.999 32 180 32 185 32 190 32 195 33 200 38 201 42 201 47 201 52 201 60 198 60 199 61 194 61 190 61 185 60 180 55 180 50 179 45 179 40 179 34 180
13 0.999 298 186 275 186 252 186 230 187 207 187 185 187 163 188 140 188 116 188 100 189 94 206 114 209 137 209 159 208 182 208 204 208 226 207 250 207 272 206 292 205
13 0.999 25 209 25 213 30 215 35 214 41 214 47 214 52 214 58 214 65 214 71 211 71 205 70 202 65 201 59 201 53 201 47 201 41 201 36 201 30 201 25 204
13 0.999 296 210 275 208 254 208 232 208 211 209 190 210 168 210 147 211 126 211 107 212 94 221 114 224 135 223 155 223 177 223 199 222 220 221 241 221 263 220 282 220
13 0.999 28 222 28 225 32 228 38 228 43 228 48 228 53 228 58 228 64 228 70 226 70 221 70 217 65 216 60 216 55 216 50 216 45 216 39 216 34 216 28 218
13 0.999 261 224 246 224 233 224 219 224 205 224 191 224 177 225 164 225 150 225 139 225 134 236 147 238 160 237 174 237 189 237 202 237 216 237 230 236 244 236 258 236
14 0.999 60 39 72 59 91 63 113 53 140 46 162 39 183 40 205 48 227 58 249 69 264 62 265 37 242 26 220 19 197 13 172 10 149 12 126 16 103 19 80 28
14 0.999 146 79 145 83 146 91 146 97 146 103 150 107 154 107 160 107 165 107 170 107 175 105 175 101 176 92 177 86 177 79 173 79 168 79 161 78 155 78 150 78
14 0.999 40 111 40 123 40 139 43 148 55 147 69 147 80 147 92 149 105 151 116 153 124 149 125 135 126 118 125 109 114 107 100 106 87 105 74 105 61 107 49 108
14 0.999 197 119 197 129 197 145 197 157 209 158 224 155 235 156 246 160 258 161 269 160 280 159 280 149 281 132 280 124 269 122 257 121 245 120 232 120 220 118 207 118
14 0.999 82 158 95 168 110 176 127 182 145 185 163 186 180 186 196 182 213 177 228 170 239 159 226 155 212 163 195 168 178 172 161 172 145 171 127 167 112 160 96 152
14 0.999 95 194 99 206 114 206 128 206 143 205 157 205 171 205 185 205 200 205 214 205 228 204 224 193 209 192 195 192 181 192 167 192 152 192 138 192 123 192 109 192
15 0.999 99 25 104 39 110 52 118 59 135 54 149 53 163 55 179 60 194 68 203 68 209 57 216 46 206 39 193 32 182 28 169 23 155 20 141 17 125 18 112 20
15 0.999 102 107 104 126 106 146 105 157 128 157 149 157 167 157 188 157 211 157 218 157 234 155 233 140 231 125 223 112 204 111 189 111 172 110 154 110 137 108 120 107
15 0.999 267 240 251 226 238 212 227 206 214 218 196 226 179 227 161 224 146 219 133 213 127 231 122 252 136 260 150 264 167 268 183 270 201 269 220 264 235 258 248 251
16 0.999 353 28 353 36 354 43 360 44 366 44 374 44 380 44 388 44 395 44 403 44 410 43 410 36 410 27 405 27 397 27 390 26 381 25 375 25 367 26 359 26
16 0.999 85 29 85 38 86 44 92 44 98 44 104 44 111 44 117 44 125 44 130 44 138 43 138 35 137 28 131 28 125 28 118 28 111 28 104 28 98 28 90 28
16 0.999 141 70 154 91 175 87 197 80 218 76 240 74 262 76 285 77 307 83 329 89 344 82 342 65 321 58 298 52 274 49 251 47 228 47 205 50 183 55 163 62
16 0.999 33 61 31 70 31 80 31 89 31 99 31 107 31 116 31 125 31 135 34 144 46 144 48 134 48 125 48 115 48 106 48 96 48 86 48 77 48 67 45 60
16 0.999 11 62 9 71 9 80 9 89 10 98 10 106 10 115 10 124 10 133 9 141 19 144 23 135 23 126 23 116 23 107 23 98 23 88 23 80 23 70 21 63
16 0.999 457 62 451 80 451 100 451 120 451 140 451 160 451 179 450 199 450 219 450 239 453 258 460 241 461 220 461 200 461 181 461 160 461 140 461 119 462 99 462 78
16 0.999 468 62 462 81 462 100 462 121 462 141 462 160 462 180 462 200 462 219 462 239 464 258 472 239 472 220 472 200 472 180 472 159 473 138 473 119 473 99 473 78
16 0.999 476 63 473 84 473 104 473 123 473 144 473 163 473 183 473 202 473 223 473 243 483 258 486 237 486 217 486 197 486 176 486 156 486 135 487 115 487 95 487 75
16 0.999 12 153 12 174 11 195 12 216 12 236 11 257 11 277 11 298 11 318 11 339 17 356 20 334 20 314 20 294 20 273 20 252 20 231 20 210 20 189 20 168
16 0.999 32 155 30 175 30 196 30 216 30 236 30 257 30 277 30 297 30 318 30 338 35 356 39 336 39 315 39 294 39 274 39 254 38 233 38 212 39 192 39 171
16 0.999 22 157 20 178 20 198 20 219 20 238 20 258 20 278 20 298 20 318 20 339 27 356 30 335 30 315 30 295 30 275 30 254 29 235 29 214 29 194 30 173
16 0.999 40 198 38 214 38 231 38 247 39 263 39 279 39 294 39 310 39 326 39 343 46 355 48 339 48 323 48 307 48 291 48 274 48 258 48 242 48 226 48 209
16 0.999 120 205 120 241 126 255 157 254 189 255 219 254 248 254 277 255 309 255 337 254 370 255 370 228 360 211 329 209 302 209 268 211 237 211 210 211 180 211 150 207
16 0.999 163 273 171 289 187 284 203 281 221 279 237 278 255 279 272 280 289 283 306 287 321 287 317 271 302 266 284 263 265 260 248 258 230 259 212 260 195 264 179 268
16 0.999 86 312 86 321 86 327 92 328 98 328 104 328 111 328 117 328 125 328 131 329 137 327 138 319 137 313 133 311 126 311 120 311 112 310 106 311 100 311 93 311
16 0.999 346 341 349 344 357 344 365 344 373 344 381 344 388 344 396 344 405 344 412 343 412 334 409 329 401 328 394 327 385 326 377 326 369 326 361 325 353 325 346 328
16 0.999 83 334 83 343 89 344 96 344 102 344 109 344 115 345 122 345 129 345 137 345 140 339 140 331 135 329 127 329 120 329 112 328 107 328 101 328 94 328 87 328
17 0.999 156 73 164 102 182 97 202 87 224 81 243 77 265 82 286 92 307 104 326 118 343 122 348 96 329 82 311 68 290 55 269 46 243 42 218 43 196 52 174 62
17 0.999 161 135 158 164 175 171 195 171 216 173 236 174 256 175 278 176 301 176 321 178 341 179 343 146 331 144 310 142 290 140 268 138 245 137 222 135 200 134 179 133
18 0.999 170 136 165 170 165 208 201 200 206 164 224 136 248 122 271 123 301 135 324 159 338 192 352 208 368 188 358 154 339 124 312 106 280 92 248 89 212 97 183 116
18 0.999 437 249 404 226 368 226 334 226 295 226 255 226 214 227 170 227 129 227 90 228 64 241 84 258 128 256 170 255 209 254 249 254 287 254 325 252 361 251 400 251
18 0.999 397 257 368 257 343 258 319 258 292 260 263 260 233 261 203 263 173 263 146 264 136 286 159 288 191 287 220 285 248 284 277 283 305 281 331 280 356 278 385 277
19 0.999 100 93 110 107 123 108 138 100 153 97 169 97 184 101 199 108 211 117 223 128 235 125 233 112 222 100 210 90 195 82 178 76 162 75 145 75 129 78 114 84
19 0.999 140 101 139 110 140 116 148 118 157 119 165 121 172 122 180 123 188 124 196 126 204 127 205 115 204 111 196 109 188 107 180 106 172 104 164 103 156 101 147 100
19 0.999 156 126 156 130 159 133 163 133 166 134 170 134 174 135 177 135 181 136 185 136 189 136 189 130 186 129 183 128 178 127 175 127 171 126 168 125 163 125 159 124
19 0.999 19 165 19 167 19 171 20 173 23 174 25 174 28 174 31 174 33 174 36 175 39 174 39 169 39 165 38 164 35 164 33 163 30 163 27 163 24 163 21 163
19 0.999 43 196 43 200 43 206 46 208 50 208 54 209 58 209 63 209 68 210 72 210 76 210 77 204 78 197 74 196 70 196 66 196 61 195 56 195 52 195 47 195
20 0.999 53 16 56 43 60 67 83 67 111 59 136 56 160 56 186 59 211 62 230 66 250 66 256 44 246 29 222 23 200 20 177 17 151 15 128 14 100 14 76 15
20 0.999 73 90 81 103 95 101 117 99 142 98 162 98 184 98 206 98 231 100 237 89 238 77 227 65 208 61 188 60 169 58 150 58 129 57 109 60 87 64 70 71
20 0.999 37 112 41 140 42 164 70 156 102 149 128 147 155 144 183 144 211 147 229 149 251 151 252 124 245 108 219 103 193 101 168 100 141 100 113 100 84 102 60 107
20 0.999 154 146 155 164 156 186 158 207 163 215 185 216 205 216 225 218 248 219 248 220 259 219 260 201 261 186 263 166 259 157 242 154 222 152 201 151 184 150 171 148
20 0.999 140 169 138 164 122 155 109 155 99 156 90 157 80 158 68 160 63 161 55 170 57 177 58 190 68 192 79 191 90 190 100 189 110 189 122 187 130 185 135 178
20 0.999 158 208 153 191 144 188 131 189 119 190 108 190 96 190 83 190 74 190 62 191 56 195 55 213 66 217 80 217 93 218 105 217 117 217 130 216 142 216 156 215
20 0.999 49 237 53 257 76 256 99 255 121 254 143 253 165 252 188 251 211 251 232 251 251 251 245 234 224 233 203 232 180 232 159 232 137 232 114 232 91 233 70 234
20 0.999 225 253 206 254 187 253 167 253 148 254 130 255 112 256 91 257 77 258 59 264 61 284 79 286 96 285 116 284 135 282 153 281 172 281 191 280 210 280 225 274
21 0.999 118 96 119 128 118 161 152 162 185 161 220 160 254 159 289 159 320 160 352 162 385 164 385 134 381 98 346 96 315 95 281 95 248 94 215 94 182 93 150 93
21 0.999 144 185 152 208 176 205 199 200 223 198 246 197 270 196 295 198 318 200 341 207 359 204 357 185 336 178 310 172 286 168 263 168 238 169 213 171 190 174 166 179
21 0.999 227 304 226 311 227 321 234 322 242 322 250 322 256 322 265 322 272 322 280 322 288 322 288 313 287 302 281 301 274 301 266 301 257 301 249 301 242 301 233 301
22 0.999 191 60 190 76 189 92 192 101 210 103 227 103 242 104 259 104 274 104 287 104 302 104 301 88 301 72 298 63 280 63 263 63 247 62 232 62 218 61 204 61
22 0.999 430 103 427 103 423 103 420 103 417 104 413 104 410 105 408 107 409 112 409 115 409 118 412 119 417 119 420 119 424 118 427 118 431 118 432 113 432 110 431 107
22 0.999 453 117 447 117 440 117 435 117 429 118 424 118 418 118 412 118 407 120 408 125 408 131 413 133 418 133 424 133 431 133 437 133 444 133 450 133 452 127 452 122
22 0.999 125 137 120 137 115 137 111 137 105 137 100 137 94 137 89 138 86 141 87 145 87 151 90 152 96 152 101 151 107 151 111 151 117 151 122 151 126 147 126 142
22 0.999 200 193 204 203 211 208 220 204 229 201 239 200 250 200 260 201 269 203 278 207 286 202 290 193 280 189 270 185 260 183 250 182 238 182 228 184 219 186 209 189
22 0.999 200 229 206 234 215 234 225 234 235 234 246 235 256 235 266 234 276 234 286 234 289 223 283 221 274 221 264 221 254 221 243 221 233 221 223 221 214 221 203 221
22 0.999 419 366 421 374 430 374 439 374 448 374 457 374 466 374 475 374 484 374 493 374 499 373 498 366 491 365 482 365 472 365 463 365 454 365 445 365 436 365 427 365
23 0.999 194 110 196 122 197 133 210 133 224 133 237 133 250 135 262 137 274 140 285 144 296 146 300 134 294 124 282 120 271 116 257 113 245 111 231 110 219 110 207 110
23 0.999 214 139 214 147 218 151 226 151 234 151 242 152 250 152 257 154 265 155 271 158 279 158 280 148 274 145 266 143 259 141 252 140 243 139 236 139 228 138 221 138
23 0.999 453 159 452 166 453 172 453 177 459 179 465 179 471 179 477 181 483 183 487 186 492 189 495 182 493 176 489 171 486 167 481 164 476 162 469 160 463 159 458 159
23 0.999 220 188 220 194 224 197 231 197 237 197 243 198 250 199 257 199 263 200 269 201 275 200 275 192 269 191 263 189 256 189 250 189 244 188 237 187 231 186 225 186
23 0.999 460 191 457 189 454 190 450 190 447 191 443 191 439 191 436 191 433 191 432 193 432 197 435 201 438 200 441 199 444 199 448 199 451 199 456 199 459 198 461 193
23 0.999 222 204 225 207 231 207 236 208 242 208 247 208 253 209 259 209 264 210 270 210 272 202 269 200 263 200 258 199 252 199 246 198 241 198 236 198 230 198 224 198
23 0.999 231 209 230 213 231 217 236 218 240 218 246 219 251 219 255 220 259 220 264 220 268 218 268 211 266 210 262 209 257 209 253 209 248 209 243 208 238 208 234 208
24 0.999 128 75 135 104 144 132 172 118 199 102 221 91 231 89 261 85 285 89 308 106 324 117 330 99 323 79 302 60 277 47 253 39 224 40 208 43 181 52 154 62
24 0.999 315 153 302 162 294 169 289 174 269 184 246 191 213 191 190 187 183 201 180 222 175 241 191 244 212 244 233 240 251 232 270 223 286 214 295 206 310 193 321 177
25 0.999 128 78 121 77 115 77 108 77 102 77 96 77 91 77 85 77 80 83 80 89 81 96 86 97 93 97 98 97 105 97 112 97 120 97 124 97 127 91 127 85
25 0.999 198 107 174 108 149 109 124 109 101 110 77 110 55 110 34 110 9 121 10 146 11 170 30 169 60 168 80 167 103 167 126 167 149 166 174 166 198 153 198 131
25 0.999 174 177 155 177 135 179 115 180 98 179 79 179 62 178 45 180 33 201 34 220 34 241 48 244 70 242 86 241 106 238 126 236 147 232 163 229 172 214 173 195
25 0.999 157 290 145 285 137 293 128 300 118 305 106 307 94 306 84 302 73 295 65 287 57 294 64 302 73 310 84 315 94 319 106 319 119 318 130 314 140 308 149 299
25 0.999 92 288 92 292 92 296 92 300 94 302 97 302 103 303 107 303 110 303 114 303 118 302 118 298 118 294 118 290 116 288 112 288 108 288 103 288 100 288 96 288
26 0.999 231 62 225 64 221 67 218 71 217 77 216 81 215 85 214 90 214 96 214 100 216 104 225 105 228 101 229 96 229 90 231 83 232 78 233 75 235 69 233 65
26 0.999 267 63 264 67 264 72 264 77 266 81 268 86 270 92 271 97 272 103 274 106 281 107 285 103 286 98 285 93 284 87 283 83 281 78 278 71 277 67 272 64
26 0.999 228 127 228 132 234 135 238 137 244 139 250 140 256 140 260 139 267 136 270 134 271 127 270 122 265 121 260 121 255 123 250 124 244 123 239 122 235 121 231 121
26 0.999 391 164 364 162 333 162 303 163 275 163 246 163 216 163 185 163 157 163 130 162 114 182 139 188 171 188 200 188 229 188 260 188 290 187 321 187 349 188 379 187
26 0.999 89 222 124 223 152 223 185 223 220 223 255 223 288 223 323 223 355 223 390 223 409 201 381 200 347 200 314 200 278 200 242 200 209 200 175 199 139 199 103 199
26 0.999 321 225 304 224 288 224 272 224 257 224 240 225 225 225 207 225 192 225 178 226 178 243 192 246 209 246 225 246 241 246 258 245 273 245 289 245 306 245 321 240
26 0.999 378 259 350 256 323 256 296 256 269 256 242 256 214 257 188 256 162 256 132 256 118 275 145 281 174 280 201 280 229 279 257 279 285 279 311 278 339 279 368 278
26 0.999 107 290 129 303 157 303 186 303 216 303 246 303 277 303 307 303 339 303 368 303 392 292 372 280 342 279 313 279 282 280 253 280 224 280 192 280 160 280 131 281
26 0.999 84 305 98 329 136 330 173 329 209 329 246 329 282 328 317 329 353 328 389 328 424 328 407 304 371 304 335 304 297 305 261 305 226 305 189 305 151 304 116 304
26 0.999 380 342 350 339 322 339 296 339 269 339 240 339 212 339 183 339 154 339 125 339 119 364 146 366 175 365 204 364 232 364 260 364 289 364 318 364 347 364 375 366
26 0.999 175 367 176 383 192 388 209 388 225 388 242 388 259 388 276 388 292 388 310 388 324 385 324 365 307 365 290 364 273 364 257 365 239 365 223 365 206 365 189 365
26 0.999 182 392 184 407 194 414 210 414 226 414 242 414 257 414 271 414 287 414 303 414 317 412 317 396 305 390 290 389 275 390 259 390 244 390 228 390 212 390 196 390
26 0.999 218 417 217 425 217 435 224 440 232 441 242 441 251 441 261 441 269 440 280 440 287 439 288 428 287 419 281 414 271 414 262 414 253 414 243 414 234 415 225 415
27 0.999 3 3 4 12 12 13 21 13 30 13 39 13 48 13 56 13 65 13 73 13 81 10 79 1 72 1 63 1 54 1 45 1 37 1 27 1 19 1 10 1
27 0.999 192 17 191 20 192 23 194 24 198 24 201 25 204 25 207 25 210 26 213 26 217 25 216 22 216 19 213 18 210 18 207 17 203 17 200 16 197 16 193 16
27 0.999 160 46 148 28 135 19 120 13 102 13 86 16 72 23 60 33 49 48 44 68 45 82 48 92 57 86 69 78 83 70 97 64 112 59 130 56 145 55 158 50
27 0.999 181 24 181 29 186 31 192 32 197 33 203 34 208 34 213 35 219 36 225 37 228 33 228 27 223 27 217 26 212 26 207 25 201 24 196 24 190 22 184 22
27 0.999 189 37 189 40 189 45 190 47 194 48 198 49 201 49 205 49 209 50 213 51 216 49 217 46 217 42 215 40 211 39 207 39 204 39 200 38 196 37 192 37
27 0.999 131 56 124 58 116 60 108 62 100 65 93 68 86 71 79 75 79 81 82 87 85 93 92 93 99 91 107 89 114 86 122 84 130 81 137 78 136 70 133 64
27 0.999 162 61 152 68 138 77 124 85 107 91 93 94 76 96 62 97 50 105 57 114 64 124 77 134 95 138 112 139 128 135 144 128 156 118 168 102 169 86 165 75
27 0.999 157 175 151 176 144 178 138 180 131 181 124 183 119 184 116 189 118 195 119 202 121 207 127 207 133 205 139 204 146 202 153 200 159 199 160 193 159 187 158 181
28 0.999 168 70 177 93 192 98 213 94 232 90 251 89 272 90 292 93 311 97 328 102 342 94 346 73 325 65 307 59 287 56 267 54 246 54 226 55 206 57 187 63
28 0.999 76 107 82 148 123 148 164 149 204 149 243 150 284 150 323 150 363 150 402 151 439 150 437 110 392 108 354 108 314 107 274 106 233 106 193 106 152 107 115 106
28 0.999 148 163 155 164 165 165 175 166 184 167 193 167 203 168 213 168 223 168 230 166 234 155 226 152 216 150 208 150 198 150 188 149 178 149 169 149 159 149 149 151
28 0.999 410 271 416 277 424 277 434 277 442 277 451 277 460 278 468 278 478 278 486 278 495 274 489 269 480 269 472 269 462 269 454 269 445 269 436 269 427 269 417 269
29 0.999 67 53 66 61 65 71 68 75 79 75 88 75 96 76 105 77 113 77 121 77 129 78 130 70 130 57 126 54 117 54 109 53 100 53 91 51 82 51 72 50
29 0.999 64 76 63 86 62 96 66 100 77 101 86 101 95 101 104 102 112 102 121 102 130 103 131 95 131 83 126 81 117 80 108 79 99 79 90 78 80 76 70 75
29 0.999 71 102 70 109 70 120 70 127 76 128 85 128 92 129 100 129 107 129 113 130 120 130 120 122 121 112 120 106 114 105 106 105 99 104 92 103 83 102 76 101
29 0.999 60 130 58 139 59 147 69 148 78 148 87 148 95 148 104 149 113 149 122 149 130 149 131 140 129 132 120 132 112 131 103 131 95 131 86 131 77 130 67 130
29 0.999 38 184 49 187 61 189 73 191 86 192 98 193 111 192 124 192 136 190 147 188 147 176 139 169 126 172 114 173 102 174 90 174 78 173 65 171 53 169 42 169
29 0.999 38 210 40 219 52 219 63 220 75 221 86 221 98 222 110 222 121 222 132 223 142 222 139 212 128 211 116 210 105 210 94 209 82 209 70 208 59 208 47 208
29 0.999 74 235 74 239 73 244 76 245 80 245 84 245 88 245 92 246 96 246 100 246 103 245 104 240 104 235 102 234 98 234 94 234 90 234 85 234 81 234 77 234
29 0.999 42 254 50 255 60 256 71 256 81 257 91 257 100 258 111 258 120 258 130 259 135 250 127 247 117 247 108 246 98 246 87 246 77 246 67 245 57 245 46 245
29 0.999 50 260 50 265 54 267 60 267 65 268 71 268 76 268 81 268 87 268 91 267 97 266 95 261 91 260 86 257 80 257 75 257 70 257 64 257 58 257 52 256
29 0.999 99 260 98 264 99 268 102 269 106 269 109 269 113 269 117 270 120 270 123 270 125 269 126 263 126 259 123 258 119 258 116 258 112 258 109 258 105 258 101 258
30 0.999 14 98 19 101 28 105 38 108 48 109 59 110 69 109 79 107 91 103 98 98 97 86 95 86 83 90 74 93 63 95 54 94 45 94 35 91 26 87 16 85
30 0.999 4 125 16 126 27 125 37 125 49 125 61 125 73 125 86 125 98 127 108 127 110 114 99 112 87 112 76 112 63 112 51 112 39 112 28 112 17 112 5 113
30 0.999 35 125 34 130 34 135 39 136 44 136 50 136 55 136 61 136 67 136 73 136 75 135 76 130 75 125 70 125 65 124 60 124 54 124 49 124 44 124 39 124
30 0.999 7 160 7 172 11 180 23 176 35 171 48 167 60 168 75 172 90 177 103 179 106 177 108 164 103 155 91 152 78 148 65 144 51 144 37 148 26 152 15 157
30 0.999 17 199 21 205 31 205 39 205 48 205 57 205 66 205 75 205 84 205 93 205 100 202 94 197 86 197 78 197 68 197 60 197 51 197 42 197 33 197 24 197
30 0.999 86 216 84 209 77 209 70 209 64 209 58 209 52 209 45 209 39 209 33 209 27 210 27 217 34 217 41 217 48 217 55 217 62 217 68 217 75 217 81 217
30 0.999 108 243 97 240 86 239 74 239 63 240 52 242 41 244 30 245 19 245 7 246 4 256 15 257 25 256 37 255 49 255 61 253 72 251 83 250 95 251 107 252
30 0.999 78 259 74 258 70 258 66 258 63 258 59 259 55 259 51 259 48 259 44 260 44 264 47 265 51 265 55 265 59 265 63 265 67 265 71 265 75 265 78 263
30 0.999 34 270 37 270 42 270 47 270 52 270 56 270 61 270 66 270 72 270 77 270 77 265 74 264 69 264 65 264 60 265 55 265 50 265 45 265 41 264 35 264
30 0.999 9 273 16 277 26 277 36 276 46 277 56 276 66 276 77 276 87 276 97 276 105 271 97 269 87 269 78 270 67 270 57 270 46 270 36 270 27 270 17 269
31 0.999 212 37 218 62 243 56 264 50 287 47 311 48 335 49 362 51 385 53 406 60 425 57 421 34 400 28 376 22 351 19 328 17 302 19 280 19 255 24 232 30
31 0.999 40 113 88 123 148 122 203 122 261 122 320 122 379 122 442 122 503 122 552 122 584 85 531 80 480 78 421 78 362 77 305 76 243 76 186 77 127 77 70 78
31 0.999 35 131 73 155 128 154 181 154 237 154 292 153 348 153 405 152 461 152 515 152 569 152 529 129 477 128 422 129 366 129 311 129 254 129 200 128 143 128 88 129
31 0.999 426 178 407 175 386 175 360 175 338 175 317 176 296 176 275 176 252 177 227 177 226 199 240 205 269 204 291 203 313 203 335 202 355 202 378 202 400 202 423 202
32 0.999 27 60 25 83 42 87 62 88 83 89 102 89 123 90 144 91 160 92 179 92 197 92 197 70 179 68 159 67 138 66 119 65 100 64 82 63 63 62 45 61
32 0.999 189 103 169 100 153 97 132 95 114 95 95 96 77 99 58 103 43 108 30 111 20 131 39 131 50 127 71 123 90 118 107 115 124 114 144 114 164 116 182 118
32 0.999 83 133 91 136 101 136 112 137 125 138 136 138 148 138 160 139 176 140 185 133 189 120 182 118 167 116 157 115 146 115 130 115 119 115 108 116 95 117 85 121
33 0.999 85 144 83 186 111 210 153 196 196 185 223 181 254 180 292 184 335 197 378 210 409 216 410 174 401 142 362 141 320 140 277 140 236 139 189 139 163 139 125 142
33 0.999 304 199 296 184 287 183 274 181 258 180 237 180 219 182 205 182 191 185 178 187 176 192 180 207 192 208 209 208 226 208 242 209 259 209 274 209 290 210 303 206
33 0.999 98 226 125 229 158 229 187 229 220 230 246 232 275 232 305 233 338 233 370 234 387 217 358 215 329 215 300 214 270 212 239 212 209 211 177 211 147 210 118 209
34 0.999 455 49 409 36 350 51 291 61 233 80 189 107 141 123 83 144 37 172 11 218 26 267 62 255 111 225 167 203 225 185 278 166 323 148 381 130 434 120 480 93
34 0.999 85 52 73 54 61 56 50 59 38 60 29 61 18 61 10 69 8 80 7 91 7 102 16 102 26 98 37 96 48 92 60 90 70 89 78 86 80 76 82 64
34 0.999 127 67 113 72 99 77 83 85 68 91 56 96 41 100 25 102 12 108 10 123 9 140 21 139 37 135 52 130 66 123 81 116 94 110 109 102 122 96 126 81
34 0.999 367 155 354 158 341 160 327 164 314 168 302 172 289 176 276 181 264 185 259 195 259 208 270 207 283 203 296 198 309 193 322 189 333 185 346 182 360 177 368 168
34 0.999 247 193 229 198 209 203 189 208 170 214 153 220 135 225 115 232 97 238 85 251 85 269 101 267 120 261 138 255 157 248 176 241 195 235 214 230 232 224 245 212
34 0.999 379 212 378 218 377 224 377 230 377 238 377 243 379 249 389 249 396 249 403 249 410 247 411 241 410 234 410 227 410 220 410 212 406 209 399 210 391 210 384 210
34 0.999 293 251 291 277 296 295 321 301 347 306 373 309 402 310 431 308 453 304 475 300 492 295 487 270 478 250 451 255 423 259 398 261 377 261 356 258 334 254 309 249
34 0.999 488 328 439 327 390 328 342 328 293 328 246 328 198 328 148 328 100 328 53 329 15 340 63 341 111 341 160 341 208 341 256 341 303 342 351 341 401 341 449 341
35 0.999 146 58 146 68 152 72 161 72 171 74 180 77 189 81 198 85 206 90 214 95 223 91 226 84 218 79 210 74 201 69 193 65 183 61 174 59 164 58 154 58
35 0.999 141 59 133 60 125 62 116 65 108 69 101 73 95 78 87 84 81 90 76 95 80 102 88 103 95 97 100 91 107 87 114 82 121 79 130 75 140 73 143 68
35 0.999 225 112 218 97 199 99 183 100 167 101 151 102 135 103 119 105 104 105 90 106 78 109 86 121 103 120 118 120 135 119 150 118 166 117 182 116 198 114 212 114
35 0.999 234 137 216 138 199 139 181 139 163 140 146 141 129 142 111 142 93 144 77 144 71 156 89 156 107 155 124 154 141 154 159 153 176 152 194 151 212 151 230 150
35 0.999 142 228 142 234 144 239 149 239 154 239 160 239 165 239 171 239 175 239 181 239 185 238 185 232 183 228 178 228 173 228 167 228 162 228 157 227 151 226 146 226
36 0.999 189 48 188 62 188 85 197 85 216 79 229 76 245 75 261 78 276 82 290 89 306 93 304 77 305 57 296 49 281 42 265 37 247 34 231 34 215 36 198 40
36 0.999 402 326 408 330 419 330 429 330 439 330 448 330 458 330 468 330 479 330 489 331 496 323 490 319 480 319 470 319 459 319 450 319 439 319 429 319 419 319 408 319
37 0.999 40 71 56 88 73 90 89 74 105 64 125 58 148 57 167 61 186 70 204 73 216 52 209 40 189 32 169 26 148 23 128 22 107 25 86 34 70 44 55 57
37 0.999 223 49 212 63 207 73 207 85 216 95 224 106 231 119 238 134 244 147 253 152 265 149 279 146 281 136 276 124 270 113 265 102 260 90 253 78 245 68 233 58
37 0.999 77 78 70 102 73 123 75 157 76 187 85 212 98 237 142 245 172 238 186 240 208 224 217 198 222 160 222 142 216 121 195 100 173 90 162 71 139 62 105 66
37 0.999 39 79 33 88 29 95 25 105 22 115 20 125 19 137 18 147 18 152 25 157 36 157 45 157 50 151 51 138 52 130 54 119 59 111 63 103 60 97 51 86
37 0.999 278 207 246 195 231 217 211 241 183 256 150 261 121 253 97 240 85 224 55 199 35 220 56 245 79 269 102 280 129 290 161 294 193 289 221 277 244 259 261 234
38 0.999 47 37 59 46 70 40 82 34 94 32 106 31 119 34 131 38 142 44 152 52 162 47 157 37 146 29 135 22 123 18 109 16 96 16 83 17 70 21 59 28
38 0.999 143 64 143 80 145 93 161 94 176 95 192 96 206 97 221 99 236 99 249 100 265 100 264 84 262 74 245 72 231 71 216 69 201 68 187 67 172 65 156 64
38 0.999 143 101 142 119 145 134 161 135 177 136 194 137 210 138 225 139 242 140 256 142 270 143 271 122 270 111 251 109 235 107 220 106 205 105 188 104 172 102 154 100
38 0.999 141 148 143 162 159 163 174 164 188 165 202 166 218 167 232 167 247 169 262 169 276 169 274 154 259 153 245 152 230 150 215 150 200 149 185 147 170 147 155 147
38 0.999 60 225 61 245 64 265 83 265 102 265 122 265 141 266 161 266 180 267 199 268 216 268 216 244 215 228 193 227 174 227 156 226 137 226 117 226 98 225 76 224
38 0.999 0 282 0 284 3 285 7 285 10 285 13 285 17 285 20 285 24 285 26 285 31 282 29 279 25 279 21 279 19 278 15 278 11 278 7 278 3 278 0 279
39 0.999 46 66 47 81 51 100 68 101 83 103 100 105 116 107 133 109 149 111 164 113 179 114 180 96 175 84 159 81 143 79 129 77 113 74 96 71 79 68 61 65
39 0.999 36 150 35 168 48 173 63 174 78 175 94 177 109 178 125 179 141 181 156 182 172 182 174 163 160 160 144 159 130 157 115 156 99 155 83 153 66 151 50 149
40 0.999 34 39 33 43 32 50 31 58 32 65 36 69 42 71 49 72 56 73 62 73 69 74 70 68 71 61 72 53 73 45 71 43 63 42 55 40 48 39 41 38
40 0.999 83 108 85 123 87 141 88 154 103 154 124 152 142 153 159 155 175 162 190 168 202 170 204 155 206 142 199 130 185 125 167 119 151 114 133 110 116 107 97 105
40 0.999 35 129 33 133 34 139 33 146 33 152 33 157 34 162 41 163 47 163 52 163 58 162 58 156 58 150 59 143 60 137 62 130 60 129 53 129 46 128 40 128
40 0.999 87 156 87 171 87 183 99 186 114 188 129 189 143 191 158 193 172 195 186 196 199 198 200 181 200 173 186 169 171 166 158 164 143 161 129 159 115 156 100 155
40 0.999 31 175 30 180 29 187 28 195 27 201 27 208 30 212 38 212 45 213 51 213 57 214 58 208 58 200 58 192 58 185 60 179 57 175 51 175 44 174 36 173
40 0.999 33 225 31 230 31 235 30 242 30 247 30 252 30 258 34 261 40 261 46 262 52 261 53 259 53 253 54 245 54 238 54 232 54 227 51 225 43 224 37 224
40 0.999 62 283 61 291 65 293 72 294 78 295 84 295 91 295 97 296 104 296 110 297 116 297 117 288 113 286 107 285 100 285 94 284 88 283 81 283 75 283 68 282
40 0.999 42 301 50 303 59 304 69 305 78 306 88 306 97 307 108 308 117 309 127 310 131 301 124 298 114 297 105 297 95 296 85 295 75 295 66 294 56 293 46 291
40 0.999 26 303 31 313 43 314 56 315 69 316 81 317 94 318 106 319 119 319 131 319 144 319 139 311 126 310 114 309 102 308 89 307 76 306 64 305 51 303 39 302
41 0.999 497 59 489 59 482 60 475 63 469 65 463 68 457 71 450 74 445 76 443 83 443 89 451 90 456 86 462 84 468 80 475 78 481 76 488 73 495 72 498 66
41 0.999 83 121 81 153 113 163 145 171 177 181 209 191 241 201 272 211 304 220 335 230 368 240 363 214 331 203 300 193 270 182 239 171 208 160 176 150 146 139 115 129
41 0.999 0 160 0 170 6 178 12 184 20 188 30 191 39 193 49 193 58 192 67 188 74 184 71 175 63 174 55 177 45 180 36 178 27 176 19 171 11 166 6 160
41 0.999 164 180 163 200 160 224 179 230 200 235 225 240 248 245 270 250 293 255 314 259 338 264 340 245 337 231 315 223 291 218 271 211 248 205 227 198 206 191 184 184
42 0.999 25 20 36 27 49 27 62 27 75 27 88 27 101 28 116 28 130 28 140 28 152 21 143 17 130 17 117 16 104 16 91 16 77 16 64 16 51 16 39 16
42 0.999 5 51 13 61 33 58 52 55 71 54 89 54 107 55 125 56 146 60 161 64 176 58 167 48 149 44 132 40 113 38 95 37 76 37 58 39 41 41 23 45
42 0.999 5 60 7 76 8 93 8 108 12 122 30 119 48 113 67 110 83 108 97 109 114 109 121 99 122 81 120 73 102 70 86 69 70 67 52 65 37 61 23 60
42 0.999 69 109 66 123 66 136 67 150 72 161 88 161 105 154 119 150 140 149 143 150 156 149 160 139 161 125 158 119 144 117 132 117 118 116 103 114 91 109 80 108
42 0.999 170 157 153 162 135 171 115 181 94 188 74 193 55 197 39 199 22 198 7 214 10 235 32 238 53 237 74 233 95 226 115 219 132 211 151 201 169 192 175 179
42 0.999 131 239 131 242 133 243 136 244 139 243 142 243 145 243 148 243 151 241 152 240 152 235 152 233 149 233 146 233 143 233 140 232 137 232 133 232 132 235 131 238
42 0.999 35 254 45 260 56 261 73 261 90 261 105 261 120 262 135 262 155 263 166 263 171 250 166 242 147 242 133 242 118 241 102 241 87 240 71 240 57 239 41 239
42 0.999 39 264 39 275 47 278 57 278 69 279 79 279 89 280 100 280 113 280 119 279 129 278 130 267 121 265 111 265 100 265 90 265 79 265 69 264 59 264 49 264
42 0.999 31 299 40 301 50 302 61 302 74 302 85 302 95 303 106 304 118 304 128 305 136 298 127 295 116 295 105 294 94 293 83 293 73 293 61 292 50 292 40 292
43 0.999 44 24 44 39 55 43 68 40 85 39 101 40 118 42 133 45 146 59 155 67 163 58 166 40 169 23 153 19 137 13 119 11 101 10 85 11 70 14 50 17
43 0.999 47 47 49 56 58 57 69 56 79 56 90 56 100 56 110 57 120 58 129 60 137 56 136 47 126 45 116 43 106 42 96 42 85 42 75 42 64 43 55 45
43 0.999 37 61 37 75 45 82 59 82 73 82 86 82 99 82 113 83 127 83 140 85 151 85 151 71 144 63 131 62 118 61 104 60 90 60 76
gitextract_9_0bdakf/
├── .gitignore
├── README.md
├── cache/
│ └── README.md
├── cfglib/
│ ├── config.py
│ └── option.py
├── data/
│ ├── ArT/
│ │ └── README.md
│ ├── CTW-1500/
│ │ └── README.md
│ ├── Icdar2015/
│ │ └── README.md
│ ├── LSVT/
│ │ └── README.md
│ ├── MLT-2019/
│ │ └── README.md
│ ├── MLT2017/
│ │ └── README.md
│ ├── README.md
│ ├── SynthText/
│ │ ├── README.md
│ │ └── findPath.sh
│ ├── TD500/
│ │ └── README.md
│ ├── Total-Text/
│ │ └── README.md
│ ├── ctw1500/
│ │ └── README.md
│ └── total-text-mat/
│ └── README.md
├── dataset/
│ ├── CTW1500_Text_New.py
│ ├── Icdar15_Text.py
│ ├── Icdar17_Text.py
│ ├── Icdar19ArT_Json.py
│ ├── Icdar19ArT_Text.py
│ ├── Icdar19LSVT_Json.py
│ ├── Icdar19_Text.py
│ ├── README.md
│ ├── TD500/
│ │ ├── 075eval.sh
│ │ ├── Evaluation_Protocol/
│ │ │ ├── readme.txt
│ │ │ ├── rrc_evaluation_funcs.py
│ │ │ ├── script.py
│ │ │ └── script075.py
│ │ ├── batch_eval.sh
│ │ ├── eval.sh
│ │ └── submit/
│ │ └── res_img_1.txt
│ ├── TD500_Text.py
│ ├── Total_Text.py
│ ├── Total_Text_New.py
│ ├── __init__.py
│ ├── ctw1500/
│ │ ├── Evaluation_Protocol/
│ │ │ ├── ctw1500_eval.py
│ │ │ └── voc_eval_polygon.py
│ │ ├── Evaluation_sort/
│ │ │ └── detections_text0.5.txt
│ │ ├── Readme.md
│ │ └── annots.pkl
│ ├── ctw1500_text.py
│ ├── data_util.py
│ ├── dataload.py
│ ├── deploy.py
│ ├── icdar15/
│ │ ├── 075eval.sh
│ │ ├── Evaluation_Protocol/
│ │ │ ├── readme.txt
│ │ │ ├── rrc_evaluation_funcs.py
│ │ │ ├── script.py
│ │ │ └── script075.py
│ │ ├── batch_eval.sh
│ │ ├── eval.sh
│ │ └── submit/
│ │ └── res_img_1.txt
│ ├── synth-text/
│ │ ├── README.md
│ │ └── make_list.py
│ ├── synth_text.py
│ └── total_text/
│ ├── .gitignore
│ ├── Evaluation_Protocol/
│ │ ├── ComputePrecisionRecall.m
│ │ ├── Eval.m
│ │ ├── Examples/
│ │ │ ├── Groundtruth/
│ │ │ │ ├── poly_gt_img1.mat
│ │ │ │ ├── poly_gt_img2.mat
│ │ │ │ ├── poly_gt_img3.mat
│ │ │ │ ├── poly_gt_img4.mat
│ │ │ │ └── poly_gt_img5.mat
│ │ │ ├── Prediction/
│ │ │ │ ├── img1.mat
│ │ │ │ ├── img2.mat
│ │ │ │ ├── img3.mat
│ │ │ │ ├── img4.mat
│ │ │ │ └── img5.mat
│ │ │ └── Result.txt
│ │ ├── Python_scripts/
│ │ │ ├── Deteval.py
│ │ │ ├── Pascal_VOC.py
│ │ │ ├── __init__.py
│ │ │ ├── polygon_fast.py
│ │ │ └── polygon_wrapper.py
│ │ ├── README.md
│ │ └── __init__.py
│ ├── README.md
│ ├── download.sh
│ └── gdrivedl.sh
├── demo.py
├── demo.sh
├── eval.sh
├── eval_textBPN.py
├── eval_textBPN_speed.py
├── model/
│ └── README.md
├── network/
│ ├── Reg_loss.py
│ ├── Seg_loss.py
│ ├── __init__.py
│ ├── backbone/
│ │ ├── __init__.py
│ │ ├── assets/
│ │ │ └── dcn/
│ │ │ ├── Makefile
│ │ │ ├── Makefile.sh
│ │ │ ├── __init__.py
│ │ │ ├── functions/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deform_conv.py
│ │ │ │ └── deform_pool.py
│ │ │ ├── modules/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deform_conv.py
│ │ │ │ └── deform_pool.py
│ │ │ ├── setup.py
│ │ │ └── src/
│ │ │ ├── deform_conv_cuda.cpp
│ │ │ ├── deform_conv_cuda_kernel.cu
│ │ │ ├── deform_pool_cuda.cpp
│ │ │ └── deform_pool_cuda_kernel.cu
│ │ ├── resnet.py
│ │ └── vgg.py
│ ├── layers/
│ │ ├── Adaptive_Deformation.py
│ │ ├── CircConv.py
│ │ ├── GCN.py
│ │ ├── GraphConv.py
│ │ ├── RNN.py
│ │ ├── Transformer.py
│ │ ├── Transformer_old.py
│ │ ├── __init__.py
│ │ ├── gcn_utils.py
│ │ ├── model_block.py
│ │ ├── position_encoding.py
│ │ ├── resnet.py
│ │ ├── resnet_dcn.py
│ │ └── vgg.py
│ ├── loss.py
│ ├── loss_org.py
│ └── textnet.py
├── output/
│ ├── Analysis/
│ │ ├── ctw1500_eval.txt
│ │ └── totalText_eval.txt
│ └── README.md
├── requirements.txt
├── scripts-eval/
│ ├── Eval_ArT.sh
│ ├── Eval_CTW1500.sh
│ ├── Eval_MLT2017.sh
│ ├── Eval_TD500.sh
│ └── Eval_Totaltext.sh
├── scripts-train/
│ ├── train_ALL_res50_dcn_1s.sh
│ ├── train_Art_res50_1s_fine_mlt.sh
│ ├── train_Art_res50_dcn_1s_fine_mlt.sh
│ ├── train_CTW1500_res18_4s_fine_mlt.sh
│ ├── train_CTW1500_res50_1s.sh
│ ├── train_CTW1500_res50_1s_fine_mlt.sh
│ ├── train_CTW1500_res50_dcn_1s_fine_mlt.sh
│ ├── train_MLT2017_res18_4s.sh
│ ├── train_MLT2017_res50_1s.sh
│ ├── train_MLT2017_res50_dcn_1s.sh
│ ├── train_MLT2019_res50_1s.sh
│ ├── train_SynText_res18_4s.sh
│ ├── train_SynText_res50_1s.sh
│ ├── train_SynText_res50_dcn_1s.sh
│ ├── train_TD500_res18_4s_fine_mlt.sh
│ ├── train_TD500_res50_1s.sh
│ ├── train_TD500_res50_1s_fine_mlt.sh
│ ├── train_TD500_res50_dcn_1s_fine_mlt.sh
│ ├── train_Totaltext_res18_1s.sh
│ ├── train_Totaltext_res18_2s.sh
│ ├── train_Totaltext_res18_4s.sh
│ ├── train_Totaltext_res18_4s_fine_mlt.sh
│ ├── train_Totaltext_res50_1s.sh
│ ├── train_Totaltext_res50_1s_fine_mlt.sh
│ ├── train_Totaltext_res50_4s.sh
│ └── train_Totaltext_res50_dcn_1s_fine_mlt.sh
├── train_textBPN.py
├── train_textBPN_DDP.py
├── util/
│ ├── __init__.py
│ ├── augmentation.py
│ ├── canvas.py
│ ├── detection.py
│ ├── eval.py
│ ├── graph.py
│ ├── io.py
│ ├── logging.py
│ ├── meters.py
│ ├── misc.py
│ ├── pbox.py
│ ├── serialization.py
│ ├── shedule.py
│ ├── strs.py
│ ├── summary.py
│ ├── vis_flux.py
│ └── visualize.py
└── vis/
└── README.md
SYMBOL INDEX (648 symbols across 75 files)
FILE: cfglib/config.py
function update_config (line 69) | def update_config(config, extra_config):
function print_config (line 76) | def print_config(config):
FILE: cfglib/option.py
function str2bool (line 9) | def str2bool(v):
function arg2str (line 13) | def arg2str(args):
class BaseOptions (line 23) | class BaseOptions(object):
method __init__ (line 25) | def __init__(self):
method parse (line 86) | def parse(self, fixed=None):
method initialize (line 95) | def initialize(self, fixed=None):
method update (line 120) | def update(self, args, extra_options):
FILE: dataset/CTW1500_Text_New.py
class Ctw1500Text_New (line 13) | class Ctw1500Text_New(TextDataset):
method __init__ (line 14) | def __init__(self, data_root, is_training=True, load_memory=False, tra...
method parse_carve_txt (line 31) | def parse_carve_txt(gt_path):
method parse_carve_xml (line 49) | def parse_carve_xml(gt_path):
method load_img_gt (line 67) | def load_img_gt(self, item):
method __getitem__ (line 100) | def __getitem__(self, item):
method __len__ (line 113) | def __len__(self):
FILE: dataset/Icdar15_Text.py
class Icdar15Text (line 14) | class Icdar15Text(TextDataset):
method __init__ (line 16) | def __init__(self, data_root, is_training=True, load_memory=False, tra...
method parse_txt (line 37) | def parse_txt(gt_path):
method load_img_gt (line 65) | def load_img_gt(self, item):
method __getitem__ (line 88) | def __getitem__(self, item):
method __len__ (line 102) | def __len__(self):
FILE: dataset/Icdar17_Text.py
class Mlt2017Text (line 13) | class Mlt2017Text(TextDataset):
method __init__ (line 15) | def __init__(self, data_root, is_training=True, load_memory=False, tra...
method parse_txt (line 50) | def parse_txt(gt_path):
method load_img_gt (line 73) | def load_img_gt(self, item):
method __getitem__ (line 104) | def __getitem__(self, item):
method __len__ (line 118) | def __len__(self):
FILE: dataset/Icdar19ArT_Json.py
class ArtTextJson (line 11) | class ArtTextJson(TextDataset):
method __init__ (line 12) | def __init__(self, data_root, is_training=True, ignore_list=None, load...
method preprocess (line 41) | def preprocess(image_list: list, annotation_data: dict):
method parse_curve_txt (line 53) | def parse_curve_txt(self, gt_data):
method load_img_gt (line 65) | def load_img_gt(self, item):
method __getitem__ (line 92) | def __getitem__(self, item):
method __len__ (line 106) | def __len__(self):
FILE: dataset/Icdar19ArT_Text.py
class ArtText (line 16) | class ArtText(TextDataset):
method __init__ (line 18) | def __init__(self, data_root, ignore_list=None, is_training=True, load...
method parse_carve_txt (line 43) | def parse_carve_txt(gt_path):
method load_img_gt (line 63) | def load_img_gt(self, item):
method __getitem__ (line 91) | def __getitem__(self, item):
method __len__ (line 105) | def __len__(self):
FILE: dataset/Icdar19LSVT_Json.py
class LsvtTextJson (line 11) | class LsvtTextJson(TextDataset):
method __init__ (line 12) | def __init__(self, data_root, is_training=True, ignore_list=None,
method preprocess (line 43) | def preprocess(image_list: list, annotation_data: dict):
method parse_curve_txt (line 55) | def parse_curve_txt(self, gt_data):
method load_img_gt (line 67) | def load_img_gt(self, item):
method __getitem__ (line 94) | def __getitem__(self, item):
method __len__ (line 108) | def __len__(self):
FILE: dataset/Icdar19_Text.py
class Mlt2019Text (line 13) | class Mlt2019Text(TextDataset):
method __init__ (line 15) | def __init__(self, data_root, is_training=True, transform=None, load_m...
method parse_txt (line 44) | def parse_txt(gt_path):
method load_img_gt (line 68) | def load_img_gt(self, item):
method __getitem__ (line 99) | def __getitem__(self, item):
method __len__ (line 113) | def __len__(self):
FILE: dataset/TD500/Evaluation_Protocol/rrc_evaluation_funcs.py
function print_help (line 13) | def print_help():
function load_zip_file_keys (line 18) | def load_zip_file_keys(file,fileNameRegExp=''):
function load_zip_file (line 47) | def load_zip_file(file,fileNameRegExp='',allEntries=False):
function decode_utf8 (line 78) | def decode_utf8(raw):
function validate_lines_in_file (line 92) | def validate_lines_in_file(fileName,file_contents,CRLF=True,LTRB=True,wi...
function validate_tl_line (line 111) | def validate_tl_line(line,LTRB=True,withTranscription=True,withConfidenc...
function get_tl_line_values (line 122) | def get_tl_line_values(line,LTRB=True,withTranscription=False,withConfid...
function validate_point_inside_bounds (line 242) | def validate_point_inside_bounds(x,y,imWidth,imHeight):
function validate_clockwise_points (line 248) | def validate_clockwise_points(points):
function get_tl_line_values_from_file_contents (line 273) | def get_tl_line_values_from_file_contents(content,CRLF=True,LTRB=True,wi...
function main_evaluation (line 303) | def main_evaluation(p,default_evaluation_params_fn,validate_data_fn,eval...
function main_validation (line 369) | def main_validation(default_evaluation_params_fn,validate_data_fn):
FILE: dataset/TD500/Evaluation_Protocol/script.py
function evaluation_imports (line 13) | def evaluation_imports():
function default_evaluation_params (line 22) | def default_evaluation_params():
function validate_data (line 37) | def validate_data(gtFilePath, submFilePath,evaluationParams):
function evaluate_method (line 59) | def evaluate_method(gtFilePath, submFilePath, evaluationParams):
FILE: dataset/TD500/Evaluation_Protocol/script075.py
function evaluation_imports (line 7) | def evaluation_imports():
function default_evaluation_params (line 16) | def default_evaluation_params():
function validate_data (line 31) | def validate_data(gtFilePath, submFilePath,evaluationParams):
function evaluate_method (line 53) | def evaluate_method(gtFilePath, submFilePath, evaluationParams):
FILE: dataset/TD500_Text.py
class TD500Text (line 14) | class TD500Text(TextDataset):
method __init__ (line 16) | def __init__(self, data_root, is_training=True, ignore_list=None, load...
method parse_txt (line 37) | def parse_txt(gt_path):
method load_img_gt (line 64) | def load_img_gt(self, item):
method __getitem__ (line 85) | def __getitem__(self, item):
method __len__ (line 112) | def __len__(self):
FILE: dataset/Total_Text.py
class TotalText (line 16) | class TotalText(TextDataset):
method __init__ (line 18) | def __init__(self, data_root, ignore_list=None, is_training=True, load...
method parse_mat (line 43) | def parse_mat(mat_path):
method parse_carve_txt (line 65) | def parse_carve_txt(gt_path):
method load_img_gt (line 96) | def load_img_gt(self, item):
method __getitem__ (line 116) | def __getitem__(self, item):
method __len__ (line 141) | def __len__(self):
FILE: dataset/Total_Text_New.py
class TotalText_New (line 13) | class TotalText_New(TextDataset):
method __init__ (line 15) | def __init__(self, data_root, ignore_list=None, is_training=True,
method parse_mat (line 48) | def parse_mat(mat_path):
method load_img_gt (line 66) | def load_img_gt(self, item):
method __getitem__ (line 86) | def __getitem__(self, item):
method __len__ (line 111) | def __len__(self):
FILE: dataset/ctw1500/Evaluation_Protocol/voc_eval_polygon.py
function parse_rec_txt (line 17) | def parse_rec_txt(filename):
function curve_parse_rec_txt (line 34) | def curve_parse_rec_txt(filename):
function voc_ap (line 52) | def voc_ap(rec, prec, use_07_metric=False):
function voc_eval_polygon (line 86) | def voc_eval_polygon(detpath,
FILE: dataset/ctw1500_text.py
class Ctw1500Text (line 12) | class Ctw1500Text(TextDataset):
method __init__ (line 13) | def __init__(self, data_root, is_training=True, load_memory=False, tra...
method parse_carve_txt (line 30) | def parse_carve_txt(gt_path):
method load_img_gt (line 49) | def load_img_gt(self, item):
method __getitem__ (line 76) | def __getitem__(self, item):
method __len__ (line 90) | def __len__(self):
FILE: dataset/data_util.py
function pil_load_img (line 9) | def pil_load_img(path):
FILE: dataset/dataload.py
function pil_load_img (line 14) | def pil_load_img(path):
class TextInstance (line 20) | class TextInstance(object):
method __init__ (line 21) | def __init__(self, points, orient, text):
method find_bottom_and_sideline (line 50) | def find_bottom_and_sideline(self):
method get_sample_point (line 54) | def get_sample_point(self, size=None):
method get_control_points (line 61) | def get_control_points(self, size=None):
method __repr__ (line 82) | def __repr__(self):
method __getitem__ (line 85) | def __getitem__(self, item):
class TextDataset (line 89) | class TextDataset(object):
method __init__ (line 91) | def __init__(self, transform, is_training=False):
method sigmoid_alpha (line 100) | def sigmoid_alpha(x, k):
method fill_polygon (line 107) | def fill_polygon(mask, pts, value):
method generate_proposal_point (line 120) | def generate_proposal_point(text_mask, num_points, approx_factor, jitt...
method compute_direction_field (line 140) | def compute_direction_field(inst_mask, h, w):
method make_text_region (line 159) | def make_text_region(self, img, polygons):
method get_training_data (line 217) | def get_training_data(self, image, polygons, image_id=None, image_path...
method get_test_data (line 243) | def get_test_data(self, image, polygons=None, image_id=None, image_pat...
method __len__ (line 277) | def __len__(self):
FILE: dataset/deploy.py
class DeployDataset (line 11) | class DeployDataset(TextDataset):
method __init__ (line 13) | def __init__(self, image_root, transform=None):
method __getitem__ (line 18) | def __getitem__(self, item):
method __len__ (line 27) | def __len__(self):
FILE: dataset/icdar15/Evaluation_Protocol/rrc_evaluation_funcs.py
function print_help (line 12) | def print_help():
function load_zip_file_keys (line 17) | def load_zip_file_keys(file,fileNameRegExp=''):
function load_zip_file (line 46) | def load_zip_file(file,fileNameRegExp='',allEntries=False):
function decode_utf8 (line 77) | def decode_utf8(raw):
function validate_lines_in_file (line 91) | def validate_lines_in_file(fileName,file_contents,CRLF=True,LTRB=True,wi...
function validate_tl_line (line 110) | def validate_tl_line(line,LTRB=True,withTranscription=True,withConfidenc...
function get_tl_line_values (line 121) | def get_tl_line_values(line,LTRB=True,withTranscription=False,withConfid...
function validate_point_inside_bounds (line 221) | def validate_point_inside_bounds(x,y,imWidth,imHeight):
function validate_clockwise_points (line 227) | def validate_clockwise_points(points):
function get_tl_line_values_from_file_contents (line 252) | def get_tl_line_values_from_file_contents(content,CRLF=True,LTRB=True,wi...
function main_evaluation (line 280) | def main_evaluation(p,default_evaluation_params_fn,validate_data_fn,eval...
function main_validation (line 348) | def main_validation(default_evaluation_params_fn,validate_data_fn):
FILE: dataset/icdar15/Evaluation_Protocol/script.py
function evaluation_imports (line 13) | def evaluation_imports():
function default_evaluation_params (line 22) | def default_evaluation_params():
function validate_data (line 37) | def validate_data(gtFilePath, submFilePath,evaluationParams):
function evaluate_method (line 59) | def evaluate_method(gtFilePath, submFilePath, evaluationParams):
FILE: dataset/icdar15/Evaluation_Protocol/script075.py
function evaluation_imports (line 8) | def evaluation_imports():
function default_evaluation_params (line 17) | def default_evaluation_params():
function validate_data (line 32) | def validate_data(gtFilePath, submFilePath,evaluationParams):
function evaluate_method (line 54) | def evaluate_method(gtFilePath, submFilePath, evaluationParams):
FILE: dataset/synth_text.py
class SynthText (line 9) | class SynthText(TextDataset):
method __init__ (line 11) | def __init__(self, data_root, is_training=True, load_memory=False, tra...
method parse_txt (line 28) | def parse_txt(annotation_path):
method load_img_gt (line 41) | def load_img_gt(self, item):
method __getitem__ (line 59) | def __getitem__(self, item):
method __len__ (line 73) | def __len__(self):
FILE: dataset/total_text/Evaluation_Protocol/Python_scripts/Deteval.py
function input_reading_mod (line 39) | def input_reading_mod(input_dir, input):
function gt_reading_mod (line 47) | def gt_reading_mod(gt_dir, gt_id):
function detection_filtering (line 55) | def detection_filtering(detections, groundtruths, threshold=0.5):
function sigma_calculation (line 72) | def sigma_calculation(det_x, det_y, gt_x, gt_y):
function tau_calculation (line 78) | def tau_calculation(det_x, det_y, gt_x, gt_y):
function one_to_one (line 133) | def one_to_one(local_sigma_table, local_tau_table, local_accumulative_re...
function one_to_many (line 154) | def one_to_many(local_sigma_table, local_tau_table, local_accumulative_r...
function many_to_many (line 193) | def many_to_many(local_sigma_table, local_tau_table, local_accumulative_...
FILE: dataset/total_text/Evaluation_Protocol/Python_scripts/Pascal_VOC.py
function input_reading_mod (line 19) | def input_reading_mod(input_dir, input):
function gt_reading_mod (line 27) | def gt_reading_mod(gt_dir, gt_id):
function detection_filtering (line 33) | def detection_filtering(detections, groundtruths, threshold=0.5):
FILE: dataset/total_text/Evaluation_Protocol/Python_scripts/polygon_fast.py
function area (line 20) | def area(x, y):
function approx_area_of_intersection (line 25) | def approx_area_of_intersection(det_x, det_y, gt_x, gt_y):
function area_of_intersection (line 51) | def area_of_intersection(det_x, det_y, gt_x, gt_y):
function area_of_union (line 56) | def area_of_union(det_x, det_y, gt_x, gt_y):
function iou (line 62) | def iou(det_x, det_y, gt_x, gt_y):
function iod (line 66) | def iod(det_x, det_y, gt_x, gt_y):
FILE: dataset/total_text/Evaluation_Protocol/Python_scripts/polygon_wrapper.py
function area (line 18) | def area(x, y):
function approx_area_of_intersection (line 33) | def approx_area_of_intersection(det_x, det_y, gt_x, gt_y):
function shapely_area_of_intersection (line 59) | def shapely_area_of_intersection(det_x, det_y, gt_x, gt_y):
function shapely_area (line 64) | def shapely_area(x, y):
function area_of_intersection (line 68) | def area_of_intersection(det_x, det_y, gt_x, gt_y):
function iou (line 96) | def iou(det_x, det_y, gt_x, gt_y):
function iod (line 128) | def iod(det_x, det_y, gt_x, gt_y):
FILE: demo.py
function osmkdir (line 21) | def osmkdir(out_dir):
function write_to_file (line 28) | def write_to_file(contours, file_path):
function inference (line 44) | def inference(model, test_loader, output_dir):
function main (line 117) | def main(vis_dir_path):
FILE: eval_textBPN.py
function osmkdir (line 26) | def osmkdir(out_dir):
function write_to_file (line 33) | def write_to_file(contours, file_path):
function inference (line 49) | def inference(model, test_loader, output_dir):
function main (line 164) | def main(vis_dir_path):
FILE: eval_textBPN_speed.py
function osmkdir (line 18) | def osmkdir(out_dir):
function inference (line 25) | def inference(model, test_loader, output_dir):
function main (line 54) | def main(vis_dir_path):
FILE: network/Reg_loss.py
class PolyMatchingLoss (line 10) | class PolyMatchingLoss(nn.Module):
method __init__ (line 11) | def __init__(self, pnum, device, loss_type="L1"):
method match_loss (line 31) | def match_loss(self, pred, gt):
method forward (line 49) | def forward(self, pred_list, gt):
class AttentionLoss (line 70) | class AttentionLoss(nn.Module):
method __init__ (line 71) | def __init__(self, beta=4, gamma=0.5):
method forward (line 77) | def forward(self, pred, gt):
class GeoCrossEntropyLoss (line 90) | class GeoCrossEntropyLoss(nn.Module):
method __init__ (line 91) | def __init__(self):
method forward (line 94) | def forward(self, output, target, poly):
class AELoss (line 106) | class AELoss(nn.Module):
method __init__ (line 107) | def __init__(self):
method forward (line 110) | def forward(self, ae, ind, ind_mask):
function smooth_l1_loss (line 147) | def smooth_l1_loss(inputs, target, sigma=9.0):
function _neg_loss (line 161) | def _neg_loss(pred, gt):
class FocalLoss (line 189) | class FocalLoss(nn.Module):
method __init__ (line 191) | def __init__(self):
method forward (line 195) | def forward(self, out, target):
FILE: network/Seg_loss.py
class SegmentLoss (line 9) | class SegmentLoss(nn.Module):
method __init__ (line 10) | def __init__(self, Lambda, ratio=3, reduction='mean'):
method forward (line 19) | def forward(self, outputs, labels, training_masks, th=0.5):
method dice_loss (line 54) | def dice_loss(self, input, target, mask):
method ohem_single (line 70) | def ohem_single(self, score, gt_text, training_mask, th=0.5):
method ohem_batch (line 96) | def ohem_batch(self, scores, gt_texts, training_masks):
FILE: network/backbone/assets/dcn/functions/deform_conv.py
class DeformConvFunction (line 8) | class DeformConvFunction(Function):
method forward (line 11) | def forward(ctx,
method backward (line 55) | def backward(ctx, grad_output):
method _output_size (line 92) | def _output_size(input, weight, padding, dilation, stride):
class ModulatedDeformConvFunction (line 108) | class ModulatedDeformConvFunction(Function):
method forward (line 111) | def forward(ctx,
method backward (line 146) | def backward(ctx, grad_output):
method _infer_shape (line 168) | def _infer_shape(ctx, input, weight):
FILE: network/backbone/assets/dcn/functions/deform_pool.py
class DeformRoIPoolingFunction (line 7) | class DeformRoIPoolingFunction(Function):
method forward (line 10) | def forward(ctx,
method backward (line 50) | def backward(ctx, grad_output):
FILE: network/backbone/assets/dcn/modules/deform_conv.py
class DeformConv (line 10) | class DeformConv(nn.Module):
method __init__ (line 12) | def __init__(self,
method reset_parameters (line 47) | def reset_parameters(self):
method forward (line 54) | def forward(self, x, offset):
class DeformConvPack (line 59) | class DeformConvPack(DeformConv):
method __init__ (line 61) | def __init__(self, *args, **kwargs):
method init_offset (line 74) | def init_offset(self):
method forward (line 78) | def forward(self, x):
class ModulatedDeformConv (line 84) | class ModulatedDeformConv(nn.Module):
method __init__ (line 86) | def __init__(self,
method reset_parameters (line 116) | def reset_parameters(self):
method forward (line 125) | def forward(self, x, offset, mask):
class ModulatedDeformConvPack (line 131) | class ModulatedDeformConvPack(ModulatedDeformConv):
method __init__ (line 133) | def __init__(self, *args, **kwargs):
method init_offset (line 146) | def init_offset(self):
method forward (line 150) | def forward(self, x):
FILE: network/backbone/assets/dcn/modules/deform_pool.py
class DeformRoIPooling (line 6) | class DeformRoIPooling(nn.Module):
method __init__ (line 8) | def __init__(self,
method forward (line 27) | def forward(self, data, rois, offset):
class DeformRoIPoolingPack (line 36) | class DeformRoIPoolingPack(DeformRoIPooling):
method __init__ (line 38) | def __init__(self,
method forward (line 72) | def forward(self, data, rois):
class ModulatedDeformRoIPoolingPack (line 95) | class ModulatedDeformRoIPoolingPack(DeformRoIPooling):
method __init__ (line 97) | def __init__(self,
method forward (line 150) | def forward(self, data, rois):
FILE: network/backbone/assets/dcn/src/deform_conv_cuda.cpp
function shape_check (line 61) | void shape_check(at::Tensor input, at::Tensor offset, at::Tensor *gradOu...
function deform_conv_forward_cuda (line 150) | int deform_conv_forward_cuda(at::Tensor input, at::Tensor weight,
function deform_conv_backward_input_cuda (line 259) | int deform_conv_backward_input_cuda(at::Tensor input, at::Tensor offset,
function deform_conv_backward_parameters_cuda (line 372) | int deform_conv_backward_parameters_cuda(
function modulated_deform_conv_cuda_forward (line 484) | void modulated_deform_conv_cuda_forward(
function modulated_deform_conv_cuda_backward (line 564) | void modulated_deform_conv_cuda_backward(
function PYBIND11_MODULE (line 679) | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
FILE: network/backbone/assets/dcn/src/deform_pool_cuda.cpp
function deform_psroi_pooling_cuda_forward (line 30) | void deform_psroi_pooling_cuda_forward(
function deform_psroi_pooling_cuda_backward (line 54) | void deform_psroi_pooling_cuda_backward(
function PYBIND11_MODULE (line 81) | PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
FILE: network/backbone/resnet.py
function constant_init (line 19) | def constant_init(module, constant, bias=0):
function conv3x3 (line 25) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 31) | class BasicBlock(nn.Module):
method __init__ (line 34) | def __init__(self, inplanes, planes, stride=1, downsample=None, dcn=No...
method forward (line 74) | def forward(self, x):
class Bottleneck (line 103) | class Bottleneck(nn.Module):
method __init__ (line 106) | def __init__(self, inplanes, planes, stride=1, downsample=None, dcn=No...
method forward (line 145) | def forward(self, x):
class ResNet (line 178) | class ResNet(nn.Module):
method __init__ (line 179) | def __init__(self, block, layers, num_classes=1000,
method _make_layer (line 215) | def _make_layer(self, block, planes, blocks, stride=1, dcn=None):
method forward (line 233) | def forward(self, x):
function resnet18 (line 247) | def resnet18(pretrained=True, **kwargs):
function deformable_resnet18 (line 258) | def deformable_resnet18(pretrained=True, **kwargs):
function resnet34 (line 274) | def resnet34(pretrained=True, **kwargs):
function resnet50 (line 286) | def resnet50(pretrained=True, **kwargs):
function deformable_resnet50 (line 298) | def deformable_resnet50(pretrained=True, **kwargs):
function resnet101 (line 315) | def resnet101(pretrained=True, **kwargs):
function resnet152 (line 327) | def resnet152(pretrained=True, **kwargs):
FILE: network/backbone/vgg.py
class VggNet (line 15) | class VggNet(nn.Module):
method __init__ (line 16) | def __init__(self, name="vgg16", pretrain=True):
method forward (line 41) | def forward(self, x):
FILE: network/layers/Adaptive_Deformation.py
class MeanAggregator (line 16) | class MeanAggregator(nn.Module):
method __init__ (line 17) | def __init__(self):
method forward (line 20) | def forward(self, features, A):
class GraphConv (line 25) | class GraphConv(nn.Module):
method __init__ (line 26) | def __init__(self, in_dim, out_dim, agg):
method forward (line 36) | def forward(self, features, A):
class AdaptiveDeformation (line 46) | class AdaptiveDeformation(nn.Module):
method __init__ (line 47) | def __init__(self, input, state_dim):
method forward (line 66) | def forward(self, x, A):
FILE: network/layers/CircConv.py
class CircConv (line 5) | class CircConv(nn.Module):
method __init__ (line 6) | def __init__(self, state_dim, out_state_dim=None, n_adj=4):
method forward (line 13) | def forward(self, input, adj):
class DilatedCircConv (line 18) | class DilatedCircConv(nn.Module):
method __init__ (line 19) | def __init__(self, state_dim, out_state_dim=None, n_adj=4, dilation=1):
method forward (line 27) | def forward(self, input, adj):
class BasicBlock (line 39) | class BasicBlock(nn.Module):
method __init__ (line 40) | def __init__(self, state_dim, out_state_dim, conv_type, n_adj=4, dilat...
method forward (line 47) | def forward(self, x, adj=None):
class DeepSnake (line 54) | class DeepSnake(nn.Module):
method __init__ (line 55) | def __init__(self, state_dim, feature_dim, conv_type='dgrid'):
method forward (line 76) | def forward(self, x, adj):
FILE: network/layers/GCN.py
class MeanAggregator (line 16) | class MeanAggregator(nn.Module):
method __init__ (line 17) | def __init__(self):
method forward (line 20) | def forward(self, features, A):
class GraphConv (line 25) | class GraphConv(nn.Module):
method __init__ (line 26) | def __init__(self, in_dim, out_dim, agg):
method forward (line 36) | def forward(self, features, A):
class GCN (line 46) | class GCN(nn.Module):
method __init__ (line 47) | def __init__(self, in_dim, out_dim):
method forward (line 63) | def forward(self, x, A):
FILE: network/layers/GraphConv.py
class GraphConvolution (line 9) | class GraphConvolution(Module):
method __init__ (line 14) | def __init__(self, in_features, out_features, bias=True):
method reset_parameters (line 28) | def reset_parameters(self):
method forward (line 34) | def forward(self, input, adj):
method __repr__ (line 42) | def __repr__(self):
FILE: network/layers/RNN.py
class RNN (line 16) | class RNN(nn.Module):
method __init__ (line 17) | def __init__(self, input, state_dim):
method forward (line 28) | def forward(self, x, adj):
FILE: network/layers/Transformer.py
class Positional_encoding (line 11) | class Positional_encoding(nn.Module):
method __init__ (line 12) | def __init__(self, PE_size, n_position=256):
method get_encoding_table (line 18) | def get_encoding_table(self, n_position, PE_size):
method forward (line 25) | def forward(self, inputs):
class MultiHeadAttention (line 29) | class MultiHeadAttention(nn.Module):
method __init__ (line 30) | def __init__(self, num_heads, embed_dim, dropout=0.1, if_resi=True):
method forward (line 39) | def forward(self, inputs):
class FeedForward (line 53) | class FeedForward(nn.Module):
method __init__ (line 54) | def __init__(self, in_channel, FFN_channel, if_resi=True):
method forward (line 65) | def forward(self, inputs):
class TransformerLayer (line 76) | class TransformerLayer(nn.Module):
method __init__ (line 77) | def __init__(self, out_dim, in_dim, num_heads, attention_size,
method forward (line 88) | def forward(self, query):
class Transformer (line 102) | class Transformer(nn.Module):
method __init__ (line 104) | def __init__(self, in_dim, out_dim, num_heads=8,
method forward (line 125) | def forward(self, x, adj):
FILE: network/layers/Transformer_old.py
class Positional_encoding (line 14) | class Positional_encoding(nn.Module):
method __init__ (line 15) | def __init__(self, PE_size, n_position=200):
method get_encoding_table (line 21) | def get_encoding_table(self, n_position, PE_size):
method forward (line 28) | def forward(self, inputs):
class MultiHeadAttention (line 32) | class MultiHeadAttention(nn.Module):
method __init__ (line 33) | def __init__(self, num_heads, embedding_size, attention_size,
method forward (line 50) | def forward(self, query, key, value):
class FeedForward (line 91) | class FeedForward(nn.Module):
method __init__ (line 92) | def __init__(self, in_channel, FFN_channel, if_resi=True):
method forward (line 103) | def forward(self, inputs):
class TransformerLayer (line 114) | class TransformerLayer(nn.Module):
method __init__ (line 115) | def __init__(self, out_dim, num_heads, embedding_size, attention_size,
method forward (line 125) | def forward(self, query):
class Transformer (line 133) | class Transformer(nn.Module):
method __init__ (line 135) | def __init__(self, in_dim, out_dim, num_heads=8,
method forward (line 157) | def forward(self, x, adj):
FILE: network/layers/gcn_utils.py
function normalize_adj (line 10) | def normalize_adj(A, type="AD"):
function np_to_variable (line 32) | def np_to_variable(x, is_cuda=True, dtype=torch.FloatTensor):
function set_trainable (line 39) | def set_trainable(model, requires_grad):
function weights_normal_init (line 44) | def weights_normal_init(model, dev=0.01):
function clip_gradient (line 56) | def clip_gradient(model, clip_norm):
function EuclideanDistances (line 71) | def EuclideanDistances(A, B):
function get_center_feature (line 87) | def get_center_feature(cnn_feature, img_poly, ind, h, w):
function get_node_feature (line 96) | def get_node_feature(cnn_feature, img_poly, ind, h, w):
function get_adj_mat (line 109) | def get_adj_mat(n_adj, n_nodes):
function get_adj_ind (line 120) | def get_adj_ind(n_adj, n_nodes, device):
function coord_embedding (line 126) | def coord_embedding(b, w, h, device):
function img_poly_to_can_poly (line 137) | def img_poly_to_can_poly(img_poly):
FILE: network/layers/model_block.py
class UpBlok (line 12) | class UpBlok(nn.Module):
method __init__ (line 14) | def __init__(self, in_channels, out_channels):
method forward (line 20) | def forward(self, upsampled, shortcut):
class MergeBlok (line 41) | class MergeBlok(nn.Module):
method __init__ (line 42) | def __init__(self, in_channels, out_channels):
method forward (line 47) | def forward(self, upsampled, shortcut):
class FPN (line 61) | class FPN(nn.Module):
method __init__ (line 63) | def __init__(self, backbone='resnet50', is_training=True):
method forward (line 144) | def forward(self, x):
FILE: network/layers/position_encoding.py
class PositionEmbeddingSine (line 12) | class PositionEmbeddingSine(nn.Module):
method __init__ (line 17) | def __init__(self, num_pos_feats=64, temperature=10000, normalize=Fals...
method forward (line 28) | def forward(self, tensor_list: NestedTensor):
class PositionEmbeddingLearned (line 51) | class PositionEmbeddingLearned(nn.Module):
method __init__ (line 55) | def __init__(self, num_pos_feats=256):
method reset_parameters (line 61) | def reset_parameters(self):
method forward (line 65) | def forward(self, tensor_list: NestedTensor):
function build_position_encoding (line 79) | def build_position_encoding(args):
FILE: network/layers/resnet.py
class ResNet (line 17) | class ResNet(nn.Module):
method __init__ (line 18) | def __init__(self, name="resnet50", pretrain=True):
method forward (line 50) | def forward(self, x):
FILE: network/layers/resnet_dcn.py
class ResNet_DCN (line 17) | class ResNet_DCN(nn.Module):
method __init__ (line 18) | def __init__(self, name="deformable_resnet18", pretrain=False):
method forward (line 42) | def forward(self, x):
FILE: network/layers/vgg.py
class VggNet (line 16) | class VggNet(nn.Module):
method __init__ (line 17) | def __init__(self, name="vgg16", pretrain=True):
method forward (line 43) | def forward(self, x):
FILE: network/loss.py
class TextLoss (line 12) | class TextLoss(nn.Module):
method __init__ (line 14) | def __init__(self):
method single_image_loss (line 22) | def single_image_loss(pre_loss, loss_label):
method cls_ohem (line 50) | def cls_ohem(self, predict, target, train_mask, negative_ratio=3.):
method loss_calc_flux (line 68) | def loss_calc_flux(pred_flux, gt_flux, weight_matrix, mask, train_mask):
method get_poly_energy (line 87) | def get_poly_energy(energy_field, img_poly, ind, h, w):
method loss_energy_regularization (line 99) | def loss_energy_regularization(self, energy_field, img_poly, inds, h, w):
method forward (line 113) | def forward(self, input_dict, output_dict, eps=None):
FILE: network/loss_org.py
class TextLoss (line 11) | class TextLoss(nn.Module):
method __init__ (line 13) | def __init__(self):
method single_image_loss (line 21) | def single_image_loss(pre_loss, loss_label):
method cls_ohem (line 49) | def cls_ohem(self, predict, target, train_mask, negative_ratio=3.):
method loss_calc_flux (line 68) | def loss_calc_flux(pred_flux, gt_flux, weight_matrix, mask, train_mask):
method forward (line 85) | def forward(self, input_dict, output_dict, eps=None):
FILE: network/textnet.py
class Evolution (line 23) | class Evolution(nn.Module):
method __init__ (line 24) | def __init__(self, node_num, adj_num, is_training=True, device=None, m...
method get_boundary_proposal (line 76) | def get_boundary_proposal(input=None, seg_preds=None, switch="gt"):
method get_boundary_proposal_eval (line 101) | def get_boundary_proposal_eval(self, input=None, seg_preds=None):
method evolve_poly (line 139) | def evolve_poly(self, snake, cnn_feature, i_it_poly, ind):
method forward (line 152) | def forward(self, embed_feature, input=None, seg_preds=None, switch="g...
class TextNet (line 170) | class TextNet(nn.Module):
method __init__ (line 172) | def __init__(self, backbone='vgg', is_training=True):
method load_model (line 188) | def load_model(self, model_path):
method forward (line 198) | def forward(self, input_dict, test_speed=False):
FILE: train_textBPN.py
function save_model (line 31) | def save_model(model, epoch, lr, optimzer):
function load_model (line 48) | def load_model(model, model_path):
function _parse_data (line 54) | def _parse_data(inputs):
function train (line 70) | def train(model, train_loader, criterion, scheduler, optimizer, epoch):
function main (line 135) | def main():
FILE: train_textBPN_DDP.py
class WarmupScheduler (line 31) | class WarmupScheduler(lr_scheduler._LRScheduler):
method __init__ (line 32) | def __init__(self, optimizer, warmup_epochs, base_lr, final_lr, after_...
method get_last_lr (line 39) | def get_last_lr(self):
method step (line 49) | def step(self, epoch=None):
function save_model (line 63) | def save_model(model, epoch, lr, optimizer):
function load_model (line 78) | def load_model(model, model_path):
function _parse_data (line 84) | def _parse_data(inputs):
function train (line 99) | def train(model, train_loader, criterion, scheduler, optimizer, epoch, s...
function main (line 179) | def main():
FILE: util/augmentation.py
function crop_first (line 17) | def crop_first(image, polygons, scale =10):
class Compose (line 54) | class Compose(object):
method __init__ (line 65) | def __init__(self, transforms):
method __call__ (line 68) | def __call__(self, img, pts=None):
class Normalize (line 74) | class Normalize(object):
method __init__ (line 75) | def __init__(self, mean, std):
method __call__ (line 79) | def __call__(self, image, polygons=None):
class MinusMean (line 87) | class MinusMean(object):
method __init__ (line 88) | def __init__(self, mean):
method __call__ (line 91) | def __call__(self, image, polygons=None):
class RandomMirror (line 97) | class RandomMirror(object):
method __init__ (line 99) | def __init__(self):
method __call__ (line 102) | def __call__(self, image, polygons=None):
class AugmentColor (line 113) | class AugmentColor(object):
method __init__ (line 115) | def __init__(self):
method __call__ (line 123) | def __call__(self, img, polygons=None):
class RandomContrast (line 136) | class RandomContrast(object):
method __init__ (line 137) | def __init__(self, lower=0.5, upper=1.5):
method __call__ (line 144) | def __call__(self, image, polygons=None):
class RandomBrightness (line 151) | class RandomBrightness(object):
method __init__ (line 152) | def __init__(self, delta=32):
method __call__ (line 157) | def __call__(self, image, polygons=None):
class RandomErasing (line 165) | class RandomErasing(object):
method __init__ (line 166) | def __init__(self, sr=(0.0004, 0.01), scale=(0.5, 3), ratio=0.2, Type ...
method __call__ (line 177) | def __call__(self, img, polygons=None):
class RandomMixUp (line 201) | class RandomMixUp(object):
method __init__ (line 202) | def __init__(self, mixup_alpha=2):
method __call__ (line 205) | def __call__(self, img1, img2, label1=[], label2=[]):
class Rotate (line 225) | class Rotate(object):
method __init__ (line 226) | def __init__(self, up=30):
method rotate (line 230) | def rotate(center, pt, theta): # 二维图形学的旋转
method __call__ (line 245) | def __call__(self, img, polygons=None):
class RotatePadding (line 261) | class RotatePadding(object):
method __init__ (line 262) | def __init__(self, up=60,colors=True):
method rotate (line 268) | def rotate(center, pt, theta, movSize=[0, 0], scale=1): # 二维图形学的旋转
method shift (line 287) | def shift(size, degree):
method __call__ (line 300) | def __call__(self, image, polygons=None, scale=1.0):
class SquarePadding (line 334) | class SquarePadding(object):
method __call__ (line 336) | def __call__(self, image, polygons=None):
class RandomImgCropPatch (line 362) | class RandomImgCropPatch(object):
method __init__ (line 363) | def __init__(self, up=30, beta=0.3):
method get_contour_min_area_box (line 369) | def get_contour_min_area_box(contour):
method CropWH (line 375) | def CropWH(self, image, cut_w, cut_h, polygons=None):
method __call__ (line 405) | def __call__(self, images, polygons_list=None):
class RandomCropFlip (line 435) | class RandomCropFlip(object):
method __init__ (line 437) | def __init__(self, min_crop_side_ratio=0.01):
method __call__ (line 443) | def __call__(self, image, polygons=None):
class RandomResizedCrop (line 530) | class RandomResizedCrop(object):
method __init__ (line 531) | def __init__(self, min_crop_side_ratio=0.1):
method __call__ (line 536) | def __call__(self, image, polygons):
class RandomResizeScale (line 603) | class RandomResizeScale(object):
method __init__ (line 604) | def __init__(self, size=512, ratio=(3./4, 5./2)):
method __call__ (line 608) | def __call__(self, image, polygons=None):
class Resize (line 624) | class Resize(object):
method __init__ (line 625) | def __init__(self, size=1024):
method __call__ (line 629) | def __call__(self, image, polygons=None):
class ResizeSquare (line 642) | class ResizeSquare(object):
method __init__ (line 643) | def __init__(self, size=(480, 1280)):
method __call__ (line 646) | def __call__(self, image, polygons=None):
class ResizeLimitSquare (line 675) | class ResizeLimitSquare(object):
method __init__ (line 676) | def __init__(self, size=512, ratio=0.6):
method __call__ (line 681) | def __call__(self, image, polygons=None):
class RandomResizePadding (line 695) | class RandomResizePadding(object):
method __init__ (line 696) | def __init__(self, size=512, random_scale=np.array([0.75, 1.0, 1.25,1....
method __call__ (line 711) | def __call__(self, image, polygons=None):
class RandomDistortion (line 731) | class RandomDistortion(object):
method __init__ (line 732) | def __init__(self, transform_dict, prob=0.5):
method __call__ (line 736) | def __call__(self, img, target):
class Augmentation (line 749) | class Augmentation(object):
method __init__ (line 750) | def __init__(self, size, mean, std):
method __call__ (line 766) | def __call__(self, image, polygons=None):
class BaseTransform (line 770) | class BaseTransform(object):
method __init__ (line 771) | def __init__(self, size, mean, std):
method __call__ (line 781) | def __call__(self, image, polygons=None):
class BaseTransformNresize (line 785) | class BaseTransformNresize(object):
method __init__ (line 786) | def __init__(self, mean, std):
method __call__ (line 793) | def __call__(self, image, polygons=None):
FILE: util/canvas.py
function heatmap (line 10) | def heatmap(im_gray):
function loss_ploy (line 20) | def loss_ploy(loss_list, steps, period, name=""):
function plt_ploys (line 30) | def plt_ploys(ploys, period, name=""):
FILE: util/detection.py
class TextDetector (line 6) | class TextDetector(object):
method __init__ (line 8) | def __init__(self, model):
method detect (line 16) | def detect(self, image, img_show):
FILE: util/eval.py
function osmkdir (line 9) | def osmkdir(out_dir):
function analysize_result (line 16) | def analysize_result(source_dir, fid_path, outpt_dir, name):
function deal_eval_total_text (line 44) | def deal_eval_total_text(debug=False):
function deal_eval_ctw1500 (line 81) | def deal_eval_ctw1500(debug=False):
function deal_eval_icdar15 (line 105) | def deal_eval_icdar15(debug=False):
function deal_eval_TD500 (line 134) | def deal_eval_TD500(debug=False):
function data_transfer_ICDAR (line 161) | def data_transfer_ICDAR(contours):
function data_transfer_TD500 (line 175) | def data_transfer_TD500(contours, res_file, img=None):
function data_transfer_MLT2017 (line 210) | def data_transfer_MLT2017(contours, res_file):
FILE: util/graph.py
class Data (line 9) | class Data(object):
method __init__ (line 10) | def __init__(self, name):
method name (line 15) | def name(self):
method links (line 19) | def links(self):
method add_link (line 22) | def add_link(self, other, score):
function connected_components (line 27) | def connected_components(nodes, score_dict, th):
function connected_components_constraint (line 51) | def connected_components_constraint(nodes, max_sz, score_dict=None, th=N...
function graph_propagation_naive (line 84) | def graph_propagation_naive(edges, score, th, bboxs=None, dis_thresh=50,...
function graph_search (line 129) | def graph_search(edges, scores, edges_num, th=None):
function graph_propagation (line 156) | def graph_propagation(edges, score, max_sz, step=0.1, beg_th=0.5, pool=N...
function graph_propagation_soft (line 202) | def graph_propagation_soft(edges, score, max_sz, step=0.1, **kwargs):
function diffusion (line 240) | def diffusion(vertex, label, score_dict, max_depth=5, weight_decay=0.6, ...
function clusters2labels (line 290) | def clusters2labels(clusters, n_nodes):
function single_remove (line 299) | def single_remove(bbox, pred):
FILE: util/io.py
function mkdir (line 17) | def mkdir(path):
function make_parent_dir (line 26) | def make_parent_dir(path):
function pwd (line 32) | def pwd():
function dump (line 35) | def dump(path, obj):
function load (line 43) | def load(path):
function join_path (line 49) | def join_path(a, *p):
function is_dir (line 52) | def is_dir(path):
function is_path (line 58) | def is_path(path):
function get_dir (line 62) | def get_dir(path):
function get_parent_dir (line 72) | def get_parent_dir(path):
function get_filename (line 76) | def get_filename(path):
function get_absolute_path (line 79) | def get_absolute_path(p):
function cd (line 84) | def cd(p):
function ls (line 88) | def ls(path = '.', suffix = None):
function find_files (line 106) | def find_files(pattern):
function read_lines (line 110) | def read_lines(p):
function write_lines (line 116) | def write_lines(p, lines, append_break = False):
function cat (line 126) | def cat(p):
function exists (line 131) | def exists(path):
function not_exists (line 135) | def not_exists(path):
function load_mat (line 138) | def load_mat(path):
function dump_mat (line 143) | def dump_mat(path, dict_obj, append = True):
function dir_mat (line 149) | def dir_mat(path):
function get_file_size (line 161) | def get_file_size(path, unit = SIZE_UNIT_K):
function create_h5 (line 166) | def create_h5(path):
function open_h5 (line 172) | def open_h5(path, mode = 'r'):
function read_h5 (line 177) | def read_h5(h5, key):
function read_h5_attrs (line 179) | def read_h5_attrs(h5, key, attrs):
function copy (line 182) | def copy(src, dest):
function remove (line 189) | def remove(p):
function search (line 194) | def search(pattern, path, file_only = True):
function dump_json (line 220) | def dump_json(path, data):
function load_json (line 229) | def load_json(path):
FILE: util/logging.py
class Logger (line 21) | class Logger(object):
method __init__ (line 22) | def __init__(self, fpath=None):
method __del__ (line 37) | def __del__(self):
method __enter__ (line 40) | def __enter__(self):
method __exit__ (line 43) | def __exit__(self, *args):
method write (line 46) | def write(self, msg):
method flush (line 51) | def flush(self):
method close (line 57) | def close(self):
class TFLogger (line 63) | class TFLogger(object):
method __init__ (line 64) | def __init__(self, log_dir=None):
method scalar_summary (line 70) | def scalar_summary(self, tag, value, step):
method image_summary (line 76) | def image_summary(self, tag, images, step):
method histo_summary (line 100) | def histo_summary(self, tag, values, step, bins=1000):
method close (line 128) | def close(self):
FILE: util/meters.py
class AverageMeter (line 4) | class AverageMeter(object):
method __init__ (line 7) | def __init__(self):
method reset (line 13) | def reset(self):
method update (line 19) | def update(self, val, n=1):
FILE: util/misc.py
function to_device (line 10) | def to_device(*tensors):
function mkdirs (line 16) | def mkdirs(newdir):
function rescale_result (line 30) | def rescale_result(image, bbox_contours, H, W):
function fill_hole (line 43) | def fill_hole(input_mask):
function regularize_sin_cos (line 56) | def regularize_sin_cos(sin, cos):
function gaussian2D (line 62) | def gaussian2D(shape, sigma=1):
function draw_gaussian (line 71) | def draw_gaussian(heatmap, center, radius, k=1, delte=6):
function gaussian_radius (line 87) | def gaussian_radius(det_size, min_overlap=0.7):
function point_dist_to_line (line 110) | def point_dist_to_line(line, p3):
class AverageMeter (line 130) | class AverageMeter(object):
method __init__ (line 132) | def __init__(self):
method reset (line 135) | def reset(self):
method update (line 141) | def update(self, val, n=1):
function norm2 (line 148) | def norm2(x, axis=None):
function cos (line 154) | def cos(p1, p2):
function vector_sin (line 158) | def vector_sin(v):
function vector_cos (line 165) | def vector_cos(v):
function find_bottom (line 172) | def find_bottom(pts):
function split_long_edges (line 238) | def split_long_edges(points, bottoms):
function find_long_edges (line 260) | def find_long_edges(points, bottoms):
function split_edge_seqence (line 283) | def split_edge_seqence(points, n_parts):
function split_edge_seqence_with_cell_division (line 317) | def split_edge_seqence_with_cell_division(points, n_parts):
function split_edge_seqence_by_step (line 338) | def split_edge_seqence_by_step(points, long_edge1, long_edge2, step=16.0):
function disjoint_find (line 355) | def disjoint_find(x, F):
function disjoint_merge (line 362) | def disjoint_merge(x, y, F):
function merge_polygons (line 371) | def merge_polygons(polygons, merge_map):
function get_sample_point (line 394) | def get_sample_point(text_mask, num_points, approx_factor, scales=None):
FILE: util/pbox.py
function functools_reduce (line 9) | def functools_reduce(a):
function minConnectPath (line 16) | def minConnectPath(list_all: List[list]):
function bbox_transfor_inv (line 62) | def bbox_transfor_inv(radius_map, sin_map, cos_map, score_map, wclip=(2,...
FILE: util/serialization.py
function read_json (line 21) | def read_json(fpath):
function write_json (line 27) | def write_json(obj, fpath):
function save_checkpoint (line 33) | def save_checkpoint(state, is_best, fpath='checkpoint.pth.tar'):
function load_checkpoint (line 52) | def load_checkpoint(fpath):
function copy_state_dict (line 69) | def copy_state_dict(state_dict, model, strip=None):
FILE: util/shedule.py
class FixLR (line 3) | class FixLR(_LRScheduler):
method __init__ (line 24) | def __init__(self, optimizer, last_epoch=-1):
method get_lr (line 27) | def get_lr(self):
FILE: util/strs.py
function int_array_to_str (line 2) | def int_array_to_str(arr):
function join (line 7) | def join(arr, splitter=','):
function is_str (line 16) | def is_str(s):
function to_lowercase (line 20) | def to_lowercase(s):
function to_uppercase (line 24) | def to_uppercase(s):
function ends_with (line 28) | def ends_with(s, suffix, ignore_case = False):
function starts_with (line 43) | def starts_with(s, prefix, ignore_case = False):
function contains (line 58) | def contains(s, target, ignore_case = False):
function index_of (line 65) | def index_of(s, target):
function replace_all (line 69) | def replace_all(s, old, new, reg = False):
function remove_all (line 80) | def remove_all(s, sub):
function split (line 84) | def split(s, splitter, reg = False):
function remove_invisible (line 91) | def remove_invisible(s):
function find_all (line 100) | def find_all(s, pattern):
function is_none_or_empty (line 105) | def is_none_or_empty(s):
function to_json (line 111) | def to_json(obj):
function to_list (line 116) | def to_list(obj):
function to_tuple (line 124) | def to_tuple(obj):
FILE: util/summary.py
class LogSummary (line 5) | class LogSummary(object):
method __init__ (line 7) | def __init__(self, log_path):
method write_scalars (line 12) | def write_scalars(self, scalar_dict, n_iter, tag=None):
method write_hist_parameters (line 19) | def write_hist_parameters(self, net, n_iter):
FILE: util/vis_flux.py
function label2color (line 12) | def label2color(label):
function vis_direction_field (line 36) | def vis_direction_field(gt_flux):
function vis_flux (line 59) | def vis_flux(vis_image, pred_flux, gt_flux, gt_mask, image_name, save_dir):
FILE: util/visualize.py
function visualize_network_output (line 15) | def visualize_network_output(output_dict, input_dict, mode='train'):
function visualize_gt (line 134) | def visualize_gt(image, contours, label_tag):
function visualize_detection (line 149) | def visualize_detection(image, output_dict, meta=None):
Condensed preview — 180 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,206K chars).
[
{
"path": ".gitignore",
"chars": 57,
"preview": ".idea\n**/__pycache__\n*.so\noutput/TD500/*\nvis/TD500_test/\n"
},
{
"path": "README.md",
"chars": 16862,
"preview": "# TextBPN-Puls-Plus \nThis is a Pytorch implementation of TextBPN++: [Arbitrary Shape Text Detection via Boundary Transfo"
},
{
"path": "cache/README.md",
"chars": 73,
"preview": "Download the pre-training weights on ImgNet for ResNet18 or ResNet50 ...\n"
},
{
"path": "cfglib/config.py",
"chars": 1492,
"preview": "from easydict import EasyDict\nimport torch\nimport os\n\nconfig = EasyDict()\n\n\n# Normalize image\nconfig.means = (0.485, 0.4"
},
{
"path": "cfglib/option.py",
"chars": 6454,
"preview": "import argparse\nimport torch\nimport os\nimport torch.backends.cudnn as cudnn\n\nfrom datetime import datetime\n\n\ndef str2boo"
},
{
"path": "data/ArT/README.md",
"chars": 219,
"preview": "## ArT\n\nAn example of the path of ArT dataset: \n\n```\n├── ArT\n│ ├──Images\n│ ├── Train\n│ ├── Test\n│ ├── gt"
},
{
"path": "data/CTW-1500/README.md",
"chars": 214,
"preview": "## CTW-1500 (new)\n\nAn example of the path of CTW-1500 dataset: \n\n```\n├── CTW-1500\n│ ├──Images\n│ ├── Train\n│ "
},
{
"path": "data/Icdar2015/README.md",
"chars": 176,
"preview": "## ICDAR 2015 \n\nAn example of the path of ICDAR2015 dataset: \n\n```\n├── Icdar2015\n│ ├──Train (include img and gt files"
},
{
"path": "data/LSVT/README.md",
"chars": 188,
"preview": "## LSVT \n\nAn example of the path of LSVT dataset: \n\n```\n├── LSVT\n│ ├──Images\n│ ├── Train\n│ ├── ...\n│ ├─"
},
{
"path": "data/MLT-2019/README.md",
"chars": 206,
"preview": "## MLT-2019\n\nAn example of the path of MLT-2019 dataset: \n\n```\n├── MLT-2019\n│ ├──TrainImages\n│ ├──Train_gt # gt wit"
},
{
"path": "data/MLT2017/README.md",
"chars": 197,
"preview": "## MLT2017\n\nAn example of the path of MLT2017 dataset: \n\n```\n├── MLT2017\n│ ├──mlt_train\n│ ├──mlt_val\n│ ├──mlt_test"
},
{
"path": "data/README.md",
"chars": 22,
"preview": "Put the datasets here\n"
},
{
"path": "data/SynthText/README.md",
"chars": 170,
"preview": "## SynthText\n\nAn example of the path of SynthText dataset: \n\n```\n├── SynthText\n│ ├──1\n│ ├──...\n│ ├──200\n│\n│ ├──g"
},
{
"path": "data/SynthText/findPath.sh",
"chars": 179,
"preview": "#!/bin/bash\nroot_dir=\"./gt_e2e/\"\nfn=\"/*.txt\"\nout_fn=\"gt_e2e.txt\"\n\nfor element in `ls $root_dir`\n do\n echo $root_di"
},
{
"path": "data/TD500/README.md",
"chars": 176,
"preview": "## TD500\n\nAn example of the path of TD500 dataset: \n\n```\n├── TD500\n│ ├──Train (include img and gt(\".txt\") files)\n│ ├"
},
{
"path": "data/Total-Text/README.md",
"chars": 478,
"preview": "## Total-Text (new)\n\nAn example of the path of Total-Text dataset: \n\n```\n├── Total-Text\n│ ├──Images\n│ ├── Train\n"
},
{
"path": "data/ctw1500/README.md",
"chars": 237,
"preview": "## CTW-1500 (old)\n\nAn example of the path of CTW-1500 dataset: \n\n```\n├── ctw1500\n│ ├──train\n│ ├── text_image\n│ "
},
{
"path": "data/total-text-mat/README.md",
"chars": 212,
"preview": "## Total-Text (old)\n\nAn example of the path of Total-Text dataset: \n\n```\n├── total-text-mat\n│ ├──Images\n│ ├── Tr"
},
{
"path": "dataset/CTW1500_Text_New.py",
"chars": 7776,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\nimport os\nimport cv2\nimport numpy as np\nfrom dataset.dat"
},
{
"path": "dataset/Icdar15_Text.py",
"chars": 4732,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\nimport re\nimport os\nimport numpy as np\nfrom util import "
},
{
"path": "dataset/Icdar17_Text.py",
"chars": 5498,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport os\nimport numpy as np\nfrom dataset.data_util import pil_load_img"
},
{
"path": "dataset/Icdar19ArT_Json.py",
"chars": 6711,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport os\nimport numpy as np\nfrom dataset.data_util import pil_load_img"
},
{
"path": "dataset/Icdar19ArT_Text.py",
"chars": 5324,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport os\nimport re\ni"
},
{
"path": "dataset/Icdar19LSVT_Json.py",
"chars": 6787,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport os\nimport numpy as np\nfrom dataset.data_util import pil_load_img"
},
{
"path": "dataset/Icdar19_Text.py",
"chars": 8158,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport os\nimport numpy as np\nfrom dataset.data_util import pil_load_img"
},
{
"path": "dataset/README.md",
"chars": 151,
"preview": "You can add your dataset load scripts here, and details you refer to the loading script of other datasets, such as CTW15"
},
{
"path": "dataset/TD500/075eval.sh",
"chars": 134,
"preview": "rm submit/*\ncp $1/*.txt submit\ncd submit/;zip -r submit.zip *;mv submit.zip ../; cd ../\npython2 script075.py -g=gt.zip "
},
{
"path": "dataset/TD500/Evaluation_Protocol/readme.txt",
"chars": 1278,
"preview": "INSTRUCTIONS FOR THE STANDALONE SCRIPTS\nRequirements:\n- Python version 2.7.\n- Each Task requires differe"
},
{
"path": "dataset/TD500/Evaluation_Protocol/rrc_evaluation_funcs.py",
"chars": 16993,
"preview": "#!/usr/bin/env python2\n#encoding: UTF-8\nimport json\nimport sys;sys.path.append('./')\nimport zipfile\nimport re\nimport sys"
},
{
"path": "dataset/TD500/Evaluation_Protocol/script.py",
"chars": 14374,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom collections import namedtuple\nimport rrc_evaluation_funcs\nimport impo"
},
{
"path": "dataset/TD500/Evaluation_Protocol/script075.py",
"chars": 13474,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom collections import namedtuple\nimport rrc_evaluation_funcs\nimport impo"
},
{
"path": "dataset/TD500/batch_eval.sh",
"chars": 92,
"preview": "for ((i=490000;i<=510000;i+=1000)); do echo $i;sh eval.sh $1/submit-${i}_1.5|grep Calc;done\n"
},
{
"path": "dataset/TD500/eval.sh",
"chars": 196,
"preview": "cd dataset/TD500\nrm submit.zip\ncp $1/*.txt submit\ncd submit/;zip -r submit.zip * &> ../log.txt ; mv submit.zip ../; cd "
},
{
"path": "dataset/TD500/submit/res_img_1.txt",
"chars": 36,
"preview": "637,679,749,723,0.08314135922921725\n"
},
{
"path": "dataset/TD500_Text.py",
"chars": 5062,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\nimport re\nimport os\nimport numpy as np\nfrom util import "
},
{
"path": "dataset/Total_Text.py",
"chars": 9409,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport os\nimport re\ni"
},
{
"path": "dataset/Total_Text_New.py",
"chars": 8458,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport os\nimport cv2\n"
},
{
"path": "dataset/__init__.py",
"chars": 521,
"preview": "from .dataload import *\nfrom .Total_Text import TotalText\nfrom .synth_text import SynthText\nfrom .ctw1500_text import Ct"
},
{
"path": "dataset/ctw1500/Evaluation_Protocol/ctw1500_eval.py",
"chars": 2443,
"preview": "#!/usr/bin/env python2\n# -*- coding: utf-8 -*-\n\nimport os, shutil, sys\nfrom voc_eval_polygon import voc_eval_polygon\nfro"
},
{
"path": "dataset/ctw1500/Evaluation_Protocol/voc_eval_polygon.py",
"chars": 7703,
"preview": "# --------------------------------------------------------\n# Fast/er R-CNN\n# Licensed under The MIT License [see LICENSE"
},
{
"path": "dataset/ctw1500/Evaluation_sort/detections_text0.5.txt",
"chars": 480518,
"preview": "0 0.999 44 73 49 83 59 80 68 75 78 71 87 69 98 70 106 74 115 78 123 82 131 79 130 71 120 66 111 63 101 59 91 56 80 57 70"
},
{
"path": "dataset/ctw1500/Readme.md",
"chars": 412,
"preview": "# Evaluation_step (Make sure you have downloaded the data and put them in the correct path)\n\n(In ROOT directory)\n\n1. Fol"
},
{
"path": "dataset/ctw1500_text.py",
"chars": 7117,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\nimport os\nimport numpy as np\nfrom dataset.data_util impo"
},
{
"path": "dataset/data_util.py",
"chars": 301,
"preview": "from PIL import ImageFile\nfrom PIL import Image\nimport numpy as np\n\nImageFile.LOAD_TRUNCATED_IMAGES = True\nImage.MAX_IMA"
},
{
"path": "dataset/dataload.py",
"chars": 10871,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport copy\nimport cv2\nimport torch\nimport numpy as np\nfrom PIL import "
},
{
"path": "dataset/deploy.py",
"chars": 1298,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport scipy.io as io\nimport numpy as np\nimport os\n\nfrom dataset.data_u"
},
{
"path": "dataset/icdar15/075eval.sh",
"chars": 134,
"preview": "rm submit/*\ncp $1/*.txt submit\ncd submit/;zip -r submit.zip *;mv submit.zip ../; cd ../\npython2 script075.py -g=gt.zip "
},
{
"path": "dataset/icdar15/Evaluation_Protocol/readme.txt",
"chars": 1278,
"preview": "INSTRUCTIONS FOR THE STANDALONE SCRIPTS\nRequirements:\n- Python version 2.7.\n- Each Task requires differe"
},
{
"path": "dataset/icdar15/Evaluation_Protocol/rrc_evaluation_funcs.py",
"chars": 15347,
"preview": "#!/usr/bin/env python2\n#encoding: UTF-8\nimport json\nimport zipfile\nimport re\nimport sys\nimport os\nimport codecs\n# import"
},
{
"path": "dataset/icdar15/Evaluation_Protocol/script.py",
"chars": 13962,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom collections import namedtuple\nimport rrc_evaluation_funcs\nimport impo"
},
{
"path": "dataset/icdar15/Evaluation_Protocol/script075.py",
"chars": 13493,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom collections import namedtuple\nimport rrc_evaluation_funcs\nimport impo"
},
{
"path": "dataset/icdar15/batch_eval.sh",
"chars": 92,
"preview": "for ((i=490000;i<=510000;i+=1000)); do echo $i;sh eval.sh $1/submit-${i}_1.5|grep Calc;done\n"
},
{
"path": "dataset/icdar15/eval.sh",
"chars": 196,
"preview": "cd dataset/icdar15/\nrm submit/*\ncp $1/*.txt submit\ncd submit/;zip -r submit.zip * &> ../log.txt ;mv submit.zip ../; cd "
},
{
"path": "dataset/icdar15/submit/res_img_1.txt",
"chars": 32,
"preview": "137,342,179,342,179,354,137,354\n"
},
{
"path": "dataset/synth-text/README.md",
"chars": 619,
"preview": "## SynthText\n\nSynthText is uploaded to Baidu Cloud [link](https://pan.baidu.com/s/17Gk301SwsnoESM1jQZRq0g), extract code"
},
{
"path": "dataset/synth-text/make_list.py",
"chars": 927,
"preview": "import os\nimport scipy.io as io\nfrom tqdm import tqdm\n\ngt_mat_path = 'data/SynthText/gt.mat'\nim_root = 'data/SynthText/'"
},
{
"path": "dataset/synth_text.py",
"chars": 3767,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport os\nimport numpy as np\nfrom dataset.data_util import pil_load_img"
},
{
"path": "dataset/total_text/.gitignore",
"chars": 35,
"preview": "groundtruth_text.zip\ntotaltext.zip\n"
},
{
"path": "dataset/total_text/Evaluation_Protocol/ComputePrecisionRecall.m",
"chars": 5709,
"preview": "function [ precision, recall ] = ComputePrecisionRecall( tau, sigma, tp,tr,k,fsc_k )\n%COMPUTEPRECISIONRECALL Summary of "
},
{
"path": "dataset/total_text/Evaluation_Protocol/Eval.m",
"chars": 4803,
"preview": "%% Evaluation method for Total-Text. \n% Chee Kheng Ch'ng and Chee Seng Chan.\n% \"Total-Text: A Comprehensive Dataset fo"
},
{
"path": "dataset/total_text/Evaluation_Protocol/Examples/Result.txt",
"chars": 1332,
"preview": "poly_gt_img1.mat 0.779921424378009 0.0942898883654127\npoly_gt_img1.mat 0.525106870874419 0.629432040680526\npoly_gt_img2."
},
{
"path": "dataset/total_text/Evaluation_Protocol/Python_scripts/Deteval.py",
"chars": 13432,
"preview": "# modified from https://github.com/cs-chan/Total-Text-Dataset/blob/master/Evaluation_Protocol/Python_scripts/Deteval.py\n"
},
{
"path": "dataset/total_text/Evaluation_Protocol/Python_scripts/Pascal_VOC.py",
"chars": 4650,
"preview": "from os import listdir\nfrom scipy import io\nimport numpy as np\nfrom skimage.draw import polygon\nfrom polygon_wrapper imp"
},
{
"path": "dataset/total_text/Evaluation_Protocol/Python_scripts/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dataset/total_text/Evaluation_Protocol/Python_scripts/polygon_fast.py",
"chars": 2276,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\n\nimport numpy as np\nfrom shapely.geometry import Polygon"
},
{
"path": "dataset/total_text/Evaluation_Protocol/Python_scripts/polygon_wrapper.py",
"chars": 5018,
"preview": "import numpy as np\n# from skimage.draw import polygon\nfrom shapely.geometry import Polygon\n\n\"\"\"\n:param det_x: [1, N] Xs "
},
{
"path": "dataset/total_text/Evaluation_Protocol/README.md",
"chars": 559,
"preview": "## Description\n\nThese codes are the official evaluation protocol implementation for Total-Text. Two methods are made ava"
},
{
"path": "dataset/total_text/Evaluation_Protocol/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dataset/total_text/README.md",
"chars": 163,
"preview": "### Total-Text dataset\n\nHome page: https://github.com/cs-chan/Total-Text-Dataset\n\ndownload dataset and make it to a data"
},
{
"path": "dataset/total_text/download.sh",
"chars": 594,
"preview": "set -e\n\n# download image data\nbash gdrivedl.sh https://drive.google.com/file/d/1bC68CzsSVTusZVvOkk7imSZSbgD1MqK2/view?us"
},
{
"path": "dataset/total_text/gdrivedl.sh",
"chars": 1449,
"preview": "#!/bin/bash\n# modified from https://github.com/matthuisman/files.matthuisman.nz/blob/master/gdrivedl\n\nurl=$1\nfilename=$2"
},
{
"path": "demo.py",
"chars": 5497,
"preview": "import os\nimport time\nimport cv2\nimport numpy as np\nimport torch\nimport torch.backends.cudnn as cudnn\nimport torch.utils"
},
{
"path": "demo.sh",
"chars": 206,
"preview": "#!/bin/bash\nCUDA_LAUNCH_BLOCKING=1 python3 demo.py --net resnet18 --scale 4 --exp_name TD500 --checkepoch 1135 --test_si"
},
{
"path": "eval.sh",
"chars": 1170,
"preview": "#!/bin/bash\n##################### Total-Text ###################################\n# test_size=(640,1024)--cfglib/option\n#"
},
{
"path": "eval_textBPN.py",
"chars": 9596,
"preview": "import os\nimport time\nimport cv2\nimport numpy as np\nimport json\nfrom shapely.geometry import *\nimport torch\nimport subpr"
},
{
"path": "eval_textBPN_speed.py",
"chars": 4095,
"preview": "import os\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport torch.utils.data as data\nfrom dataset imp"
},
{
"path": "model/README.md",
"chars": 24,
"preview": "Save the model here...\n\n"
},
{
"path": "network/Reg_loss.py",
"chars": 6679,
"preview": "# -*- coding: utf-8 -*-\n# @Time : 10/1/21\n# @Author : GXYM\nimport torch\nfrom torch import nn\nimport numpy as np\nimpo"
},
{
"path": "network/Seg_loss.py",
"chars": 4272,
"preview": "# -*- coding: utf-8 -*-\n# @Time : 10/1/21\n# @Author : GXYM\nimport torch\nfrom torch import nn\nimport numpy as np\n\n\ncl"
},
{
"path": "network/__init__.py",
"chars": 15,
"preview": "from . import *"
},
{
"path": "network/backbone/__init__.py",
"chars": 101,
"preview": "from .resnet import resnet18, resnet34, resnet50, resnet101, deformable_resnet50, deformable_resnet18"
},
{
"path": "network/backbone/assets/dcn/Makefile",
"chars": 75,
"preview": "#!/bin/bash\nrm *.so \npython setup.py build_ext --inplace\nrm -rf ./build\n\n\n"
},
{
"path": "network/backbone/assets/dcn/Makefile.sh",
"chars": 75,
"preview": "#!/bin/bash\nrm *.so \npython setup.py build_ext --inplace\nrm -rf ./build\n\n\n"
},
{
"path": "network/backbone/assets/dcn/__init__.py",
"chars": 656,
"preview": "from .functions.deform_conv import deform_conv, modulated_deform_conv\nfrom .functions.deform_pool import deform_roi_pool"
},
{
"path": "network/backbone/assets/dcn/functions/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "network/backbone/assets/dcn/functions/deform_conv.py",
"chars": 7291,
"preview": "import torch\nfrom torch.autograd import Function\nfrom torch.nn.modules.utils import _pair\n\nfrom .. import deform_conv_cu"
},
{
"path": "network/backbone/assets/dcn/functions/deform_pool.py",
"chars": 2370,
"preview": "import torch\nfrom torch.autograd import Function\n\nfrom .. import deform_pool_cuda\n\n\nclass DeformRoIPoolingFunction(Funct"
},
{
"path": "network/backbone/assets/dcn/modules/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "network/backbone/assets/dcn/modules/deform_conv.py",
"chars": 5198,
"preview": "import math\n\nimport torch\nimport torch.nn as nn\nfrom torch.nn.modules.utils import _pair\n\nfrom ..functions.deform_conv i"
},
{
"path": "network/backbone/assets/dcn/modules/deform_pool.py",
"chars": 7058,
"preview": "from torch import nn\n\nfrom ..functions.deform_pool import deform_roi_pooling\n\n\nclass DeformRoIPooling(nn.Module):\n\n d"
},
{
"path": "network/backbone/assets/dcn/setup.py",
"chars": 606,
"preview": "import os\nPATH =\"{}:{}\".format(os.environ['PATH'], \"/opt/cuda/bin\")\n# os.environ['CUDA_VISIBLE_DEVICES'] = \"1\"\nos.enviro"
},
{
"path": "network/backbone/assets/dcn/src/deform_conv_cuda.cpp",
"chars": 29358,
"preview": "// modify from\n// https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/blob/mmdetection/mmdet/ops/dcn/src/def"
},
{
"path": "network/backbone/assets/dcn/src/deform_conv_cuda_kernel.cu",
"chars": 42822,
"preview": "/*!\n ******************* BEGIN Caffe Copyright Notice and Disclaimer ****************\n *\n * COPYRIGHT\n *\n * All contribu"
},
{
"path": "network/backbone/assets/dcn/src/deform_pool_cuda.cpp",
"chars": 3937,
"preview": "// modify from\n// https://github.com/chengdazhi/Deformable-Convolution-V2-PyTorch/blob/mmdetection/mmdet/ops/dcn/src/mod"
},
{
"path": "network/backbone/assets/dcn/src/deform_pool_cuda_kernel.cu",
"chars": 16572,
"preview": "/*!\n * Copyright (c) 2017 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file deformable_psro"
},
{
"path": "network/backbone/resnet.py",
"chars": 11900,
"preview": "import torch.nn as nn\nimport math\nimport torch.utils.model_zoo as model_zoo\nBatchNorm2d = nn.BatchNorm2d\n\n__all__ = ['Re"
},
{
"path": "network/backbone/vgg.py",
"chars": 2558,
"preview": "import torch.nn as nn\nimport torch.utils.model_zoo as model_zoo\nimport torchvision.models as models\n\nmodel_urls = {\n "
},
{
"path": "network/layers/Adaptive_Deformation.py",
"chars": 2747,
"preview": "###################################################################\n# File Name: AdaptiveDeformation.py\n# Author: S.X.Zh"
},
{
"path": "network/layers/CircConv.py",
"chars": 3119,
"preview": "import torch.nn as nn\nimport torch\n\n\nclass CircConv(nn.Module):\n def __init__(self, state_dim, out_state_dim=None, n_"
},
{
"path": "network/layers/GCN.py",
"chars": 2284,
"preview": "###################################################################\n# File Name: GCN.py\n# Author: S.X.Zhang\n############"
},
{
"path": "network/layers/GraphConv.py",
"chars": 1406,
"preview": "import math\n\nimport torch\nfrom torch.nn.parameter import Parameter\nfrom torch.nn.modules.module import Module\nfrom torch"
},
{
"path": "network/layers/RNN.py",
"chars": 1041,
"preview": "###################################################################\n# File Name: RNN.py\n# Author: S.X.Zhang\n############"
},
{
"path": "network/layers/Transformer.py",
"chars": 5185,
"preview": "###################################################################\n# File Name: GCN.py\n# Author: S.X.Zhang\n############"
},
{
"path": "network/layers/Transformer_old.py",
"chars": 6423,
"preview": "###################################################################\n# File Name: GCN.py\n# Author: S.X.Zhang\n############"
},
{
"path": "network/layers/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "network/layers/gcn_utils.py",
"chars": 4679,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport torch\nimport numpy as np\nimport cv2\nimport torch.nn as nn\nfrom t"
},
{
"path": "network/layers/model_block.py",
"chars": 7373,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom"
},
{
"path": "network/layers/position_encoding.py",
"chars": 3336,
"preview": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n\"\"\"\nVarious positional encodings for the transfor"
},
{
"path": "network/layers/resnet.py",
"chars": 2365,
"preview": "import torch\nimport torch.nn as nn\nfrom torchvision.models import resnet\nimport torch.utils.model_zoo as model_zoo\nfrom "
},
{
"path": "network/layers/resnet_dcn.py",
"chars": 2166,
"preview": "import torch\nimport torch.nn as nn\nfrom network.backbone.resnet import deformable_resnet18,deformable_resnet50\nimport to"
},
{
"path": "network/layers/vgg.py",
"chars": 2692,
"preview": "import torch.nn as nn\nimport torch.utils.model_zoo as model_zoo\nimport torchvision.models as models\nfrom cfglib.config i"
},
{
"path": "network/loss.py",
"chars": 8144,
"preview": "# -*- coding: utf-8 -*-\n# @Time : 10/1/21\n# @Author : GXYM\nimport torch\nimport torch.nn as nn\nfrom cfglib.config imp"
},
{
"path": "network/loss_org.py",
"chars": 5384,
"preview": "# -*- coding: utf-8 -*-\n# @Time : 10/1/21\n# @Author : GXYM\nimport torch\nimport torch.nn as nn\nfrom cfglib.config imp"
},
{
"path": "network/textnet.py",
"chars": 10253,
"preview": "# -*- coding: utf-8 -*-\n# @Time : 10/1/21\n# @Author : GXYM\nimport torch\nimport torch.nn as nn\nfrom network.layers.mo"
},
{
"path": "output/Analysis/ctw1500_eval.txt",
"chars": 10396,
"preview": "640_1024_100 0.35/0.825 ALL :: AP=0.6632 - Precision=0.8515 - Recall=0.7722 - Fscore=0.8099\n640_1024_105 0.35/0.825 ALL "
},
{
"path": "output/Analysis/totalText_eval.txt",
"chars": 20966,
"preview": "640_1024_55_0.7_0.6 0.3/0.85 ALL :: Precision=0.8919 - Recall=0.5764 - Fscore=0.7003\n640_1024_55_0.8_0.4 0.3/0.85 ALL ::"
},
{
"path": "output/README.md",
"chars": 37232,
"preview": "\n## Code Update Description\n**Solving the difficulties of reproducing the performance in our paper**\n\n**Reproduction rec"
},
{
"path": "requirements.txt",
"chars": 77,
"preview": "opencv-python\npillow-simd\nscipy\neasydict\nmatplotlib\nshapely\nlxml\ntorchvision\n"
},
{
"path": "scripts-eval/Eval_ArT.sh",
"chars": 860,
"preview": "#!/bin/bash\ncd ../\n##################### eval for ArT with ResNet50 1s ###################################\n#CUDA_LAUNCH_"
},
{
"path": "scripts-eval/Eval_CTW1500.sh",
"chars": 1430,
"preview": "#!/bin/bash\ncd ../\n\n##################### eval for Ctw1500 with ResNet18 4s ###################################\n#CUDA_LA"
},
{
"path": "scripts-eval/Eval_MLT2017.sh",
"chars": 1085,
"preview": "#!/bin/bash\ncd ../\n\n##################### eval for MLT2017 with ResNet50 1s ###################################\nCUDA_LAU"
},
{
"path": "scripts-eval/Eval_TD500.sh",
"chars": 1413,
"preview": "#!/bin/bash\ncd ../\n\n##################### eval for TD500 with ResNet18 4s ###################################\nCUDA_LAUNC"
},
{
"path": "scripts-eval/Eval_Totaltext.sh",
"chars": 1456,
"preview": "#!/bin/bash\ncd ../\n\n##################### eval for Total-Text with ResNet18 4s ###################################\n#CUDA"
},
{
"path": "scripts-train/train_ALL_res50_dcn_1s.sh",
"chars": 361,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name ALL --net deformable_resnet50 --scale 1 --"
},
{
"path": "scripts-train/train_Art_res50_1s_fine_mlt.sh",
"chars": 341,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python train_textBPN.py --exp_name ArT --net resnet50 --scale 1 --max_epoch 66"
},
{
"path": "scripts-train/train_Art_res50_dcn_1s_fine_mlt.sh",
"chars": 364,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name ArT --net deformable_resnet50 --scale 1 --"
},
{
"path": "scripts-train/train_CTW1500_res18_4s_fine_mlt.sh",
"chars": 543,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Ctw1500 --net resnet18 --scale 4 --max_epo"
},
{
"path": "scripts-train/train_CTW1500_res50_1s.sh",
"chars": 614,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Ctw1500 --net resnet50 --scale 1 --max_epo"
},
{
"path": "scripts-train/train_CTW1500_res50_1s_fine_mlt.sh",
"chars": 546,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Ctw1500 --net resnet50 --scale 1 --max_epo"
},
{
"path": "scripts-train/train_CTW1500_res50_dcn_1s_fine_mlt.sh",
"chars": 306,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Ctw1500 --net deformable_resnet50 --scale "
},
{
"path": "scripts-train/train_MLT2017_res18_4s.sh",
"chars": 302,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name MLT2017 --net resnet18 --scale 4 --max_epo"
},
{
"path": "scripts-train/train_MLT2017_res50_1s.sh",
"chars": 283,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name MLT2017 --net resnet50 --scale 1 --max_epo"
},
{
"path": "scripts-train/train_MLT2017_res50_dcn_1s.sh",
"chars": 367,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name MLT2017 --net deformable_resnet50 --scale "
},
{
"path": "scripts-train/train_MLT2019_res50_1s.sh",
"chars": 232,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name MLT2019 --net resnet50 --scale 1 --max_epo"
},
{
"path": "scripts-train/train_SynText_res18_4s.sh",
"chars": 300,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Synthtext --net resnet18 --scale 4 --max_e"
},
{
"path": "scripts-train/train_SynText_res50_1s.sh",
"chars": 300,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Synthtext --net resnet50 --scale 1 --max_e"
},
{
"path": "scripts-train/train_SynText_res50_dcn_1s.sh",
"chars": 245,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Synthtext --net deformable_resnet50 --scal"
},
{
"path": "scripts-train/train_TD500_res18_4s_fine_mlt.sh",
"chars": 538,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name TD500 --net resnet18 --scale 4 --max_epoch"
},
{
"path": "scripts-train/train_TD500_res50_1s.sh",
"chars": 289,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name TD500 --net resnet50 --scale 1 --max_epoch"
},
{
"path": "scripts-train/train_TD500_res50_1s_fine_mlt.sh",
"chars": 281,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name TD500 --net resnet50 --scale 1 --max_epoch"
},
{
"path": "scripts-train/train_TD500_res50_dcn_1s_fine_mlt.sh",
"chars": 280,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name TD500 --net deformable_resnet50 --scale 1 "
},
{
"path": "scripts-train/train_Totaltext_res18_1s.sh",
"chars": 293,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet18 --max_epoch 660 -"
},
{
"path": "scripts-train/train_Totaltext_res18_2s.sh",
"chars": 611,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet18 --scale 2 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res18_4s.sh",
"chars": 573,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet18 --scale 4 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res18_4s_fine_mlt.sh",
"chars": 545,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet18 --scale 4 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res50_1s.sh",
"chars": 533,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet50 --scale 1 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res50_1s_fine_mlt.sh",
"chars": 546,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet50 --scale 1 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res50_4s.sh",
"chars": 540,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python3 train_textBPN.py --exp_name Totaltext --net resnet50 --scale 4 --max_e"
},
{
"path": "scripts-train/train_Totaltext_res50_dcn_1s_fine_mlt.sh",
"chars": 308,
"preview": "#!/bin/bash\ncd ../\nCUDA_LAUNCH_BLOCKING=1 python train_textBPN.py --exp_name Totaltext --net deformable_resnet50 --scale"
},
{
"path": "train_textBPN.py",
"chars": 9192,
"preview": "import os\nimport gc\nimport time\nimport torch\nimport numpy as np\nimport torch.nn as nn\nimport torch.backends.cudnn as cud"
},
{
"path": "train_textBPN_DDP.py",
"chars": 9719,
"preview": "import os\nimport gc\nimport time\nimport torch\nimport numpy as np\nimport torch.nn as nn\nfrom torch.optim import lr_schedul"
},
{
"path": "util/__init__.py",
"chars": 45,
"preview": "from .visualize import *\nfrom .pbox import *\n"
},
{
"path": "util/augmentation.py",
"chars": 27414,
"preview": "# -*- coding: utf-8 -*-\n__author__ = \"S.X.Zhang\"\nimport numpy as np\nimport math\nimport cv2\nimport copy\nimport numpy.rand"
},
{
"path": "util/canvas.py",
"chars": 2057,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\n\nimport numpy as np\nimport random\nimport matplotlib.pypl"
},
{
"path": "util/detection.py",
"chars": 694,
"preview": "# c++ version pse based on opencv 3+\nfrom pse import decode as pse_decode\nfrom cfglib.config import config as cfg\n\n\nclas"
},
{
"path": "util/eval.py",
"chars": 8373,
"preview": "import os\nimport cv2\nimport numpy as np\nimport subprocess\nfrom cfglib.config import config as cfg\nfrom util.misc import "
},
{
"path": "util/graph.py",
"chars": 10389,
"preview": "from __future__ import print_function\nfrom __future__ import division\nfrom __future__ import absolute_import\n\nimport num"
},
{
"path": "util/io.py",
"chars": 5454,
"preview": "#coding=utf-8\n'''\nCreated on 2016年9月27日\n\n@author: dengdan\n\nTool functions for file system operation and I/O. \nIn the st"
},
{
"path": "util/logging.py",
"chars": 3544,
"preview": "from __future__ import absolute_import\nimport os\nimport sys\nimport numpy as np\nimport tensorflow as tf\nimport scipy.misc"
},
{
"path": "util/meters.py",
"chars": 440,
"preview": "from __future__ import absolute_import\n\n\nclass AverageMeter(object):\n \"\"\"Computes and stores the average and current va"
},
{
"path": "util/misc.py",
"chars": 12925,
"preview": "import numpy as np\nimport errno\nimport os\nimport cv2\nimport math\nfrom shapely.geometry import Polygon\nfrom cfglib.config"
},
{
"path": "util/pbox.py",
"chars": 2810,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n__author__ = '古溪'\n\nimport numpy as np\nfrom typing import List\n\n\ndef functo"
},
{
"path": "util/serialization.py",
"chars": 2406,
"preview": "from __future__ import print_function, absolute_import\nimport json\nimport os\nimport sys\n# import moxing as mox\nimport os"
},
{
"path": "util/shedule.py",
"chars": 918,
"preview": "from torch.optim.lr_scheduler import _LRScheduler\n\nclass FixLR(_LRScheduler):\n \"\"\"Sets the learning rate of each para"
},
{
"path": "util/strs.py",
"chars": 2534,
"preview": "# encoding = utf-8\ndef int_array_to_str(arr):\n \"\"\"turn an int array to a str\"\"\"\n return \"\".join(map(chr, arr))\n\n\nd"
},
{
"path": "util/summary.py",
"chars": 636,
"preview": "from tensorboardX import SummaryWriter\nfrom util.misc import mkdirs\n\n\nclass LogSummary(object):\n\n def __init__(self, "
},
{
"path": "util/vis_flux.py",
"chars": 2946,
"preview": "import sys\nimport scipy.io as sio\nimport math\nimport numpy as np\nimport cv2\nimport matplotlib\nmatplotlib.use('agg')\nimpo"
},
{
"path": "util/visualize.py",
"chars": 9699,
"preview": "import torch\nimport numpy as np\nimport cv2\nimport os\nimport math\nfrom cfglib.config import config as cfg\nfrom util impor"
},
{
"path": "vis/README.md",
"chars": 33,
"preview": "Save the visualization image here"
}
]
// ... and 11 more files (download for full content)
About this extraction
This page contains the full source code of the GXYM/TextBPN-Plus-Plus GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 180 files (1.1 MB), approximately 459.3k tokens, and a symbol index with 648 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.