Skip to content
This repository was archived by the owner on Dec 2, 2022. It is now read-only.

Commit 884bcee

Browse files
authored
packaging, tests and major refactorization (#2)
* update ignored extensions * initial code upload * major refactorization * add tests
1 parent 728600d commit 884bcee

21 files changed

+1485
-11
lines changed

.gitignore

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
*.pyc
2+
*.swp
3+
*.pkl
4+
*.pth
5+
result*
6+
weights*
7+
.vscode
8+
19
# Byte-compiled / optimized / DLL files
210
__pycache__/
311
*.py[cod]
@@ -50,6 +58,7 @@ coverage.xml
5058
*.py,cover
5159
.hypothesis/
5260
.pytest_cache/
61+
cover/
5362

5463
# Translations
5564
*.mo
@@ -72,6 +81,7 @@ instance/
7281
docs/_build/
7382

7483
# PyBuilder
84+
.pybuilder/
7585
target/
7686

7787
# Jupyter Notebook
@@ -82,7 +92,9 @@ profile_default/
8292
ipython_config.py
8393

8494
# pyenv
85-
.python-version
95+
# For a library or package, you might want to ignore these files since the code is
96+
# intended to run in multiple environments; otherwise, check them in:
97+
# .python-version
8698

8799
# pipenv
88100
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -127,3 +139,9 @@ dmypy.json
127139

128140
# Pyre type checker
129141
.pyre/
142+
143+
# pytype static type analyzer
144+
.pytype/
145+
146+
# Cython debug symbols
147+
cython_debug/

LICENSE

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
MIT License
2-
3-
Copyright (c) 2020 fcakyon
1+
Copyright (c) 2019 NAVER Corp., 2020 Fatih C Akyon
42

53
Permission is hereby granted, free of charge, to any person obtaining a copy
64
of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
97
copies of the Software, and to permit persons to whom the Software is
108
furnished to do so, subject to the following conditions:
119

12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
1412

1513
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1614
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1816
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1917
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

README.md

100644100755
+79-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,79 @@
1-
# craft-text-detector
2-
Cross-platform CRAFT text detection package on Pytorch
1+
[![PyPI version](https://badge.fury.io/py/craft-text-detector.svg)](https://badge.fury.io/py/craft-text-detector)
2+
[![Conda version](https://anaconda.org/fcakyon/craft-text-detector/badges/version.svg)](https://anaconda.org/fcakyon/craft-text-detector)
3+
[![CI](https://github.com/fcakyon/craft-text-detector/workflows/CI/badge.svg)](https://github.com/fcakyon/craft-text-detector/actions?query=event%3Apush+branch%3Amaster+is%3Acompleted+workflow%3ACI)
4+
5+
6+
## CRAFT: Character-Region Awareness For Text detection
7+
Packaged, Pytorch-based, easy to use, cross-platform version of the CRAFT text detector | [Paper](https://arxiv.org/abs/1904.01941) |
8+
9+
### Overview
10+
PyTorch implementation for CRAFT text detector that effectively detect text area by exploring each character region and affinity between characters. The bounding box of texts are obtained by simply finding minimum bounding rectangles on binary map after thresholding character region and affinity scores.
11+
12+
<img width="1000" alt="teaser" src="./figures/craft_example.gif">
13+
14+
15+
## Getting started
16+
### Installation
17+
- Install using conda for Linux, Mac and Windows (preferred):
18+
```console
19+
conda install -c fcakyon craft-text-detector
20+
```
21+
- Install using pip for Linux and Mac:
22+
```console
23+
pip install craft-text-detector
24+
```
25+
26+
### Basic Usage
27+
```python
28+
# import package
29+
import craft_text_detector as craft
30+
31+
# set image path and export folder directory
32+
image_path = 'figures/idcard.png'
33+
output_dir = 'outputs/'
34+
35+
# apply craft text detection and export detected regions to output directory
36+
prediction_result = craft.detect_text(image_path, output_dir, crop_type="poly", cuda=False)
37+
```
38+
39+
### Advanced Usage
40+
```python
41+
# import package
42+
import craft_text_detector as craft
43+
44+
# set image path and export folder directory
45+
image_path = 'figures/idcard.png'
46+
output_dir = 'outputs/'
47+
48+
# read image
49+
image = craft.read_image(image_path)
50+
51+
# load models
52+
refine_net = craft.load_refinenet_model()
53+
craft_net = craft.load_craftnet_model()
54+
55+
# perform prediction
56+
prediction_result = craft.get_prediction(image=image,
57+
craft_net=craft_net,
58+
refine_net=refine_net,
59+
text_threshold=0.7,
60+
link_threshold=0.4,
61+
low_text=0.4,
62+
cuda=True,
63+
long_size=1280,
64+
show_time=True)
65+
66+
# export detected text regions
67+
exported_file_paths = craft.export_detected_regions(image_path=image_path,
68+
image=image,
69+
regions=prediction_result["boxes"],
70+
output_dir=output_dir,
71+
rectify=True)
72+
73+
# export heatmap, detection points, box visualization
74+
craft.export_extra_results(image_path=image_path,
75+
image=image,
76+
regions=prediction_result["boxes"],
77+
heatmaps=prediction_result["heatmaps"],
78+
output_dir=output_dir)
79+
```

craft_text_detector/__init__.py

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from __future__ import absolute_import
2+
3+
__version__ = "0.1.8"
4+
5+
from craft_text_detector.imgproc import read_image
6+
7+
from craft_text_detector.file_utils import (export_detected_regions,
8+
export_extra_results)
9+
10+
from craft_text_detector.predict import (load_craftnet_model,
11+
load_refinenet_model,
12+
get_prediction)
13+
14+
# load craft model
15+
craft_net = load_craftnet_model()
16+
17+
18+
# detect texts
19+
def detect_text(image_path,
20+
output_dir=None,
21+
rectify=True,
22+
export_extra=True,
23+
text_threshold=0.7,
24+
link_threshold=0.4,
25+
low_text=0.4,
26+
cuda=False,
27+
long_size=1280,
28+
show_time=False,
29+
refiner=True,
30+
crop_type="poly"):
31+
"""
32+
Arguments:
33+
image_path: path to the image to be processed
34+
output_dir: path to the results to be exported
35+
rectify: rectify detected polygon by affine transform
36+
export_extra: export heatmap, detection points, box visualization
37+
text_threshold: text confidence threshold
38+
link_threshold: link confidence threshold
39+
low_text: text low-bound score
40+
cuda: Use cuda for inference
41+
long_size: desired longest image size for inference
42+
show_time: show processing time
43+
refiner: enable link refiner
44+
crop_type: crop regions by detected boxes or polys ("poly" or "box")
45+
Output:
46+
{"masks": lists of predicted masks 2d as bool array,
47+
"boxes": list of coords of points of predicted boxes,
48+
"boxes_as_ratios": list of coords of points of predicted boxes as ratios of image size,
49+
"polys_as_ratios": list of coords of points of predicted polys as ratios of image size,
50+
"heatmaps": visualization of the detected characters/links,
51+
"text_crop_paths": list of paths of the exported text boxes/polys}
52+
"""
53+
# load image
54+
image = read_image(image_path)
55+
56+
# load refiner if required
57+
if refiner:
58+
refine_net = load_refinenet_model()
59+
else:
60+
refine_net = None
61+
62+
# perform prediction
63+
prediction_result = get_prediction(image=image,
64+
craft_net=craft_net,
65+
refine_net=refine_net,
66+
text_threshold=text_threshold,
67+
link_threshold=link_threshold,
68+
low_text=low_text,
69+
cuda=cuda,
70+
long_size=long_size,
71+
show_time=show_time)
72+
73+
# arange regions
74+
if crop_type == "box":
75+
regions = prediction_result["boxes"]
76+
elif crop_type == "poly":
77+
regions = prediction_result["polys"]
78+
else:
79+
raise TypeError("crop_type can be only 'polys' or 'boxes'")
80+
81+
# export if output_dir is given
82+
prediction_result["text_crop_paths"] = []
83+
if output_dir is not None:
84+
# export detected text regions
85+
exported_file_paths = export_detected_regions(image_path=image_path,
86+
image=image,
87+
regions=regions,
88+
output_dir=output_dir,
89+
rectify=rectify)
90+
prediction_result["text_crop_paths"] = exported_file_paths
91+
92+
# export heatmap, detection points, box visualization
93+
if export_extra:
94+
export_extra_results(image_path=image_path,
95+
image=image,
96+
regions=regions,
97+
heatmaps=prediction_result["heatmaps"],
98+
output_dir=output_dir)
99+
100+
# return prediction results
101+
return prediction_result

0 commit comments

Comments
 (0)