mckabue commited on
Commit
93264c9
·
verified ·
1 Parent(s): eb2bcc4

RE_UPLOAD-REBUILD-RESTART

Browse files
Files changed (1) hide show
  1. utils/get_features.py +123 -0
utils/get_features.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import layoutparser as lp
2
+ from PIL import Image
3
+ import tensorflow as tf
4
+ import numpy as np
5
+ import torch
6
+ import torchvision.ops.boxes as box_ops
7
+ from typing import List, Tuple
8
+ from .split_image import split_image
9
+ from .get_unique_values import get_unique_values
10
+
11
+ def get_vectors(*,
12
+ predicted_bboxes: List[Tuple[int, int, int, int]],
13
+ predicted_scores: List[float],
14
+ predicted_labels: List[str],
15
+ label_names: List[str],
16
+ sub_images_bboxes: List[Tuple[int, int, int, int]],
17
+ index_start: int = 0.17,
18
+ index_end: int = 1,
19
+ weighted_jaccard_index = False):
20
+ bboxes_tensor: torch.Tensor = torch.tensor(predicted_bboxes)
21
+ labels_nonce = { value:key for key, value in zip(get_unique_values(start = index_start, end = index_end, count = len(label_names)), list(label_names)) }
22
+
23
+ def get_vector(bbox: Tuple[int, int, int, int], region_nonce: int):
24
+ # bbox: Expected to be in ``(x1, y1, x2, y2)`` format with ``0 <= x1 < x2`` and ``0 <= y1 < y2``.
25
+ bbox_tensor: torch.Tensor = torch.tensor([bbox])
26
+ [jaccard_indexes] = box_ops.box_iou(bbox_tensor, bboxes_tensor)
27
+ '''
28
+ Either get the index of bounding box with largest jaccard_index (Intersection Over Union) or
29
+ get the index of bounding box with largest jaccard_index (Intersection Over Union) multiplied by the score.
30
+ By doing this we strike a balance between accuracy and relative position.
31
+ '''
32
+ index_of_jaccard_index = jaccard_indexes.argmax() if not weighted_jaccard_index else np.multiply(jaccard_indexes, predicted_scores).argmax()
33
+ jaccard_index = jaccard_indexes[index_of_jaccard_index]
34
+ jaccard_index_bbox_label__nonce = labels_nonce[predicted_labels[index_of_jaccard_index]]
35
+ jaccard_index_bbox_score = predicted_scores[index_of_jaccard_index]
36
+ vector = region_nonce * jaccard_index * jaccard_index_bbox_label__nonce * jaccard_index_bbox_score
37
+ return vector.item()
38
+ sub_images_nonces = get_unique_values(start = index_start, end = index_end, count = len(sub_images_bboxes))
39
+ for sub_image_bbox, region_nonce in zip(sub_images_bboxes, sub_images_nonces):
40
+ yield get_vector(sub_image_bbox, region_nonce)
41
+
42
+ def get_predictions(
43
+ image: Image.Image,
44
+ model: lp.Detectron2LayoutModel,
45
+ predictions_reducer = lambda *args: args):
46
+ layout_predicted = model.detect(image)
47
+ if len(layout_predicted) > 0:
48
+ predicted_bboxes = [block.coordinates for block in layout_predicted]
49
+ predicted_scores = [block.score for block in layout_predicted]
50
+ predicted_labels = [block.type for block in layout_predicted]
51
+ [predicted_bboxes, predicted_scores, predicted_labels] = predictions_reducer(
52
+ predicted_bboxes,
53
+ predicted_scores,
54
+ predicted_labels)
55
+ return {
56
+ 'predicted_bboxes': predicted_bboxes,
57
+ 'predicted_scores': predicted_scores,
58
+ 'predicted_labels': predicted_labels,
59
+ }
60
+ else:
61
+ return {
62
+ 'predicted_bboxes': [],
63
+ 'predicted_scores': [],
64
+ 'predicted_labels': [],
65
+ }
66
+
67
+ def predictions_reducer(
68
+ predicted_bboxes: List[Tuple[int, int, int, int]],
69
+ predicted_scores: List[float],
70
+ predicted_labels: List[str]):
71
+ selected_indices = tf.image.non_max_suppression(
72
+ boxes = predicted_bboxes,
73
+ scores = predicted_scores ,
74
+ max_output_size = len(predicted_bboxes),
75
+ iou_threshold = 0.01)
76
+ return {
77
+ 'predicted_bboxes': tf.gather(predicted_bboxes, selected_indices).numpy().tolist(), # List[List[int, int, int, int]]
78
+ 'predicted_scores': tf.gather(predicted_scores, selected_indices).numpy().astype(float).tolist(),
79
+ 'predicted_labels': tf.gather(predicted_labels, selected_indices).numpy().astype(str).tolist()
80
+ }
81
+
82
+ def get_features(image: Image.Image, model: lp.Detectron2LayoutModel, label_names: List[str], width_parts = 100, height_parts = 100):
83
+ predictions = get_predictions(image, model)
84
+ reduced_predictions = predictions_reducer(**predictions)
85
+ sub_images_bboxes = list(split_image(np.array(image), width_parts, height_parts, result = 'bboxes'))
86
+
87
+ vectors = get_vectors(
88
+ sub_images_bboxes = sub_images_bboxes,
89
+ label_names = label_names,
90
+ weighted_jaccard_index = False,
91
+ **predictions)
92
+
93
+ weighted_vectors = get_vectors(
94
+ sub_images_bboxes = sub_images_bboxes,
95
+ label_names = label_names,
96
+ weighted_jaccard_index = True,
97
+ **predictions)
98
+
99
+ reduced_vectors = get_vectors(
100
+ sub_images_bboxes = sub_images_bboxes,
101
+ label_names = label_names,
102
+ weighted_jaccard_index = False,
103
+ **reduced_predictions)
104
+
105
+ reduced_weighted_vectors = get_vectors(
106
+ sub_images_bboxes = sub_images_bboxes,
107
+ label_names = label_names,
108
+ weighted_jaccard_index = True,
109
+ **reduced_predictions)
110
+
111
+ return {
112
+ 'predicted_bboxes': predictions['predicted_bboxes'],
113
+ 'predicted_scores': predictions['predicted_scores'],
114
+ 'predicted_labels': predictions['predicted_labels'],
115
+ 'vectors': list(vectors),
116
+ 'weighted_vectors': list(weighted_vectors),
117
+
118
+ 'reduced_predicted_bboxes': reduced_predictions['predicted_bboxes'],
119
+ 'reduced_predicted_scores': reduced_predictions['predicted_scores'],
120
+ 'reduced_predicted_labels': reduced_predictions['predicted_labels'],
121
+ 'reduced_vectors': list(reduced_vectors),
122
+ 'reduced_weighted_vectors': list(reduced_weighted_vectors),
123
+ }