python-wml 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of python-wml might be problematic. Click here for more details.

Files changed (164) hide show
  1. python_wml-3.0.0.dist-info/LICENSE +23 -0
  2. python_wml-3.0.0.dist-info/METADATA +51 -0
  3. python_wml-3.0.0.dist-info/RECORD +164 -0
  4. python_wml-3.0.0.dist-info/WHEEL +5 -0
  5. python_wml-3.0.0.dist-info/top_level.txt +1 -0
  6. wml/__init__.py +0 -0
  7. wml/basic_data_def/__init__.py +2 -0
  8. wml/basic_data_def/detection_data_def.py +279 -0
  9. wml/basic_data_def/io_data_def.py +2 -0
  10. wml/basic_img_utils.py +816 -0
  11. wml/img_patch.py +92 -0
  12. wml/img_utils.py +571 -0
  13. wml/iotoolkit/__init__.py +17 -0
  14. wml/iotoolkit/aic_keypoint.py +115 -0
  15. wml/iotoolkit/baidu_mask_toolkit.py +244 -0
  16. wml/iotoolkit/base_dataset.py +210 -0
  17. wml/iotoolkit/bboxes_statistics.py +515 -0
  18. wml/iotoolkit/build.py +0 -0
  19. wml/iotoolkit/cityscapes_toolkit.py +183 -0
  20. wml/iotoolkit/classification_data_statistics.py +25 -0
  21. wml/iotoolkit/coco_data_fwd.py +225 -0
  22. wml/iotoolkit/coco_keypoints.py +118 -0
  23. wml/iotoolkit/coco_keypoints_fmt2.py +103 -0
  24. wml/iotoolkit/coco_toolkit.py +397 -0
  25. wml/iotoolkit/coco_wholebody.py +269 -0
  26. wml/iotoolkit/common.py +108 -0
  27. wml/iotoolkit/crowd_pose.py +146 -0
  28. wml/iotoolkit/fast_labelme.py +110 -0
  29. wml/iotoolkit/image_folder.py +95 -0
  30. wml/iotoolkit/imgs_cache.py +58 -0
  31. wml/iotoolkit/imgs_reader_mt.py +73 -0
  32. wml/iotoolkit/labelme_base.py +102 -0
  33. wml/iotoolkit/labelme_json_to_img.py +49 -0
  34. wml/iotoolkit/labelme_toolkit.py +117 -0
  35. wml/iotoolkit/labelme_toolkit_fwd.py +733 -0
  36. wml/iotoolkit/labelmemckeypoints_dataset.py +169 -0
  37. wml/iotoolkit/lspet.py +48 -0
  38. wml/iotoolkit/mapillary_vistas_toolkit.py +269 -0
  39. wml/iotoolkit/mat_data.py +90 -0
  40. wml/iotoolkit/mckeypoints_statistics.py +28 -0
  41. wml/iotoolkit/mot_datasets.py +62 -0
  42. wml/iotoolkit/mpii.py +108 -0
  43. wml/iotoolkit/npmckeypoints_dataset.py +164 -0
  44. wml/iotoolkit/o365_to_coco.py +136 -0
  45. wml/iotoolkit/object365_toolkit.py +156 -0
  46. wml/iotoolkit/object365v2_toolkit.py +71 -0
  47. wml/iotoolkit/pascal_voc_data.py +51 -0
  48. wml/iotoolkit/pascal_voc_toolkit.py +194 -0
  49. wml/iotoolkit/pascal_voc_toolkit_fwd.py +473 -0
  50. wml/iotoolkit/penn_action.py +57 -0
  51. wml/iotoolkit/rawframe_dataset.py +129 -0
  52. wml/iotoolkit/rewrite_pascal_voc.py +28 -0
  53. wml/iotoolkit/semantic_data.py +49 -0
  54. wml/iotoolkit/split_file_by_type.py +29 -0
  55. wml/iotoolkit/sports_mot_datasets.py +78 -0
  56. wml/iotoolkit/vis_objectdetection_dataset.py +70 -0
  57. wml/iotoolkit/vis_torch_data.py +39 -0
  58. wml/iotoolkit/yolo_toolkit.py +38 -0
  59. wml/object_detection2/__init__.py +4 -0
  60. wml/object_detection2/basic_visualization.py +37 -0
  61. wml/object_detection2/bboxes.py +812 -0
  62. wml/object_detection2/data_process_toolkit.py +146 -0
  63. wml/object_detection2/keypoints.py +292 -0
  64. wml/object_detection2/mask.py +120 -0
  65. wml/object_detection2/metrics/__init__.py +3 -0
  66. wml/object_detection2/metrics/build.py +15 -0
  67. wml/object_detection2/metrics/classifier_toolkit.py +440 -0
  68. wml/object_detection2/metrics/common.py +71 -0
  69. wml/object_detection2/metrics/mckps_toolkit.py +338 -0
  70. wml/object_detection2/metrics/toolkit.py +1953 -0
  71. wml/object_detection2/npod_toolkit.py +361 -0
  72. wml/object_detection2/odtools.py +243 -0
  73. wml/object_detection2/standard_names.py +75 -0
  74. wml/object_detection2/visualization.py +956 -0
  75. wml/object_detection2/wmath.py +34 -0
  76. wml/semantic/__init__.py +0 -0
  77. wml/semantic/basic_toolkit.py +65 -0
  78. wml/semantic/mask_utils.py +156 -0
  79. wml/semantic/semantic_test.py +21 -0
  80. wml/semantic/structures.py +1 -0
  81. wml/semantic/toolkit.py +105 -0
  82. wml/semantic/visualization_utils.py +658 -0
  83. wml/threadtoolkit.py +50 -0
  84. wml/walgorithm.py +228 -0
  85. wml/wcollections.py +212 -0
  86. wml/wfilesystem.py +487 -0
  87. wml/wml_utils.py +657 -0
  88. wml/wstructures/__init__.py +4 -0
  89. wml/wstructures/common.py +9 -0
  90. wml/wstructures/keypoints_train_toolkit.py +149 -0
  91. wml/wstructures/kps_structures.py +579 -0
  92. wml/wstructures/mask_structures.py +1161 -0
  93. wml/wtorch/__init__.py +8 -0
  94. wml/wtorch/bboxes.py +104 -0
  95. wml/wtorch/classes_suppression.py +24 -0
  96. wml/wtorch/conv_module.py +181 -0
  97. wml/wtorch/conv_ws.py +144 -0
  98. wml/wtorch/data/__init__.py +16 -0
  99. wml/wtorch/data/_utils/__init__.py +45 -0
  100. wml/wtorch/data/_utils/collate.py +183 -0
  101. wml/wtorch/data/_utils/fetch.py +47 -0
  102. wml/wtorch/data/_utils/pin_memory.py +121 -0
  103. wml/wtorch/data/_utils/signal_handling.py +72 -0
  104. wml/wtorch/data/_utils/worker.py +227 -0
  105. wml/wtorch/data/base_data_loader_iter.py +93 -0
  106. wml/wtorch/data/dataloader.py +501 -0
  107. wml/wtorch/data/datapipes/__init__.py +1 -0
  108. wml/wtorch/data/datapipes/iter/__init__.py +12 -0
  109. wml/wtorch/data/datapipes/iter/batch.py +126 -0
  110. wml/wtorch/data/datapipes/iter/callable.py +92 -0
  111. wml/wtorch/data/datapipes/iter/listdirfiles.py +37 -0
  112. wml/wtorch/data/datapipes/iter/loadfilesfromdisk.py +30 -0
  113. wml/wtorch/data/datapipes/iter/readfilesfromtar.py +60 -0
  114. wml/wtorch/data/datapipes/iter/readfilesfromzip.py +63 -0
  115. wml/wtorch/data/datapipes/iter/sampler.py +94 -0
  116. wml/wtorch/data/datapipes/utils/__init__.py +0 -0
  117. wml/wtorch/data/datapipes/utils/common.py +65 -0
  118. wml/wtorch/data/dataset.py +354 -0
  119. wml/wtorch/data/datasets/__init__.py +4 -0
  120. wml/wtorch/data/datasets/common.py +53 -0
  121. wml/wtorch/data/datasets/listdirfilesdataset.py +36 -0
  122. wml/wtorch/data/datasets/loadfilesfromdiskdataset.py +30 -0
  123. wml/wtorch/data/distributed.py +135 -0
  124. wml/wtorch/data/multi_processing_data_loader_iter.py +866 -0
  125. wml/wtorch/data/sampler.py +267 -0
  126. wml/wtorch/data/single_process_data_loader_iter.py +24 -0
  127. wml/wtorch/data/test_data_loader.py +26 -0
  128. wml/wtorch/dataset_toolkit.py +67 -0
  129. wml/wtorch/depthwise_separable_conv_module.py +98 -0
  130. wml/wtorch/dist.py +591 -0
  131. wml/wtorch/dropblock/__init__.py +6 -0
  132. wml/wtorch/dropblock/dropblock.py +228 -0
  133. wml/wtorch/dropblock/dropout.py +40 -0
  134. wml/wtorch/dropblock/scheduler.py +48 -0
  135. wml/wtorch/ema.py +61 -0
  136. wml/wtorch/fc_module.py +73 -0
  137. wml/wtorch/functional.py +34 -0
  138. wml/wtorch/iter_dataset.py +26 -0
  139. wml/wtorch/loss.py +69 -0
  140. wml/wtorch/nets/__init__.py +0 -0
  141. wml/wtorch/nets/ckpt_toolkit.py +219 -0
  142. wml/wtorch/nets/fpn.py +276 -0
  143. wml/wtorch/nets/hrnet/__init__.py +0 -0
  144. wml/wtorch/nets/hrnet/config.py +2 -0
  145. wml/wtorch/nets/hrnet/hrnet.py +494 -0
  146. wml/wtorch/nets/misc.py +249 -0
  147. wml/wtorch/nets/resnet/__init__.py +0 -0
  148. wml/wtorch/nets/resnet/layers/__init__.py +17 -0
  149. wml/wtorch/nets/resnet/layers/aspp.py +144 -0
  150. wml/wtorch/nets/resnet/layers/batch_norm.py +231 -0
  151. wml/wtorch/nets/resnet/layers/blocks.py +111 -0
  152. wml/wtorch/nets/resnet/layers/wrappers.py +110 -0
  153. wml/wtorch/nets/resnet/r50_config.py +38 -0
  154. wml/wtorch/nets/resnet/resnet.py +691 -0
  155. wml/wtorch/nets/shape_spec.py +20 -0
  156. wml/wtorch/nets/simple_fpn.py +101 -0
  157. wml/wtorch/nms.py +109 -0
  158. wml/wtorch/nn.py +896 -0
  159. wml/wtorch/ocr_block.py +193 -0
  160. wml/wtorch/summary.py +331 -0
  161. wml/wtorch/train_toolkit.py +603 -0
  162. wml/wtorch/transformer_blocks.py +266 -0
  163. wml/wtorch/utils.py +719 -0
  164. wml/wtorch/wlr_scheduler.py +100 -0
