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
wml/wml_utils.py ADDED
@@ -0,0 +1,657 @@
1
+ #coding=utf-8
2
+ from wml.wcollections import *
3
+ from wml.wfilesystem import *
4
+ from wml.walgorithm import *
5
+ import numpy as np
6
+ import random
7
+ import time
8
+ from functools import wraps
9
+ import sys
10
+ import datetime
11
+ import hashlib
12
+ import math
13
+ import pickle
14
+ from collections import OrderedDict
15
+ from importlib import metadata
16
+ import re
17
+ import torch
18
+
19
+
20
+ def _to_chinese_num(i,numbers,unites):
21
+ j = i%10
22
+ i = i/10
23
+ res = numbers[j]
24
+ if unites[0] is not None and len(unites)>0:
25
+ res = res+unites[0]
26
+ if i>0:
27
+ return _to_chinese_num(i,numbers,unites[1:])+res
28
+ else:
29
+ return res
30
+
31
+ def to_chinese_num(i):
32
+ if i==0:
33
+ return "零"
34
+ unites=[None,"十","百","千","万","十万","千万","亿","十亿"]
35
+ numbers=["","一","二","三","四","五","六","七","八","九"]
36
+ res = _to_chinese_num(i,numbers,unites)
37
+ if res.startswith("一十"):
38
+ res = res.decode("utf-8")
39
+ res = res[1:]
40
+ res = res.encode("utf-8")
41
+ return res
42
+
43
+
44
+ def show_member(obj,name=None):
45
+ if name is not None:
46
+ print("Show %s."%(name))
47
+
48
+ for name,var in vars(obj).items():
49
+ print("%s : "%(name),var)
50
+
51
+ def show_list(values,fmt=None,recurse=False):
52
+ if values is None:
53
+ return
54
+ if isinstance(values,str):
55
+ return show_list([values])
56
+ print("[")
57
+ if fmt is None:
58
+ for v in values:
59
+ if recurse and isinstance(v,(list,tuple,np.ndarray)):
60
+ show_list(v)
61
+ else:
62
+ print(v)
63
+ else:
64
+ for v in values:
65
+ if recurse and isinstance(v,(list,tuple,np.ndarray)):
66
+ show_list(v)
67
+ else:
68
+ print(fmt.format(v))
69
+
70
+ print("]")
71
+
72
+ def show_dict(values,format:str=None):
73
+ print("{")
74
+ for k,v in values.items():
75
+ if format is None:
76
+ print(k,":",v,",")
77
+ else:
78
+ print(k,":",format.format(v),",")
79
+ print("}")
80
+
81
+ def nparray2str(value,split=",",format="{}"):
82
+ if not isinstance(value,np.ndarray):
83
+ value = np.array(value)
84
+ ndims = len(value.shape)
85
+ if ndims == 1:
86
+ r_str = "["
87
+ for x in value[:-1]:
88
+ r_str+=format.format(x)+split
89
+ r_str+=format.format(value[-1])+"]"
90
+ return r_str
91
+ else:
92
+ r_str = "["
93
+ for x in value[:-1]:
94
+ r_str+=nparray2str(x,split=split,format=format)+split+"\n"
95
+ r_str+=nparray2str(value[-1],split=split,format=format)+"]\n"
96
+ return r_str
97
+
98
+ def show_nparray(value,name=None,split=",",format="{}"):
99
+ if name is not None:
100
+ print(name)
101
+ print(nparray2str(value,split=split,format=format))
102
+
103
+
104
+ def reduce_prod(x):
105
+ if len(x)==0:
106
+ return 0
107
+ elif len(x)==1:
108
+ return x[0]
109
+ res = x[0]
110
+ for v in x[1:]:
111
+ res *= v
112
+
113
+ return res
114
+
115
+ def any(iterable,v=None):
116
+ if v is None:
117
+ for value in iterable:
118
+ if value is None:
119
+ return True
120
+ return False
121
+ else:
122
+ t = type(v)
123
+ for value in iterable:
124
+ if isinstance(t,value) and v==value:
125
+ return True
126
+
127
+ return False
128
+
129
+ def all(iterable,v=None):
130
+ if v is None:
131
+ for value in iterable:
132
+ if value is not None:
133
+ return False
134
+ return True
135
+ else:
136
+ t = type(v)
137
+ for value in iterable:
138
+ if (not isinstance(t,value)) or v!=value:
139
+ return False
140
+
141
+ return True
142
+
143
+ def gather(data,indexs):
144
+ res_data = []
145
+
146
+ for d in indexs:
147
+ res_data.append(data[d])
148
+
149
+ return res_data
150
+
151
+ class TimeThis():
152
+ def __init__(self,name="TimeThis",auto_show=True):
153
+ self.begin_time = time.time()
154
+ self.end_time = 0
155
+ self.name = name
156
+ self.auto_show = auto_show
157
+ self.idx = 0
158
+
159
+ def __enter__(self):
160
+ self.begin_time = time.time()
161
+
162
+ def __exit__(self, exc_type, exc_val, exc_tb):
163
+ self.end_time = time.time()
164
+ if self.auto_show:
165
+ te = (self.end_time-self.begin_time)*1000
166
+ fps = 1000/(te+1e-8)
167
+ print(f"{self.name}: total time {te:.3f}ms, FPS={fps:.3f}.")
168
+
169
+ def time(self,reset=False):
170
+ self.end_time = time.time()
171
+ r = self.end_time-self.begin_time
172
+ if reset:
173
+ self.reset()
174
+ return r
175
+
176
+ def reset(self):
177
+ self.begin_time = time.time()
178
+
179
+
180
+ def log_and_restart(self,sub_name=""):
181
+ self.end_time = time.time()
182
+ te = (self.end_time - self.begin_time) * 1000
183
+ fps = 1000 / (te + 1e-8)
184
+ print(f"{self.name}:{self.idx}:{sub_name}: total time {te:.3f}, FPS={fps:.3f}.")
185
+ self.begin_time = self.end_time
186
+ self.idx += 1
187
+
188
+
189
+ class AvgTimeThis():
190
+ def __init__(self,name="TimeThis",skip_nr=3):
191
+ self.step = 0
192
+ self.begin_time = 0.
193
+ self.name = name
194
+ self.datas = []
195
+ self.skip_nr = skip_nr
196
+
197
+ def __enter__(self):
198
+ self.begin_time = time.time()
199
+
200
+ def __exit__(self, exc_type, exc_val, exc_tb):
201
+ self.step = self.step + 1
202
+ if(self.step>self.skip_nr):
203
+ self.datas.append(time.time()-self.begin_time)
204
+
205
+ def clear(self):
206
+ self.datas = []
207
+
208
+ def get_time(self):
209
+ if(len(self.datas) == 0):
210
+ return 0
211
+ return np.mean(np.array(self.datas))
212
+
213
+ def max(self):
214
+ return np.max(self.datas)
215
+
216
+ def min(self):
217
+ return np.min(self.datas)
218
+
219
+ def __str__(self):
220
+ return "AVG: "+str(self.get_time())+ f", test_nr = {self.step}"
221
+
222
+ class MTimer():
223
+ def __init__(self,name="TimeThis",auto_show=True):
224
+ self._begin_time = []
225
+ self.name = name
226
+ self.auto_show = auto_show
227
+ self.idx = 0
228
+ self.times = OrderedDict()
229
+ self.sub_name = None
230
+ self.last = 0
231
+ self.enter_size = 0
232
+
233
+ def __enter__(self,name):
234
+ self.enter_size = len(self._begin_time)
235
+ self.begin_time(name)
236
+
237
+ def __exit__(self, exc_type, exc_val, exc_tb):
238
+ self.end_time()
239
+ while len(self._begin_time)>self.enter_size:
240
+ self.end_time()
241
+
242
+
243
+ def begin_time(self,name):
244
+ torch.cuda.synchronize()
245
+ if len(self._begin_time) > 0:
246
+ name = self._begin_time[-1][0]+"."+name
247
+ self.sub_name = name
248
+ self._begin_time.append((name,time.time()))
249
+
250
+ def end_time(self,*,new_time=None):
251
+ if len(self._begin_time)==0:
252
+ print(f"Haven't begin time.")
253
+ return
254
+ torch.cuda.synchronize()
255
+ end_time = time.time()
256
+ name,begin_time = self._begin_time[-1]
257
+ if self.name is not None and len(self.name)>0:
258
+ name = self.name+": "+name
259
+ self.last = end_time-begin_time
260
+ self.times[name] = self.last
261
+ if self.auto_show:
262
+ te = (end_time-begin_time)*1000
263
+ fps = 1000/(te+1e-8)
264
+ print(f"{name}: total time {te:.3f}ms, FPS={fps:.3f}.")
265
+ self._begin_time = self._begin_time[:-1]
266
+
267
+ if new_time is not None:
268
+ self.begin_time(new_time)
269
+
270
+ def end_all(self):
271
+ while len(self._begin_time)>0:
272
+ self.end_time()
273
+
274
+ def reset(self,new_time=None):
275
+ self.end_all()
276
+ if new_time is not None:
277
+ self.begin_time(new_time)
278
+
279
+ def __repr__(self):
280
+ res = "{\n"
281
+ for k,v in self.times.items():
282
+ res += f"{k}: {v}\n"
283
+ res += "}"
284
+ return res
285
+
286
+
287
+ class MovingAvg(object):
288
+ def __init__(self,init_val = 0.0,momentum=0.99):
289
+ self.v = init_val
290
+ self.momentum = momentum
291
+
292
+ def __call__(self, v):
293
+ self.v = self.v*self.momentum+v*(1-self.momentum)
294
+
295
+ def value(self):
296
+ return self.v
297
+
298
+
299
+ class EstimateTimeCost(object):
300
+ RECORD_STEP = 100
301
+ def __init__(self,total_nr,auto_log=False,avg_step=2000):
302
+ self.begin_time = None
303
+ self.total_nr = total_nr
304
+ self.process_nr = 0
305
+ self.begin_step = 0
306
+ self._time_datas = None
307
+ self.t0 = None
308
+ self.reset()
309
+ self.auto_log = auto_log
310
+ self.avg_step = avg_step
311
+
312
+ def reset(self,total_nr = None):
313
+ self.begin_time = time.time()
314
+ self.t0 = time.time()
315
+ if total_nr is not None:
316
+ self.total_nr = total_nr
317
+ self.process_nr = 0
318
+ self.begin_step = 0
319
+ self._time_datas = None
320
+
321
+ def add_count(self):
322
+ self.process_nr += 1
323
+ if self.process_nr%EstimateTimeCost.RECORD_STEP == EstimateTimeCost.RECORD_STEP-1 and self._time_datas is None:
324
+ self._time_datas = (self.process_nr,time.time())
325
+ return self.__repr__()
326
+
327
+ def set_process_nr(self,process_nr):
328
+ self.process_nr = process_nr
329
+ if self.process_nr%EstimateTimeCost.RECORD_STEP == EstimateTimeCost.RECORD_STEP-1 and self._time_datas is None:
330
+ self._time_datas = (self.process_nr,time.time())
331
+ return self.__repr__()
332
+
333
+ def __exit__(self, exc_type, exc_val, exc_tb):
334
+ info = self.add_count()
335
+ if self.auto_log:
336
+ print(info)
337
+
338
+ def time_elapse(self):
339
+ return time.time() - self.t0
340
+
341
+ def time_remaind(self):
342
+ return ((time.time() - self.begin_time) / max(self.process_nr-self.begin_step, 1)) * (
343
+ self.total_nr- self.process_nr)
344
+
345
+ def total_time(self):
346
+ return ((time.time() - self.begin_time) / max(self.process_nr-self.begin_step, 1))*self.total_nr
347
+
348
+ def __repr__(self):
349
+ if self._time_datas is not None and self.process_nr-self._time_datas[0]>self.avg_step:
350
+ self.begin_step = self._time_datas[0]
351
+ self.begin_time = self._time_datas[1]
352
+ self._time_datas = None
353
+
354
+ left_time = ((time.time() - self.begin_time) / max(self.process_nr-self.begin_step, 1)) * (
355
+ self.total_nr- self.process_nr)
356
+ finish_time = datetime.datetime.now() + datetime.timedelta(seconds=left_time)
357
+ cur_str = datetime.datetime.now().strftime("%d %H:%M")
358
+ ft_str = finish_time.strftime("%d %H:%M")
359
+ #res = f"used {(time.time() - self.begin_time) / 3600:.3f}h, {left_time / 3600:.3f}h left, exp finish {str(d)}"
360
+ #res = f"{(time.time() - self.begin_time) / 3600:.3f}h/{left_time / 3600:.3f}h/{str(d)}"
361
+ res = f"{(time.time() - self.t0) / 3600:.3f}h/{left_time / 3600:.3f}h/{cur_str}/{ft_str}"
362
+ return res
363
+
364
+ def time_this(func):
365
+ @wraps(func)
366
+ def wraps_func(*args,**kwargs):
367
+ begin_t = time.time()
368
+ res = func(*args,**kwargs)
369
+ print(f"Time cost {time.time()-begin_t}s.")
370
+ return res
371
+ return wraps_func
372
+
373
+ def no_throw(func):
374
+ @wraps(func)
375
+ def wraps_func(*args,**kwargs):
376
+ try:
377
+ return func(*args,**kwargs)
378
+ except Exception as e:
379
+ print(f"ERROR: in no_throw wraps {e}")
380
+ return None
381
+ return wraps_func
382
+ '''
383
+ 将list data分为多个组,每个组size个元素
384
+ '''
385
+ def list_to_2dlist(data,size):
386
+ data_nr = len(data)
387
+ if data_nr<size:
388
+ return [data]
389
+ res = []
390
+ index = 0
391
+ while index<data_nr:
392
+ end_index = min(index+size,data_nr)
393
+ res.append(data[index:end_index])
394
+ index = end_index
395
+ return res
396
+
397
+ '''
398
+ 将list data分nr个组,每个组的元素数量基本相等
399
+ '''
400
+ def list_to_2dlistv2(data,nr):
401
+ size = (len(data)+nr-1)//nr
402
+ return list_to_2dlist(data,size)
403
+
404
+ def random_uniform(minmaxs):
405
+ res = []
406
+ for min,max in minmaxs:
407
+ res.append(random.uniform(min,max))
408
+ return res
409
+
410
+ def random_uniform_indict(minmaxs):
411
+ res = {}
412
+ for key,data in minmaxs.items():
413
+ if len(data) == 2:
414
+ if isinstance(data[0],bool):
415
+ index = random.randint(0,1)
416
+ res[key] = data[index]
417
+ else:
418
+ min,max = data[0],data[1]
419
+ res[key] = random.uniform(min,max)
420
+ else:
421
+ index = random.randint(0,len(data)-1)
422
+ res[key] = data[index]
423
+
424
+ return res
425
+
426
+ def is_child_of(obj, cls):
427
+ try:
428
+ for i in obj.__bases__:
429
+ if i is cls or isinstance(i, cls):
430
+ return True
431
+ for i in obj.__bases__:
432
+ if is_child_of(i, cls):
433
+ return True
434
+ except AttributeError:
435
+ return is_child_of(obj.__class__, cls)
436
+ return False
437
+
438
+
439
+ def add_dict(lhv,rhv):
440
+ res = dict(lhv)
441
+ for k,v in rhv.items():
442
+ if k in res:
443
+ res[k] = res[k]+v
444
+ else:
445
+ res[k] = v
446
+ return res
447
+
448
+ def sleep_for(hours):
449
+ finish_time = datetime.datetime.now() + datetime.timedelta(seconds=int(hours*3600))
450
+ sleep_until(finish_time)
451
+
452
+ def sleep_until(runtime):
453
+ if isinstance(runtime,(str,bytes)):
454
+ target_datetime = datetime.datetime.strptime(runtime, "%Y-%m-%d %H:%M:%S")
455
+ else:
456
+ target_datetime = runtime
457
+
458
+ while True:
459
+ wait_time = (target_datetime - datetime.datetime.now()).total_seconds() / 3600.0
460
+ sys.stdout.write(
461
+ f"\rRumtime is {target_datetime}, current datetime is {datetime.datetime.now()}, need to wait for {wait_time:.2f}h", )
462
+ sys.stdout.flush()
463
+
464
+ if datetime.datetime.now() >= target_datetime:
465
+ break
466
+ else:
467
+ time.sleep(30)
468
+
469
+ def file_md5(path):
470
+ with open(path,'rb') as f:
471
+ data = f.read()
472
+ return hashlib.md5(data).hexdigest()
473
+
474
+ def nparray(data,default_shape=[0],dtype=np.float32):
475
+ res = np.array(data)
476
+ if res.size == 0:
477
+ return np.zeros(default_shape,dtype=dtype)
478
+ return res
479
+
480
+ def is_int(v,eps=1e-6):
481
+ return math.fabs(v-int(v))<eps
482
+
483
+ def to_fraction(v):
484
+ '''
485
+ 将小数转化为分数
486
+ example:
487
+ v=0.4:
488
+ return:
489
+ 2,5
490
+ '''
491
+ max_try = 20
492
+ if is_int(v):
493
+ return v
494
+ denominator = 1
495
+ for i in range(max_try):
496
+ v *= 10
497
+ denominator *= 10
498
+ if is_int(v):
499
+ break
500
+ if not is_int(v):
501
+ return v,denominator
502
+
503
+ v = int(v)
504
+ for _ in range(max_try):
505
+ is_find = False
506
+ for i in range(2,v+1):
507
+ if v%i == 0 and denominator%i==0:
508
+ v = v//i
509
+ denominator = denominator//i
510
+ is_find = True
511
+ break
512
+ if not is_find:
513
+ break
514
+ return v,denominator
515
+
516
+ def is_divide_exactly(lhv,rhv):
517
+ return (lhv//rhv)*rhv==lhv
518
+
519
+ def lowest_common_multiple(a,b):
520
+ '''
521
+ 最小公倍数
522
+ '''
523
+ if a==b:
524
+ return a
525
+
526
+ max_v = max(a,b)
527
+ min_v = min(a,b)
528
+
529
+ if is_divide_exactly(max_v,min_v):
530
+ return max_v
531
+
532
+ res = max_v*min_v
533
+
534
+ while True:
535
+ for i in range(1,min_v):
536
+ if is_divide_exactly(res,i):
537
+ tmp_v = res//i
538
+ if is_divide_exactly(tmp_v,max_v) and is_divide_exactly(tmp_v,min_v):
539
+ res = tmp_v
540
+ break
541
+ if i>=min_v-1:
542
+ break
543
+
544
+ return res
545
+
546
+ def dump2file(obj,file):
547
+ if isinstance(file,(str,bytes)):
548
+ with open(file,"wb") as f:
549
+ return pickle.dump(obj,f)
550
+ else:
551
+ return pickle.dump(obj,file)
552
+
553
+ def load_from_file(file):
554
+ if isinstance(file,(str,bytes)):
555
+ with open(file,"rb") as f:
556
+ return pickle.load(f)
557
+ else:
558
+ return pickle.load(file)
559
+
560
+ def parse_version(version="0.0.0") -> tuple:
561
+ """
562
+ Convert a version string to a tuple of integers, ignoring any extra non-numeric string attached to the version. This
563
+ function replaces deprecated 'pkg_resources.parse_version(v)'.
564
+
565
+ Args:
566
+ version (str): Version string, i.e. '2.0.1+cpu'
567
+
568
+ Returns:
569
+ (tuple): Tuple of integers representing the numeric part of the version and the extra string, i.e. (2, 0, 1)
570
+ """
571
+ try:
572
+ return tuple(map(int, re.findall(r"\d+", version)[:3])) # '2.0.1+cpu' -> (2, 0, 1)
573
+ except Exception as e:
574
+ print(f"WARNING ⚠️ failure for parse_version({version}), returning (0, 0, 0): {e}")
575
+ return 0, 0, 0
576
+
577
+ def check_version(
578
+ current: str = "0.0.0",
579
+ required: str = "0.0.0",
580
+ name: str = "version",
581
+ hard: bool = False,
582
+ verbose: bool = False,
583
+ msg: str = "",
584
+ ) -> bool:
585
+ """
586
+ Check current version against the required version or range.
587
+
588
+ Args:
589
+ current (str): Current version or package name to get version from.
590
+ required (str): Required version or range (in pip-style format).
591
+ name (str, optional): Name to be used in warning message.
592
+ hard (bool, optional): If True, raise an AssertionError if the requirement is not met.
593
+ verbose (bool, optional): If True, print warning message if requirement is not met.
594
+ msg (str, optional): Extra message to display if verbose.
595
+
596
+ Returns:
597
+ (bool): True if requirement is met, False otherwise.
598
+
599
+ Example:
600
+ ```python
601
+ # Check if current version is exactly 22.04
602
+ check_version(current="22.04", required="==22.04")
603
+
604
+ # Check if current version is greater than or equal to 22.04
605
+ check_version(current="22.10", required="22.04") # assumes '>=' inequality if none passed
606
+
607
+ # Check if current version is less than or equal to 22.04
608
+ check_version(current="22.04", required="<=22.04")
609
+
610
+ # Check if current version is between 20.04 (inclusive) and 22.04 (exclusive)
611
+ check_version(current="21.10", required=">20.04,<22.04")
612
+ ```
613
+ """
614
+ if not current: # if current is '' or None
615
+ print(f"WARNING ⚠️ invalid check_version({current}, {required}) requested, please check values.")
616
+ return True
617
+ elif not current[0].isdigit(): # current is package name rather than version string, i.e. current='ultralytics'
618
+ try:
619
+ name = current # assigned package name to 'name' arg
620
+ current = metadata.version(current) # get version string from package name
621
+ except metadata.PackageNotFoundError as e:
622
+ if hard:
623
+ raise ModuleNotFoundError(f"WARNING ⚠️ {current} package is required but not installed") from e
624
+ else:
625
+ return False
626
+
627
+ if not required: # if required is '' or None
628
+ return True
629
+
630
+ op = ""
631
+ version = ""
632
+ result = True
633
+ c = parse_version(current) # '1.2.3' -> (1, 2, 3)
634
+ for r in required.strip(",").split(","):
635
+ op, version = re.match(r"([^0-9]*)([\d.]+)", r).groups() # split '>=22.04' -> ('>=', '22.04')
636
+ if not op:
637
+ op = ">=" # assume >= if no op passed
638
+ v = parse_version(version) # '1.2.3' -> (1, 2, 3)
639
+ if op == "==" and c != v:
640
+ result = False
641
+ elif op == "!=" and c == v:
642
+ result = False
643
+ elif op == ">=" and not (c >= v):
644
+ result = False
645
+ elif op == "<=" and not (c <= v):
646
+ result = False
647
+ elif op == ">" and not (c > v):
648
+ result = False
649
+ elif op == "<" and not (c < v):
650
+ result = False
651
+ if not result:
652
+ warning = f"WARNING ⚠️ {name}{op}{version} is required, but {name}=={current} is currently installed {msg}"
653
+ if hard:
654
+ raise ModuleNotFoundError(warning) # assert version requirements met
655
+ if verbose:
656
+ print(warning)
657
+ return result
@@ -0,0 +1,4 @@
1
+ from .kps_structures import WMCKeypoints,WMCKeypointsItem
2
+ from .mask_structures import WBaseMask, WPolygonMaskItem, WPolygonMasks, WBitmapMasks
3
+ from .common import WBaseMaskLike
4
+ from .keypoints_train_toolkit import MultiClassesHeatmapGenerator
@@ -0,0 +1,9 @@
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+
4
+ class WBaseMaskLike(metaclass=ABCMeta):
5
+ HORIZONTAL = 'horizontal'
6
+ VERTICAL = 'vertical'
7
+ DIAGONAL = 'diagonal'
8
+ def __init__(self) -> None:
9
+ pass