Plana-Archive commited on
Commit
ec7a616
·
verified ·
1 Parent(s): b0a7679

Upload text_detection/detect.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. text_detection/detect.py +79 -0
text_detection/detect.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path
2
+ from functools import lru_cache
3
+ from typing import List, Tuple
4
+
5
+ import cv2
6
+ import numpy as np
7
+ from huggingface_hub import HfApi, HfFileSystem, hf_hub_download
8
+ from imgutils.data import ImageTyping
9
+ from imgutils.utils import open_onnx_model
10
+
11
+ hf_client = HfApi()
12
+ hf_fs = HfFileSystem()
13
+
14
+
15
+ @lru_cache()
16
+ def _get_available_models():
17
+ for f in hf_fs.glob('deepghs/text_detection/*/end2end.onnx'):
18
+ yield os.path.relpath(f, 'deepghs/text_detection').split('/')[0]
19
+
20
+
21
+ _ALL_MODELS = list(_get_available_models())
22
+ _DEFAULT_MODEL = 'dbnetpp_resnet50_fpnc_1200e_icdar2015'
23
+
24
+
25
+ @lru_cache()
26
+ def _get_onnx_session(model):
27
+ return open_onnx_model(hf_hub_download(
28
+ 'deepghs/text_detection',
29
+ f'{model}/end2end.onnx'
30
+ ))
31
+
32
+
33
+ def _get_heatmap_of_text(image: ImageTyping, model: str) -> np.ndarray:
34
+ origin_width, origin_height = width, height = image.size
35
+ align = 32
36
+ if width % align != 0:
37
+ width += (align - width % align)
38
+ if height % align != 0:
39
+ height += (align - height % align)
40
+
41
+ input_ = np.array(image).transpose((2, 0, 1)).astype(np.float32) / 255.0
42
+ # noinspection PyTypeChecker
43
+ input_ = np.pad(input_[None, ...], ((0, 0), (0, 0), (0, height - origin_height), (0, width - origin_width)))
44
+
45
+ def _normalize(data, mean=(0.48145466, 0.4578275, 0.40821073), std=(0.26862954, 0.26130258, 0.27577711)):
46
+ mean, std = np.asarray(mean), np.asarray(std)
47
+ return (data - mean[None, :, None, None]) / std[None, :, None, None]
48
+
49
+ ort = _get_onnx_session(model)
50
+
51
+ input_ = _normalize(input_).astype(np.float32)
52
+ output_, = ort.run(['output'], {'input': input_})
53
+ heatmap = output_[0]
54
+ heatmap = heatmap[:origin_height, :origin_width]
55
+
56
+ return heatmap
57
+
58
+
59
+ def _get_bounding_box_of_text(image: ImageTyping, model: str, threshold: float) \
60
+ -> List[Tuple[Tuple[int, int, int, int], float]]:
61
+ heatmap = _get_heatmap_of_text(image, model)
62
+ c_rets = cv2.findContours((heatmap * 255.0).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
63
+ contours = c_rets[0] if len(c_rets) == 2 else c_rets[1]
64
+ bboxes = []
65
+ for c in contours:
66
+ x, y, w, h = cv2.boundingRect(c)
67
+ x0, y0, x1, y1 = x, y, x + w, y + h
68
+ score = heatmap[y0:y1, x0:x1].mean().item()
69
+ if score >= threshold:
70
+ bboxes.append(((x0, y0, x1, y1), score))
71
+
72
+ return bboxes
73
+
74
+
75
+ def detect_text(image: ImageTyping, model: str = _DEFAULT_MODEL, threshold: float = 0.05):
76
+ bboxes = []
77
+ for (x0, y0, x1, y1), score in _get_bounding_box_of_text(image, model, threshold):
78
+ bboxes.append(((x0, y0, x1, y1), 'text', score))
79
+ return bboxes