@@ -0,0 +1,361 @@
1
+ #coding=utf-8
2
+ import numpy as np
3
+ import math
4
+
5
+ '''
6
+ bboxes:[X,4], ymin,xmin,ymax,xmax, relative coordinate
7
+ '''
8
+ def bboxes_jaccard(bboxes1, bboxes2):
9
+
10
+ bboxes1 = np.transpose(bboxes1)
11
+ bboxes2 = np.transpose(bboxes2)
12
+
13
+ int_ymin = np.maximum(bboxes1[0], bboxes2[0])
14
+ int_xmin = np.maximum(bboxes1[1], bboxes2[1])
15
+ int_ymax = np.minimum(bboxes1[2], bboxes2[2])
16
+ int_xmax = np.minimum(bboxes1[3], bboxes2[3])
17
+
18
+ int_h = np.maximum(int_ymax - int_ymin, 0.)
19
+ int_w = np.maximum(int_xmax - int_xmin, 0.)
20
+ int_vol = int_h * int_w
21
+
22
+ vol1 = (bboxes1[2] - bboxes1[0]) * (bboxes1[3] - bboxes1[1])
23
+ vol2 = (bboxes2[2] - bboxes2[0]) * (bboxes2[3] - bboxes2[1])
24
+ jaccard = int_vol / (vol1 + vol2 - int_vol)
25
+ return jaccard
26
+ '''
27
+ box0,box1: ymin,xmin,ymax,xmax
28
+ '''
29
+ def box_jaccard(box0,box1):
30
+ ymin0, xmin0, ymax0, xmax0 = box0[0],box0[1],box0[2],box0[3]
31
+ ymin1, xmin1, ymax1, xmax1 = box1[0],box1[1],box1[2],box1[3]
32
+ int_ymin = max(ymin0,ymin1)
33
+ int_xmin = max(xmin0,xmin1)
34
+ int_ymax = min(ymax0,ymax1)
35
+ int_xmax = min(xmax0,xmax1)
36
+ int_w = max(int_xmax-int_xmin,0.)
37
+ int_h = max(int_ymax-int_ymin,0.)
38
+ int_vol = int_w*int_h
39
+ union_box_vol = box_vol(box0)+box_vol(box1)-int_vol
40
+
41
+ if union_box_vol < 1e-8:
42
+ return 0.0
43
+ return int_vol/union_box_vol
44
+ '''
45
+ get the unio volume over bboxes's volume.
46
+ bboxes_ref:[4] ymin,xmin,ymax,xmax, relative coordinate
47
+ bboxes2:[X,4], ymin,xmin,ymax,xmax, relative coordinate
48
+ '''
49
+ def bboxes_intersection(bboxes_ref, bboxes):
50
+
51
+ bboxes_ref = np.transpose(bboxes_ref)
52
+ bboxes = np.transpose(bboxes)
53
+ # Intersection bbox and volume.
54
+ int_ymin = np.maximum(bboxes_ref[0], bboxes[0])
55
+ int_xmin = np.maximum(bboxes_ref[1], bboxes[1])
56
+ int_ymax = np.minimum(bboxes_ref[2], bboxes[2])
57
+ int_xmax = np.minimum(bboxes_ref[3], bboxes[3])
58
+
59
+ int_h = np.maximum(int_ymax - int_ymin, 0.)
60
+ int_w = np.maximum(int_xmax - int_xmin, 0.)
61
+ int_vol = int_h * int_w
62
+ # Union volume.
63
+ vol = (bboxes[2] - bboxes[0]) * (bboxes[3] - bboxes[1])
64
+ score = int_vol / vol
65
+ return score
66
+
67
+ '''
68
+ get the unio volume over bboxes_ref's volume.
69
+ bboxes_ref:[4] ymin,xmin,ymax,xmax, relative coordinate
70
+ bboxes2:[X,4], ymin,xmin,ymax,xmax, relative coordinate
71
+ '''
72
+ def bboxes_intersection_r(bboxes_ref, bboxes):
73
+ if bboxes.shape[0] == 0 or bboxes_ref.shape[0] == 0:
74
+ return np.array([],dtype=np.float32)
75
+
76
+ bboxes = np.transpose(bboxes)
77
+ # Intersection bbox and volume.
78
+ int_ymin = np.maximum([bboxes_ref[0]], bboxes[0])
79
+ int_xmin = np.maximum([bboxes_ref[1]], bboxes[1])
80
+ int_ymax = np.minimum([bboxes_ref[2]], bboxes[2])
81
+ int_xmax = np.minimum([bboxes_ref[3]], bboxes[3])
82
+
83
+ int_h = np.maximum(int_ymax - int_ymin, 0.)
84
+ int_w = np.maximum(int_xmax - int_xmin, 0.)
85
+ int_vol = int_h * int_w
86
+ # Union volume.
87
+ vol = (bboxes_ref[2] - bboxes_ref[0]) * (bboxes_ref[3] - bboxes_ref[1])
88
+ score = int_vol / vol
89
+ return score
90
+
91
+ '''
92
+ classes wise nms implementation by numpy.
93
+ classes:[X]
94
+ scores:[X]
95
+ bboxes:[X,4]
96
+ '''
97
+ def bboxes_nms(classes, scores, bboxes, nms_threshold=0.5):
98
+
99
+ keep_bboxes = np.ones(scores.shape, dtype=np.bool)
100
+ for i in range(scores.size-1):
101
+ if keep_bboxes[i]:
102
+ # Computer overlap with bboxes which are following.
103
+ overlap = bboxes_jaccard(bboxes[i], bboxes[(i+1):])
104
+ # Overlap threshold for keeping + checking part of the same class
105
+ keep_overlap = np.logical_or(overlap < nms_threshold, classes[(i+1):] != classes[i])
106
+ keep_bboxes[(i+1):] = np.logical_and(keep_bboxes[(i+1):], keep_overlap)
107
+
108
+ idxes = np.where(keep_bboxes)
109
+ return classes[idxes], scores[idxes], bboxes[idxes]
110
+
111
+ '''
112
+ crop a sub area sub_box in image, return the boxes IOU with sub_box greater than remove_threshold
113
+ bboxes:[X,4] ymin,xmin,ymax,xmax, relative coordinate
114
+ return:
115
+ bboxes:[Y,4],mask [X]
116
+ '''
117
+ def crop_box(bboxes,sub_box,remove_threshold=0.7):
118
+ h = sub_box[2]-sub_box[0]
119
+ w = sub_box[3]-sub_box[1]
120
+ if h<1e-8 or w<1e-8:
121
+ return None
122
+ if not isinstance(bboxes,np.ndarray):
123
+ bboxes = np.array(bboxes)
124
+ jaccard = bboxes_intersection(bboxes_ref=sub_box,bboxes=bboxes)
125
+ mask = jaccard>remove_threshold
126
+ bboxes = bboxes[mask]
127
+ if bboxes.shape[0] == 0:
128
+ return bboxes,mask
129
+ top_left = np.array([[sub_box[0],sub_box[1],sub_box[0],sub_box[1]]],dtype=np.float32)
130
+ bboxes = (bboxes-top_left)/np.array([[h,w,h,w]],dtype=np.float32)
131
+ bboxes = correct_boxes(bboxes)
132
+ return bboxes,mask
133
+
134
+ '''
135
+ bboxes:[X,4], ymin,xmin,ymax,xmax releative coordinate.
136
+ '''
137
+ def correct_boxes(bboxes):
138
+ bboxes = np.transpose(bboxes,[1,0])
139
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
140
+ ymin = np.maximum(ymin,0.)
141
+ ymax = np.minimum(ymax,1.)
142
+ xmin = np.maximum(xmin,0.)
143
+ xmax = np.minimum(xmax,1.)
144
+ bboxes = np.stack([ymin,xmin,ymax,xmax],axis=0)
145
+ bboxes = np.transpose(bboxes)
146
+ return bboxes
147
+
148
+ def box_vol(box):
149
+ return (box[2]-box[0])*(box[3]-box[1])
150
+ '''
151
+ box0,box1: shape=[4] ymin,xmin,ymax,xmax
152
+ 交叉面积占box0的百分比
153
+ '''
154
+ def bbox_intersection(box0,box1):
155
+ ymin0, xmin0, ymax0, xmax0 = box0[0],box0[1],box0[2],box0[3]
156
+ ymin1, xmin1, ymax1, xmax1 = box1[0],box1[1],box1[2],box1[3]
157
+ int_ymin = max(ymin0,ymin1)
158
+ int_xmin = max(xmin0,xmin1)
159
+ int_ymax = min(ymax0,ymax1)
160
+ int_xmax = min(xmax0,xmax1)
161
+ int_w = max(int_xmax-int_xmin,0.)
162
+ int_h = max(int_ymax-int_ymin,0.)
163
+ int_vol = int_w*int_h
164
+ box0_vol = box_vol(box0)
165
+
166
+ if box0_vol < 1e-8:
167
+ return 0.0
168
+ return int_vol/box0_vol
169
+
170
+ '''
171
+ 删除与边界nms大于指定值的box
172
+ boundary:[h,w]
173
+ '''
174
+ def remove_boundary_boxes(bboxes,boundary=[0.1,0.1],threshold=0.9):
175
+ assert len(bboxes.shape)==2,"error bboxes shape"
176
+ boxes_nr = bboxes.shape[0]
177
+ boundary_w = boundary[1]
178
+ boundary_h = boundary[0]
179
+ if boxes_nr == 0:
180
+ return bboxes,np.array([],dtype=np.bool)
181
+ keep_indicts = np.ones(shape=[boxes_nr],dtype=np.bool)
182
+ boundary_boxes = np.array([[0.0,0.0,1.0,boundary_w],
183
+ [0.0, 1-boundary_w, 1.0, 1.0],
184
+ [0.0,0.0,boundary_h,1.0],
185
+ [1.0-boundary_h, 0.0, 1.0, 1.0]],dtype=np.float32)
186
+
187
+ for i in range(boxes_nr):
188
+ for j in range(boundary_boxes.shape[0]):
189
+ if bbox_intersection(bboxes[i],boundary_boxes[j]) > threshold:
190
+ keep_indicts[i] = False
191
+ break
192
+
193
+ return bboxes[keep_indicts],keep_indicts
194
+ '''
195
+ box:[x,4] 使用相对坐标表示,其参考区域为sub_box
196
+ sub_box: [ymin,xmin,ymax,xmax] 可使用相对坐标或绝对坐标,返回的box表示与sub_box相同
197
+ 函数返回box在[0,0,1,1]区域的表示值
198
+ '''
199
+ def restore_sub_area(bboxes,sub_box):
200
+ h = sub_box[2]-sub_box[0]
201
+ w = sub_box[3]-sub_box[1]
202
+ bboxes = np.transpose(bboxes,[1,0])
203
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
204
+ ymin = ymin*h+sub_box[0]
205
+ ymax = ymax*h+sub_box[0]
206
+ xmin = xmin*w+sub_box[1]
207
+ xmax = xmax*w+sub_box[1]
208
+ bboxes = np.stack([ymin,xmin,ymax,xmax],axis=0)
209
+ bboxes = np.transpose(bboxes)
210
+ return bboxes
211
+
212
+ def bboxes_flip_left_right(bboxes):
213
+ bboxes = np.transpose(bboxes)
214
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
215
+ nxmax = 1.0-xmin
216
+ nxmin = 1.0-xmax
217
+ bboxes = np.stack([ymin,nxmin,ymax,nxmax],axis=0)
218
+ bboxes = np.transpose(bboxes)
219
+ return bboxes
220
+
221
+ def bboxes_flip_up_down(bboxes):
222
+ bboxes = np.transpose(bboxes)
223
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
224
+ nymax = 1.0-ymin
225
+ nymin = 1.0- ymax
226
+ bboxes = np.stack([nymin,xmin,nymax,xmax],axis=0)
227
+ bboxes = np.transpose(bboxes)
228
+ return bboxes
229
+
230
+ '''
231
+ get a envolope box of boxes.
232
+ bboxes:[X,4]
233
+ '''
234
+ def envolope_of_boxes(bboxes):
235
+ if bboxes.shape[0]==0:
236
+ return np.array([0.,0.,1.,1.],dtype=np.float32)
237
+ bboxes = np.transpose(bboxes,[1,0])
238
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
239
+ ymin = ymin.min()
240
+ xmin = xmin.min()
241
+ ymax = ymax.max()
242
+ xmax = xmax.max()
243
+
244
+ return np.array([ymin,xmin,ymax,xmax])
245
+
246
+ def minmax_to_cyxhw(bboxes):
247
+ bboxes = np.transpose(bboxes,[1,0])
248
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
249
+ cx = (xmax+xmin)/2.
250
+ cy = (ymax+ymin)/2.
251
+ w = (xmax-xmin)
252
+ h = (ymax-ymin)
253
+ bboxes = np.stack([cy,cx,h,w],axis=0)
254
+ bboxes = np.transpose(bboxes,axes=[1,0])
255
+ return bboxes
256
+
257
+ def minmax_to_cyxsr(bboxes,h=1.0,w=1.0):
258
+ bboxes = np.transpose(bboxes,[1,0])
259
+ ymin,xmin,ymax,xmax = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
260
+ cx = (xmax+xmin)/2.
261
+ cy = (ymax+ymin)/2.
262
+ w = (xmax-xmin)*w
263
+ h = (ymax-ymin)*h
264
+ s = w*h
265
+ r = h/w
266
+ bboxes = np.stack([cy,cx,s,r],axis=0)
267
+ bboxes = np.transpose(bboxes,axes=[1,0])
268
+ return bboxes
269
+
270
+ def cyxhw_to_minmax(bboxes):
271
+ bboxes = np.transpose(bboxes,[1,0])
272
+ cy, cx, h, w = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
273
+ ymin = cy-h/2.
274
+ ymax = cy+h/2.
275
+ xmin = cx-w/2.
276
+ xmax = cx+w/2.
277
+ bboxes = np.stack([ymin,xmin,ymax,xmax],axis=0)
278
+ bboxes = np.transpose(bboxes)
279
+ return bboxes
280
+ '''
281
+ return the distance of two boxes's center point.
282
+ '''
283
+ def box_dis(box0,box1):
284
+ box0 = minmax_to_cyxhw([box0])
285
+ box1 = minmax_to_cyxhw([box1])
286
+
287
+ dy = box0[0][0]-box1[0][0]
288
+ dx = box0[0][1]-box1[0][1]
289
+ return math.sqrt(dy*dy+dx*dx)
290
+ '''
291
+ return the aspect(h/w) of a box.
292
+ '''
293
+ def box_aspect(boxes):
294
+ bboxes = minmax_to_cyxhw(boxes)
295
+ bboxes = np.transpose(bboxes,[1,0])
296
+ cy, cx, h, w = bboxes[0],bboxes[1],bboxes[2],bboxes[3]
297
+ aspect = h/w
298
+ return aspect
299
+
300
+ def bboxes_decode(feat_localizations,
301
+ anchor_bboxes,
302
+ prior_scaling=[0.1, 0.1, 0.2, 0.2]):
303
+
304
+ l_shape = feat_localizations.shape
305
+ feat_localizations = np.reshape(feat_localizations,
306
+ (-1, l_shape[-2], l_shape[-1]))
307
+ yref, xref, href, wref = anchor_bboxes
308
+ xref = np.reshape(xref, [-1, 1])
309
+ yref = np.reshape(yref, [-1, 1])
310
+
311
+ cx = feat_localizations[:, :, 0] * wref * prior_scaling[0] + xref
312
+ cy = feat_localizations[:, :, 1] * href * prior_scaling[1] + yref
313
+ w = wref * np.exp(feat_localizations[:, :, 2] * prior_scaling[2])
314
+ h = href * np.exp(feat_localizations[:, :, 3] * prior_scaling[3])
315
+ # bboxes: ymin, xmin, xmax, ymax.
316
+ bboxes = np.zeros_like(feat_localizations)
317
+ bboxes[:, :, 0] = cy - h / 2.
318
+ bboxes[:, :, 1] = cx - w / 2.
319
+ bboxes[:, :, 2] = cy + h / 2.
320
+ bboxes[:, :, 3] = cx + w / 2.
321
+ bboxes = np.reshape(bboxes, l_shape)
322
+ return bboxes
323
+
324
+ def bboxes_selectv2(predictions_layer,
325
+ localizations_layer,
326
+ select_threshold=0.5):
327
+
328
+ p_shape = predictions_layer.shape
329
+ batch_size = p_shape[0] if len(p_shape) == 5 else 1
330
+ predictions_layer = np.reshape(predictions_layer,
331
+ (batch_size, -1, p_shape[-1]))
332
+ l_shape = localizations_layer.shape
333
+ localizations_layer = np.reshape(localizations_layer,
334
+ (batch_size, -1, l_shape[-1]))
335
+
336
+ sub_predictions = predictions_layer[:, :, 1:]
337
+ idxes = np.where(sub_predictions > select_threshold)
338
+ classes = idxes[-1] + 1
339
+ scores = sub_predictions[idxes]
340
+ bboxes = localizations_layer[idxes[:-1]]
341
+
342
+ return classes, scores, bboxes
343
+
344
+ def bboxes_sort(classes, scores, bboxes, top_k=400):
345
+ idxes = np.argsort(-scores)
346
+ classes = classes[idxes][:top_k]
347
+ scores = scores[idxes][:top_k]
348
+ bboxes = bboxes[idxes][:top_k]
349
+ return classes, scores, bboxes
350
+
351
+ def bboxes_filter(bboxes,labels, probs,threshold=0.5):
352
+
353
+ keep_bboxes = np.greater_equal(probs,threshold)
354
+ idxes = np.where(keep_bboxes)
355
+ if not isinstance(bboxes,np.ndarray):
356
+ bboxes = np.array(bboxes)
357
+ if not isinstance(labels,np.ndarray):
358
+ labels = np.array(labels)
359
+ if not isinstance(probs,np.ndarray):
360
+ probs = np.array(probs)
361
+ return bboxes[idxes],labels[idxes],probs[idxes],idxes
@@ -0,0 +1,243 @@
1
+ #coding=utf-8
2
+ import numpy as np
3
+ import wml.object_detection2.bboxes as odb
4
+ import wml.img_utils as wmli
5
+ import copy
6
+ from .mask import get_bboxes_by_mask
7
+ from itertools import count
8
+
9
+
10
+ '''
11
+ image_data:[h,w,c]
12
+ bboxes:[N,4] absolute coordinate
13
+ rect:[ymin,xmin,ymax,xmax) absolute coordinate
14
+ '''
15
+ def cut_bboxes(bboxes,labels,img,rect,threshold=0.5,fill_color=None,is_sub_img=False):
16
+ res_bboxes = []
17
+ res_labels = []
18
+
19
+ if not isinstance(labels,np.ndarray):
20
+ labels = np.array(labels)
21
+
22
+ remove_bboxes = []
23
+ no_zero = 1e-3
24
+ for i in range(labels.shape[0]):
25
+ iou = odb.npbboxes_intersection_of_box0([bboxes[i]],rect)
26
+ if iou<threshold and iou>no_zero:
27
+ remove_bboxes.append(bboxes[i])
28
+ elif iou>=threshold:
29
+ res_bboxes.append(bboxes[i])
30
+ res_labels.append(labels[i])
31
+
32
+ if not is_sub_img:
33
+ img = wmli.sub_image(img,rect)
34
+
35
+ if fill_color is not None and len(remove_bboxes)>0:
36
+ remove_bboxes = np.stack(remove_bboxes, axis=0) - np.array([[rect[0], rect[1], rect[0], rect[1]]])
37
+ remove_bboxes = remove_bboxes.astype(np.int32)
38
+ img = wmli.remove_boxes_of_img(img,remove_bboxes,default_value=fill_color)
39
+
40
+ if len(res_labels)>0:
41
+ res_bboxes = np.stack(res_bboxes,axis=0) - np.array([[rect[0],rect[1],rect[0],rect[1]]])
42
+ res_labels = np.array(res_labels)
43
+ else:
44
+ res_bboxes = np.zeros(shape=[0,4],dtype=bboxes.dtype)
45
+ res_labels = np.zeros(shape=[0],dtype=labels.dtype)
46
+
47
+ return res_bboxes,res_labels,img
48
+
49
+ '''
50
+ 在每一个标目标附近裁剪出一个子图
51
+ bboxes: [N,4] absolute coordinate
52
+ size:[H,W]
53
+ return:
54
+ [N,4] (ymin,xmin,ymax,xmax) absolute coordinate
55
+ '''
56
+ def get_random_cut_bboxes_rect(bboxes,size,img_size):
57
+ res = []
58
+ y_max,x_max = img_size[0],img_size[1]
59
+ if not isinstance(bboxes,np.ndarray):
60
+ bboxes = np.array(bboxes)
61
+ if bboxes.shape[0] == 0:
62
+ return []
63
+ obj_ann_bboxes = odb.expand_bbox_by_size(bboxes,[x//2 for x in size],format='yxminmax')
64
+ obj_ann_bboxes = odb.to_xyminwh(obj_ann_bboxes)
65
+
66
+
67
+ for t_bbox in obj_ann_bboxes:
68
+ t_bbox = list(t_bbox)
69
+ t_bbox[1] = max(0,min(t_bbox[1],y_max))
70
+ t_bbox[0] = max(0,min(t_bbox[0],x_max))
71
+ t_bbox = odb.random_bbox_in_bbox(t_bbox,size)
72
+ rect = (t_bbox[1],t_bbox[0],t_bbox[1]+t_bbox[3],t_bbox[0]+t_bbox[2])
73
+
74
+ res.append(rect)
75
+ return res
76
+
77
+ '''
78
+ 在每一个标目标附近裁剪出一个子图, 如果一个bbox已经出现在前面的某一个rect中则跳过
79
+ 用于保证一个instance仅在结果中出现一次
80
+ bboxes: [N,4] absolute coordinate
81
+ size:[H,W]
82
+ return:
83
+ [N,4] (ymin,xmin,ymax,xmax) absolute coordinate
84
+ '''
85
+ def get_random_cut_bboxes_rectv2(bboxes,size,img_size,labels=None,force_cut_labels=None):
86
+ res = []
87
+ y_max,x_max = img_size[0],img_size[1]
88
+ if not isinstance(bboxes,np.ndarray):
89
+ bboxes = np.array(bboxes)
90
+ if bboxes.shape[0] == 0:
91
+ return []
92
+ obj_ann_bboxes = odb.expand_bbox_by_size(bboxes,[x//2 for x in size],format='yxminmax')
93
+ obj_ann_bboxes = odb.to_xyminwh(obj_ann_bboxes)
94
+
95
+
96
+ for i,t_bbox in enumerate(obj_ann_bboxes):
97
+ bbox = bboxes[i]
98
+ if len(res)>0:
99
+ if labels is None or (labels[i] not in force_cut_labels):
100
+ ious = odb.npbboxes_intersection_of_box0(bbox,res)
101
+ max_index = np.argmax(ious)
102
+ if ious[max_index]>0.9:
103
+ continue
104
+ t_bbox = list(t_bbox)
105
+ t_bbox[1] = max(0,min(t_bbox[1],y_max))
106
+ t_bbox[0] = max(0,min(t_bbox[0],x_max))
107
+ t_bbox = odb.random_bbox_in_bbox(t_bbox,size)
108
+ rect = (t_bbox[1],t_bbox[0],t_bbox[1]+t_bbox[3],t_bbox[0]+t_bbox[2])
109
+
110
+ res.append(rect)
111
+ return res
112
+
113
+ def filter_by_classeswise_thresholds(labels,bboxes,probs,thresholds):
114
+ '''
115
+
116
+ :param labels: [N]
117
+ :param bboxes: [N,4]
118
+ :param probs: [N]
119
+ :param thresholds: 不包含背景0
120
+ :return:
121
+ '''
122
+ n_labels = []
123
+ n_bboxes = []
124
+ n_probs = []
125
+
126
+ for i,l in enumerate(labels):
127
+ tp = thresholds[l-1]
128
+ p = probs[i]
129
+ if tp<=p:
130
+ n_labels.append(l)
131
+ n_bboxes.append(bboxes[i])
132
+ n_probs.append(p)
133
+
134
+ return np.array(n_labels),np.array(n_bboxes),np.array(n_probs)
135
+
136
+ class WCrop:
137
+ '''
138
+ '''
139
+
140
+ def __init__(self,
141
+ img_pad_value=127,
142
+ mask_pad_value=0,
143
+ bbox_keep_ratio=0.2,
144
+ mask_domina=True):
145
+
146
+ self.img_pad_value = img_pad_value
147
+ self.mask_pad_value = mask_pad_value
148
+ self.bbox_keep_ratio = bbox_keep_ratio
149
+ self.mask_domina = mask_domina
150
+
151
+ def apply(self, results,crop_bbox):
152
+ """Random crop and around padding the original image.
153
+
154
+ Args:
155
+ results (dict): Image infomations in the augment pipeline.
156
+
157
+ Returns:
158
+ results (dict): The updated dict.
159
+ """
160
+ img = results['img']
161
+ patch = crop_bbox
162
+ try:
163
+ cropped_img = wmli.crop_and_pad(img, patch,pad_color=self.img_pad_value)
164
+ except:
165
+ print("Crop error:",patch)
166
+
167
+ x_offset = patch[0]
168
+ y_offset = patch[1]
169
+ new_w = patch[2]-x_offset
170
+ new_h = patch[3]-y_offset
171
+ results['img'] = cropped_img
172
+ results['img_shape'] = cropped_img.shape
173
+ results['pad_shape'] = cropped_img.shape
174
+
175
+ # crop bboxes accordingly and clip to the image boundary
176
+ for key in results.get('bbox_fields', ['gt_bboxes']):
177
+ bboxes = results[key]
178
+ old_bboxes = copy.deepcopy(bboxes)
179
+ old_area = odb.area(old_bboxes)
180
+ bboxes[:, 0:4:2] -= x_offset
181
+ bboxes[:, 1:4:2] -= y_offset
182
+ bboxes[:, 0:4:2] = np.clip(bboxes[:, 0:4:2], 0, new_w)
183
+ bboxes[:, 1:4:2] = np.clip(bboxes[:, 1:4:2], 0, new_h)
184
+ keep0 = (bboxes[:, 2] > bboxes[:, 0]) & (
185
+ bboxes[:, 3] > bboxes[:, 1])
186
+ new_area = odb.area(bboxes)
187
+ area_ratio = new_area/(old_area+1e-6)
188
+ keep1 = area_ratio>self.bbox_keep_ratio
189
+ keep = np.logical_and(keep0,keep1)
190
+ bboxes = bboxes[keep]
191
+ results[key] = bboxes
192
+ if key in ['gt_bboxes']:
193
+ if 'gt_labels' in results:
194
+ labels = results['gt_labels']
195
+ labels = labels[keep]
196
+ results['gt_labels'] = labels
197
+ if 'gt_masks' in results:
198
+ gt_masks = results['gt_masks']
199
+ gt_masks = gt_masks[keep]
200
+ gt_masks = wmli.crop_masks_absolute_xy(gt_masks,patch)
201
+ results['gt_masks'] = gt_masks
202
+
203
+ if self.mask_domina:
204
+ old_area = old_area[keep]
205
+ bboxes = get_bboxes_by_mask(gt_masks)
206
+ new_area = odb.area(bboxes)
207
+ area_ratio = new_area/(old_area+1e-6)
208
+ keep = area_ratio>self.bbox_keep_ratio
209
+ bboxes = bboxes[keep]
210
+ results[key] = bboxes
211
+ if 'gt_labels' in results:
212
+ labels = results['gt_labels']
213
+ labels = labels[keep]
214
+ results['gt_labels'] = labels
215
+ gt_masks = gt_masks[keep]
216
+ results['gt_masks'] = gt_masks
217
+
218
+ return results
219
+
220
+ def __call__(self, results,crop_bbox):
221
+ return self.apply(results,crop_bbox)
222
+
223
+
224
+ def make_text2label(classes=None,label_text2id={}):
225
+ res = {}
226
+ if classes is not None:
227
+ tmp_d = dict(zip(classes,count()))
228
+ res.update(tmp_d)
229
+
230
+ if label_text2id is not None:
231
+ for k,v in label_text2id.items():
232
+ if isinstance(v,(str,bytes)) and v in res:
233
+ res[k] = res[v]
234
+ else:
235
+ res[k] = v
236
+
237
+ for k,v in list(res.items()):
238
+ if isinstance(v,(str,bytes)) and v in res:
239
+ res[k] = res[v]
240
+
241
+ return res
242
+
243
+
@@ -0,0 +1,75 @@
1
+ #coding=utf-8
2
+ SCORES = "scores"
3
+ INDICES = "indices"
4
+ BOXES = "boxes"
5
+ LABELS = "labels"
6
+ PROBABILITY = "probability"
7
+ RAW_PROBABILITY = "raw_probability"
8
+ IMAGE = 'img'
9
+ HEIGHT = "height"
10
+ WIDTH = "width"
11
+ MASKS = "masks"
12
+ ANN_INFO = "ann_info"
13
+ IMG_INFO = "img_info"
14
+ IS_CROWD = 'is_crowd'
15
+ MASK_AREA = "mask_area"
16
+ ORG_HEIGHT = "org_height"
17
+ ORG_WIDTH = "org_width"
18
+ LOGITS = "logits"
19
+ BOXES_REGS = "box_regs"
20
+ SEMANTIC = "semantic"
21
+ COEFFICIENT = "coefficient"
22
+ IMG_METAS = "img_metas"
23
+ PROPOSAL_BBOXES = "proposal_bboxes"
24
+ SAMPLED_BBOXES = "sampled_bboxes"
25
+
26
+ GT_BOXES = 'gt_bboxes'
27
+ GT_LENGTH = 'gt_length'
28
+ GT_LABELS = 'gt_labels'
29
+ IMG_INDEX = 'idata_index'
30
+ GT_MASKS = 'gt_masks'
31
+ GT_KEYPOINTS = 'gt_keypoints'
32
+ GT_SEMANTIC_LABELS = 'gt_semantic_mask_labels'
33
+ GT_SEG_MAP = 'gt_seg_map'
34
+ GT_SEM_SEG = 'gt_sem_seg'
35
+ GT_SEMANTIC_SEG = 'gt_semantic_seg'
36
+ FILEINDEX = "fileindex"
37
+ FILENAME = "filename"
38
+ FILEPATH = "filepath"
39
+ GT_OBJECT_LOGITS = "gt_object_logits"
40
+
41
+ BBOX_FIELDS = "bbox_fields"
42
+ #Encoded data
43
+ ED_GT_OBJECT_LOGITS = "gt_object_logits"
44
+ ED_SCORES = "scores"
45
+ ED_INDICES = "indices"
46
+ ED_BOXES = "boxes"
47
+ ED_GT_BOXES = GT_BOXES
48
+ ED_GT_LABELS = GT_LABELS
49
+ ED_GT_DELTAS = "deltas"
50
+ ED_GT_DELTAS = "deltas"
51
+
52
+ #Results Data
53
+ RD_BOXES = BOXES
54
+ RD_BOXES_ABSOLUTE = BOXES+"_absolute"
55
+ RD_LABELS = LABELS
56
+ RD_PROBABILITY = PROBABILITY
57
+ RD_RAW_PROBABILITY = RAW_PROBABILITY
58
+ RD_INDICES = INDICES
59
+ RD_LENGTH = "length"
60
+ RD_MASKS = "masks" #标准格式为[batch_size,N,h,w]
61
+ RD_SEMANTIC = "semantic" #标准格式为[batch_size,N,h,w]
62
+ RD_SPARSE_SEMANTIC = "sparse_semantic" #标准格式为[batch_size,N,h,w]
63
+ RD_FULL_SIZE_MASKS = "full_size_masks" #标准格式为[batch_size,N,H,W]
64
+ RD_RESULT_IMAGE = "result_image"
65
+ RD_KEYPOINT = "keypoint"
66
+ RD_MASK_AREA = MASK_AREA
67
+ RD_ID = "rd_id"
68
+
69
+ #Proposal network't result
70
+ PD_BOXES = "boxes"
71
+ PD_PROBABILITY = PROBABILITY
72
+
73
+
74
+ GRADIENT_DEBUG_COLLECTION = "gradient_debug_collection"
75
+