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/img_patch.py ADDED
@@ -0,0 +1,92 @@
1
+ import numpy as np
2
+ from collections import Iterable
3
+ import math
4
+ import wml.img_utils as wmli
5
+
6
+ class ImagePatch:
7
+ def __init__(self,patch_size,pad=True,pad_value=127,boundary=0) -> None:
8
+ '''
9
+ patch_size: (H,W)
10
+ boundary: (bh,bw) or value
11
+ '''
12
+ self.patch_size = patch_size
13
+ self.pad = pad
14
+ self.pad_value = pad_value
15
+ self.boundary = boundary if isinstance(boundary,Iterable) else (boundary,boundary)
16
+ self.patch_bboxes = []
17
+ self.src_img = None
18
+ self.cur_idx = 0
19
+
20
+ def set_src_img(self,img):
21
+ self.src_img = img
22
+ self.cur_idx = 0
23
+ self.patch_bboxes = []
24
+ self.rows = math.ceil((self.src_img.shape[0]-self.boundary[0])/(self.patch_size[0]-self.boundary[0]))
25
+ self.cols = math.ceil((self.src_img.shape[1]-self.boundary[1])/(self.patch_size[1]-self.boundary[1]))
26
+
27
+ x = np.array(list(range(self.cols)),dtype=np.int32)*(self.patch_size[1]-self.boundary[1])
28
+ y = np.array(list(range(self.rows)),dtype=np.int32)*(self.patch_size[0]-self.boundary[0])
29
+ wh = np.array([self.patch_size[1],self.patch_size[0]],dtype=np.int32)
30
+ wh = np.reshape(wh,[-1,2])
31
+ xv,yv = np.meshgrid(x,y,sparse=False, indexing='ij')
32
+ x0y0 = np.stack([xv,yv],axis=-1)
33
+ x0y0 = np.reshape(x0y0,[-1,x0y0.shape[-1]])
34
+ x1y1 = x0y0+wh
35
+ self.bboxes = np.concatenate([x0y0,x1y1],axis=-1)
36
+
37
+ def __len__(self):
38
+ return len(self.bboxes)
39
+
40
+ def __getitem__(self,idx):
41
+ bbox = self.bboxes[idx]
42
+ self.cur_idx = idx
43
+
44
+ if self.pad:
45
+ size = self.patch_size[::-1]
46
+ return wmli.crop_and_pad(self.src_img,bbox,size,pad_color=self.pad_value)
47
+ else:
48
+ return wmli.crop_img(self.src_img,bbox)
49
+
50
+ def patch_bboxes2img_bboxes(self,bboxes,idx=None):
51
+ '''
52
+ bboxes: [N,4] (x0,y0,x1,y1)
53
+ '''
54
+ if idx is None:
55
+ idx = self.cur_idx
56
+ bbox = self.bboxes[idx]
57
+ offset = np.array([bbox[0],bbox[1],bbox[0],bbox[1]],dtype=bboxes.dtype)
58
+ offset = np.reshape(offset,[-1,4])
59
+ bboxes = bboxes+offset
60
+ return bboxes
61
+
62
+ def cur_bbox(self):
63
+ return self.bboxes[self.cur_idx]
64
+
65
+ def remove_boundary_bboxes(self,bboxes,boundary=None):
66
+ '''
67
+ bboxes: [N,4] (x0,y0,x1,y1), in patch img
68
+ '''
69
+ if boundary is None:
70
+ boundary = self.boundary
71
+ if not isinstance(boundary,Iterable):
72
+ boundary = (boundary,boundary)
73
+
74
+ value = (boundary[0]/2,boundary[1]/2)
75
+
76
+ cxy = (bboxes[...,:2]+bboxes[...,2:])/2
77
+
78
+ mask0 = cxy[...,0]<value[1]
79
+ mask1 = cxy[...,1]<value[0]
80
+ mask2 = cxy[...,0]>(self.patch_size[1]-value[1])
81
+ mask3 = cxy[...,1]>(self.patch_size[0]-value[0])
82
+ _mask0 = np.logical_or(mask0,mask1)
83
+ _mask2 = np.logical_or(mask2,mask3)
84
+ mask = np.logical_or(_mask0,_mask2)
85
+ keep = np.logical_not(mask)
86
+
87
+ return keep
88
+
89
+
90
+
91
+
92
+
wml/img_utils.py ADDED
@@ -0,0 +1,571 @@
1
+ #coding=utf-8
2
+ #import pydicom as dcm
3
+ import PIL.Image
4
+ from PIL import Image,ImageOps
5
+ import io
6
+ import scipy.misc
7
+ import matplotlib.image as mpimg
8
+ import numpy as np
9
+ import shutil
10
+ import os
11
+ import cv2
12
+ import copy
13
+ import random
14
+ import glob
15
+ import math
16
+ from collections import OrderedDict, Iterable
17
+ from wml.basic_data_def import DEFAULT_COLOR_MAP as _DEFAULT_COLOR_MAP
18
+ from wml.basic_data_def import colors_tableau
19
+ import wml.object_detection2.basic_visualization as bodv
20
+ import torchvision
21
+ from wml.basic_img_utils import *
22
+
23
+ try:
24
+ from turbojpeg import TJCS_RGB, TJPF_BGR, TJPF_GRAY, TurboJPEG
25
+ except ImportError:
26
+ TJCS_RGB = TJPF_GRAY = TJPF_BGR = TurboJPEG = None
27
+ g_jpeg = None
28
+
29
+ '''def dcm_to_jpeg(input_file,output_file):
30
+ ds = dcm.read_file(input_file)
31
+ pix = ds.pixel_array
32
+ scipy.misc.imsave(output_file, pix)
33
+ return pix.shape'''
34
+
35
+ '''def dcms_to_jpegs(input_dir,output_dir):
36
+ input_files = wmlu.recurse_get_filepath_in_dir(input_dir,suffix=".dcm")
37
+ if not os.path.exists(output_dir):
38
+ os.mkdir(output_dir)
39
+ for file in input_files:
40
+ print('trans file \"%s\"'%(os.path.basename(file)))
41
+ output_file = os.path.join(output_dir,wmlu.base_name(file)+".png")
42
+ dcm_to_jpeg(file,output_file)'''
43
+
44
+ def to_jpeg(input_file,output_file):
45
+ _input_file = input_file.lower()
46
+ if _input_file.endswith(".jpg") or _input_file.endswith(".jpeg"):
47
+ shutil.copyfile(input_file,output_file)
48
+ #return None
49
+ else:
50
+ pix = mpimg.imread(input_file)
51
+ scipy.misc.imsave(output_file, pix)
52
+ #return pix.shape
53
+
54
+ def npgray_to_rgb(img):
55
+ if img.ndim == 2:
56
+ img = np.expand_dims(img,axis=2)
57
+ shape = img.shape
58
+ if shape[2] == 1:
59
+ img = np.concatenate([img, img, img], axis=2)
60
+ return img
61
+
62
+ def adjust_image_value_range(img):
63
+ min = np.min(img)
64
+ max = np.max(img)
65
+ img = (img-min)*255.0/(max-min)
66
+ return img
67
+
68
+ def npgray_to_rgbv2(img):
69
+ img = adjust_image_value_range(img)
70
+ def r(v):
71
+ return np.where(v >= 127., 255., v * 255. / 127)
72
+ def g(v):
73
+ return (1. - np.abs(v - 127.) / 127.) * 255.
74
+ def b(v):
75
+ return np.where(v<=127.,255.,(1.-(v-127.)/127)*255.)
76
+ if img.ndim == 2:
77
+ img = np.expand_dims(img,axis=2)
78
+ shape = img.shape
79
+ if shape[2] == 1:
80
+ img = np.concatenate([r(img), g(img), b(img)], axis=2)
81
+ return img
82
+
83
+ def __nprgb_to_gray(img,keep_channels=False):
84
+ img_gray = img * np.reshape(np.array([0.299, 0.587, 0.114], dtype=np.float32),[1,1,3])
85
+ img_gray = np.sum(img_gray,axis=-1)
86
+ if keep_channels:
87
+ img_gray = np.stack([img_gray,img_gray,img_gray],axis=-1)
88
+ return img_gray
89
+
90
+ def nprgb_to_gray(img,keep_channels=False,keep_dim=False):
91
+ img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
92
+ if keep_channels:
93
+ img_gray = np.stack([img_gray,img_gray,img_gray],axis=-1)
94
+ elif keep_dim:
95
+ img_gray = np.expand_dims(img_gray,axis=-1)
96
+ return img_gray
97
+
98
+ def npbatch_rgb_to_gray(img,keep_channels=False):
99
+ if not isinstance(img,np.ndarray):
100
+ img = np.array(img)
101
+ img_gray = img * np.array([0.299, 0.587, 0.114], dtype=np.float32)
102
+ img_gray = np.sum(img_gray,axis=-1)
103
+ if keep_channels:
104
+ img_gray = np.stack([img_gray,img_gray,img_gray],axis=-1)
105
+ return img_gray
106
+
107
+ def merge_image(src,dst,alpha):
108
+ src = adjust_image_value_range(src)
109
+ dst = adjust_image_value_range(dst)
110
+ if len(dst.shape)<3:
111
+ dst = np.expand_dims(dst,axis=2)
112
+ if src.shape[2] != dst.shape[2]:
113
+ if src.shape[2] == 1:
114
+ src = npgray_to_rgb(src)
115
+ if dst.shape[2] == 1:
116
+ dst = npgray_to_rgb(dst)
117
+
118
+ return src*(1.0-alpha)+dst*alpha
119
+
120
+ def merge_hotgraph_image(src,dst,alpha):
121
+ if len(dst.shape)<3:
122
+ dst = np.expand_dims(dst,axis=2)
123
+ if src.shape[2] != dst.shape[2]:
124
+ if src.shape[2] == 1:
125
+ src = npgray_to_rgb(src)
126
+
127
+ src = adjust_image_value_range(src)/255.
128
+ dst = adjust_image_value_range(dst)/255.
129
+ mean = np.mean(dst)
130
+ rgb_dst = npgray_to_rgbv2(dst)/255.
131
+
132
+ return np.where(dst>mean,src*(1.0-(2.*dst-1.)*alpha)+rgb_dst*(2.*dst-1.)*alpha,src)
133
+
134
+ '''def resize_img(img,size):
135
+
136
+ image_shape = img.shape
137
+
138
+ if size[0]==image_shape[0] and size[1]==image_shape[1]:
139
+ return img
140
+
141
+ h_scale = (float(size[0])+0.45)/float(image_shape[0])
142
+ w_scale = (float(size[1])+0.45)/float(image_shape[1])
143
+ if len(img.shape)==2:
144
+ return scipy.ndimage.zoom(img, [h_scale, w_scale])
145
+ else:
146
+ return scipy.ndimage.zoom(img, [h_scale, w_scale,1])'''
147
+
148
+ def nprandom_crop(img,size):
149
+ size = list(copy.deepcopy(size))
150
+ x_begin = 0
151
+ y_begin = 0
152
+ if img.shape[0]>size[0]:
153
+ y_begin = random.randint(0,img.shape[0]-size[0])
154
+ else:
155
+ size[0] = img.shape[0]
156
+ if img.shape[1]>size[1]:
157
+ x_begin = random.randint(0,img.shape[1]-size[1])
158
+ else:
159
+ size[1] = img.shape[1]
160
+
161
+ rect = [y_begin,x_begin,y_begin+size[0],x_begin+size[1]]
162
+ return sub_image(img,rect)
163
+
164
+ def imread(filepath):
165
+ img = cv2.imread(filepath,cv2.IMREAD_COLOR)
166
+ cv2.cvtColor(img,cv2.COLOR_BGR2RGB,img)
167
+ return img
168
+
169
+ def hpimread(filepath):
170
+ #return gpu_imread(filepath)
171
+ if TurboJPEG is not None:
172
+ global g_jpeg
173
+ if g_jpeg is None:
174
+ g_jpeg = TurboJPEG()
175
+ if os.path.splitext(filepath)[1].lower() in [".jpg",".jpeg"]:
176
+ with open(filepath,"rb") as f:
177
+ return g_jpeg.decode(f.read(),TJCS_RGB)
178
+ return imread(filepath)
179
+
180
+ def gpu_imread(filepath):
181
+ if os.path.splitext(filepath)[1].lower() not in [".jpg",".jpeg"]:
182
+ return imread(filepath)
183
+
184
+ datas = torchvision.io.read_file(filepath)
185
+ imgs = torchvision.io.decode_jpeg(datas,device="cuda")
186
+ imgs = imgs.cpu().numpy()
187
+ return imgs
188
+
189
+
190
+ def imsave(filename,img):
191
+ imwrite(filename,img)
192
+
193
+ def imwrite(filename, img,size=None):
194
+ '''
195
+ size: (W,H)
196
+ '''
197
+ if img.dtype != np.uint8:
198
+ img = img.astype(np.uint8)
199
+ dir_path = os.path.dirname(filename)
200
+ if dir_path != "" and not os.path.exists(dir_path):
201
+ os.makedirs(dir_path,exist_ok=True)
202
+ img = np.ascontiguousarray(img)
203
+ if len(img.shape)==3 and img.shape[2]==3:
204
+ img = copy.deepcopy(img)
205
+ cv2.cvtColor(img, cv2.COLOR_RGB2BGR,img)
206
+ if size is not None:
207
+ img = resize_img(img,size=size,keep_aspect_ratio=True)
208
+ cv2.imwrite(filename, img)
209
+
210
+ def read_and_write_img(src_path,dst_path):
211
+ img = cv2.imread(src_path)
212
+ cv2.imwrite(dst_path,img)
213
+
214
+ def imwrite_mask(filename,mask,color_map=_DEFAULT_COLOR_MAP):
215
+ if os.path.splitext(filename)[1].lower() != ".png":
216
+ print("WARNING: mask file need to be png format.")
217
+ if not isinstance(mask,np.ndarray):
218
+ mask = np.ndarray(mask)
219
+ if len(mask.shape)==3:
220
+ if mask.shape[-1] != 1:
221
+ raise RuntimeError(f"ERROR mask shape {mask.shape}")
222
+ mask = np.squeeze(mask,axis=-1)
223
+ new_mask = Image.fromarray(mask.astype(np.uint8)).convert('P')
224
+ new_mask.putpalette(color_map)
225
+ new_mask.save(filename)
226
+
227
+ def imwrite_mask_on_img(filename,img,mask,color_map=_DEFAULT_COLOR_MAP,ignored_label=255):
228
+ r_img = bodv.draw_semantic_on_image(img,mask, color_map, ignored_label=ignored_label)
229
+ imwrite(filename,r_img)
230
+
231
+ def imread_mask(filename):
232
+ mask = Image.open(filename)
233
+ return np.array(mask)
234
+
235
+ def videowrite(filename,imgs,fps=30,fmt="RGB"):
236
+ if len(imgs)==0:
237
+ return
238
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
239
+ write_size = imgs[0].shape[:2][::-1]
240
+ video_writer = cv2.VideoWriter(filename, fourcc, fps,write_size)
241
+ if fmt == "BGR":
242
+ for img in imgs:
243
+ video_writer.write(img)
244
+ elif fmt=="RGB":
245
+ for img in imgs:
246
+ video_writer.write(img[...,::-1])
247
+ else:
248
+ print(f"ERROR fmt {fmt}.")
249
+ video_writer.release()
250
+
251
+ class VideoWriter:
252
+ def __init__(self,filename,fps=30,fmt='RGB'):
253
+ self.video_writer = None
254
+ self.fmt = fmt
255
+ self.fps = fps
256
+ self.filename = filename
257
+
258
+ def __del__(self):
259
+ self.release()
260
+
261
+ def init_writer(self,img):
262
+ if self.video_writer is not None:
263
+ return
264
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
265
+ write_size = img.shape[:2][::-1]
266
+ self.video_writer = cv2.VideoWriter(self.filename, fourcc, self.fps, write_size)
267
+
268
+ def write(self,img):
269
+ if self.video_writer is None:
270
+ self.init_writer(img)
271
+ fmt = self.fmt
272
+ if fmt == "BGR":
273
+ self.video_writer.write(img)
274
+ elif fmt=="RGB":
275
+ self.video_writer.write(img[...,::-1])
276
+ else:
277
+ print(f"ERROR fmt {fmt}.")
278
+
279
+ def release(self):
280
+ if self.video_writer is not None:
281
+ self.video_writer.release()
282
+ self.video_writer = None
283
+
284
+ class VideoReader:
285
+ def __init__(self,path,file_pattern="img_{:05d}.jpg",suffix=".jpg",preread_nr=0) -> None:
286
+ if os.path.isdir(path):
287
+ self.dir_path = path
288
+ self.reader = None
289
+ self.all_files = glob.glob(os.path.join(path,"*"+suffix))
290
+ self.frames_nr = len(self.all_files)
291
+ self.fps = 1
292
+ else:
293
+ self.reader = cv2.VideoCapture(path)
294
+ self.dir_path = None
295
+ self.frames_nr = int(self.reader.get(cv2.CAP_PROP_FRAME_COUNT))
296
+ self.fps = self.reader.get(cv2.CAP_PROP_FPS)
297
+ self.preread_nr = preread_nr
298
+ if self.preread_nr>1:
299
+ self.reader_buffer = OrderedDict()
300
+ else:
301
+ self.reader_buffer = None
302
+
303
+
304
+ self.idx = 1
305
+ self.file_pattern = file_pattern
306
+
307
+ def __iter__(self):
308
+ return self
309
+
310
+ def __getitem__(self,idx):
311
+ if self.dir_path is None:
312
+ if self.preread_nr>1:
313
+ if idx in self.reader_buffer:
314
+ return self.reader_buffer[idx]
315
+ elif idx<self.idx-1:
316
+ raise NotImplemented()
317
+ else:
318
+ for x in range(self.idx-1,idx+1):
319
+ if x in self.reader_buffer:
320
+ continue
321
+ ret,frame = self.reader.read()
322
+ if ret:
323
+ frame = frame[...,::-1]
324
+ self.reader_buffer[x] = frame
325
+ if idx in self.reader_buffer:
326
+ return self.reader_buffer[idx]
327
+
328
+ raise NotImplemented()
329
+ elif idx<self.frames_nr:
330
+ if self.file_pattern is None:
331
+ file_path = self.all_files[idx]
332
+ else:
333
+ file_path = os.path.join(self.dir_path,self.file_pattern.format(idx+1))
334
+ img = cv2.imread(file_path)
335
+ return img[...,::-1]
336
+ else:
337
+ raise RuntimeError()
338
+
339
+ def __len__(self):
340
+ if self.dir_path is not None:
341
+ return self.frames_nr
342
+ elif self.reader is not None:
343
+ return self.frames_nr
344
+ else:
345
+ raise RuntimeError()
346
+
347
+ def __next__(self):
348
+ if self.reader is not None:
349
+ if self.preread_nr>1:
350
+ if self.idx-1 in self.reader_buffer:
351
+ frame = self.reader_buffer[self.idx-1]
352
+ ret = True
353
+ else:
354
+ ret,frame = self.reader.read()
355
+ if not ret:
356
+ raise StopIteration()
357
+ frame = frame[...,::-1]
358
+ self.reader_buffer[self.idx-1] = frame
359
+ while len(self.reader_buffer)>self.preread_nr:
360
+ self.reader_buffer.popitem(last=False)
361
+ else:
362
+ retry_nr = 10
363
+ while retry_nr>0:
364
+ ret,frame = self.reader.read()
365
+ retry_nr -= 1
366
+ if ret:
367
+ break
368
+
369
+ if ret:
370
+ frame = frame[...,::-1]
371
+
372
+ self.idx += 1
373
+ if not ret:
374
+ raise StopIteration()
375
+ else:
376
+ return frame
377
+ else:
378
+ if self.idx>self.frames_nr:
379
+ raise StopIteration()
380
+ if self.file_pattern is not None:
381
+ file_path = os.path.join(self.dir_path,self.file_pattern.format(self.idx))
382
+ else:
383
+ file_path = self.all_files[self.idx-1]
384
+ img = cv2.imread(file_path)
385
+ self.idx += 1
386
+ return img[...,::-1]
387
+
388
+ def imshow(winname,img):
389
+ img = copy.deepcopy(img)
390
+ cv2.cvtColor(img,cv2.COLOR_RGB2BGR,img)
391
+ cv2.imshow(winname,img)
392
+
393
+ def np_resize_to_range(img,min_dimension,max_dimension=-1):
394
+ new_shape = list(img.shape[:2])
395
+ if img.shape[0]<img.shape[1]:
396
+ new_shape[0] = min_dimension
397
+ if max_dimension>0:
398
+ new_shape[1] = min(int(new_shape[0]*img.shape[1]/img.shape[0]),max_dimension)
399
+ else:
400
+ new_shape[1] = int(new_shape[0]*img.shape[1]/img.shape[0])
401
+ else:
402
+ new_shape[1] = min_dimension
403
+ if max_dimension>0:
404
+ new_shape[0] = min(int(new_shape[1]*img.shape[0]/img.shape[1]),max_dimension)
405
+ else:
406
+ new_shape[0] = int(new_shape[1]*img.shape[0]/img.shape[1])
407
+
408
+ return resize_img(img,new_shape)
409
+
410
+ def nppsnr(labels,predictions,max_v = 2):
411
+ loss1 = np.mean(np.square(np.array(labels-predictions).astype(np.float32)))
412
+ if loss1<1e-6:
413
+ return 100.0
414
+ return 10*np.log(max_v**2/loss1)/np.log(10)
415
+
416
+
417
+ class NPImagePatch(object):
418
+ def __init__(self,patch_size):
419
+ self.patch_size = patch_size
420
+ self.patchs = None
421
+ self.batch_size = None
422
+ self.height = None
423
+ self.width = None
424
+ self.channel = None
425
+ '''
426
+ 将图像[batch_size,height,width,channel]变换为[X,patch_size,patch_size,channel]
427
+ '''
428
+ def to_patch(self,images):
429
+ patch_size = self.patch_size
430
+ batch_size, height, width, channel = images.shape
431
+ self.batch_size, self.height, self.width, self.channel = batch_size, height, width, channel
432
+ net = np.reshape(images, [batch_size, height // patch_size, patch_size, width // patch_size, patch_size,
433
+ channel])
434
+ net = np.transpose(net, [0, 1, 3, 2, 4, 5])
435
+ self.patchs = np.reshape(net, [-1, patch_size, patch_size, channel])
436
+ return self.patchs
437
+
438
+ def from_patch(self,patchs=None):
439
+ assert self.patchs is not None,"Must call to_path first."
440
+ if patchs is not None:
441
+ self.patchs = patchs
442
+ batch_size, height, width, channel = self.batch_size, self.height, self.width, self.channel
443
+ patch_size = self.patch_size
444
+ net = np.reshape(self.patchs, [batch_size, height // patch_size, width // patch_size, patch_size, patch_size,
445
+ channel])
446
+ net = np.transpose(net, [0, 1, 3, 2, 4, 5])
447
+ net = np.reshape(net, [batch_size, height, width, channel])
448
+ return net
449
+
450
+ '''
451
+ bboxes:[N,4],[ymin,xmin,ymax,xmax], absolute coordinate
452
+ '''
453
+ def remove_boxes_of_img(img,bboxes,default_value=[127,127,127]):
454
+ if not isinstance(bboxes,np.ndarray):
455
+ bboxes = np.array(bboxes)
456
+ if bboxes.shape[0] == 0:
457
+ return img
458
+ ymin,xmin,ymax,xmax = np.transpose(bboxes)
459
+ ymin = np.maximum(ymin,0)
460
+ xmin = np.maximum(xmin,0)
461
+ ymax = np.minimum(ymax,img.shape[0])
462
+ xmax = np.minimum(xmax,img.shape[1])
463
+ bboxes = np.stack([ymin,xmin,ymax,xmax],axis=1)
464
+
465
+ for box in bboxes:
466
+ img[box[0]:box[2], box[1]:box[3]] = default_value
467
+ return img
468
+
469
+ def img_info(img):
470
+ if len(img.shape) == 3 and img.shape[-1]>1:
471
+ img = nprgb_to_gray(img)
472
+ return np.std(img)
473
+
474
+
475
+ '''
476
+ img: np.ndarray, [H,W,3], RGB order
477
+ return:
478
+ bytes of jpeg string
479
+ '''
480
+ def encode_img(img,quality=95):
481
+ if isinstance(img,str):
482
+ img = imread(img)
483
+ pil_image = PIL.Image.fromarray(img)
484
+ output_io = io.BytesIO()
485
+ pil_image.save(output_io, format='JPEG',quality=quality)
486
+ return output_io.getvalue()
487
+
488
+ def _jpegflag(flag='color', channel_order='bgr'):
489
+ channel_order = channel_order.lower()
490
+ if channel_order not in ['rgb', 'bgr']:
491
+ raise ValueError('channel order must be either "rgb" or "bgr"')
492
+
493
+ if flag == 'color':
494
+ if channel_order == 'bgr':
495
+ return TJPF_BGR
496
+ elif channel_order == 'rgb':
497
+ return TJCS_RGB
498
+ elif flag == 'grayscale':
499
+ return TJPF_GRAY
500
+ else:
501
+ raise ValueError('flag must be "color" or "grayscale"')
502
+
503
+ def decode_img(buffer,fmt='rgb'):
504
+ if TurboJPEG is not None:
505
+ global g_jpeg
506
+ if g_jpeg is None:
507
+ g_jpeg = TurboJPEG()
508
+ if fmt == 'rgb':
509
+ img = g_jpeg.decode(buffer,TJCS_RGB)
510
+ elif fmt=='gray':
511
+ img = g_jpeg.decode(buffer,TJPF_GRAY)
512
+ if img.shape[-1] == 1:
513
+ img = img[:, :, 0]
514
+ return img
515
+
516
+ buff = io.BytesIO(buffer)
517
+ img = PIL.Image.open(buff)
518
+
519
+ if fmt=='rgb':
520
+ img = pillow2array(img, 'color')
521
+ else:
522
+ img = pillow2array(img, 'grayscale')
523
+
524
+ return img
525
+
526
+ def pillow2array(img,flag='color'):
527
+ # Handle exif orientation tag
528
+ #if flag in ['color', 'grayscale']:
529
+ #img = ImageOps.exif_transpose(img)
530
+ # If the image mode is not 'RGB', convert it to 'RGB' first.
531
+ if flag in ['color', 'color_ignore_orientation']:
532
+ if img.mode != 'RGB':
533
+ if img.mode != 'LA':
534
+ # Most formats except 'LA' can be directly converted to RGB
535
+ img = img.convert('RGB')
536
+ else:
537
+ # When the mode is 'LA', the default conversion will fill in
538
+ # the canvas with black, which sometimes shadows black objects
539
+ # in the foreground.
540
+ #
541
+ # Therefore, a random color (124, 117, 104) is used for canvas
542
+ img_rgba = img.convert('RGBA')
543
+ img = Image.new('RGB', img_rgba.size, (124, 117, 104))
544
+ img.paste(img_rgba, mask=img_rgba.split()[3]) # 3 is alpha
545
+ array = np.array(img)
546
+ elif flag in ['grayscale', 'grayscale_ignore_orientation']:
547
+ img = img.convert('L')
548
+ array = np.array(img)
549
+ else:
550
+ raise ValueError(
551
+ 'flag must be "color", "grayscale", "unchanged", '
552
+ f'"color_ignore_orientation" or "grayscale_ignore_orientation"'
553
+ f' but got {flag}')
554
+ return array
555
+
556
+ def get_standard_color(idx):
557
+ idx = idx%len(colors_tableau)
558
+ return colors_tableau[idx]
559
+
560
+
561
+ def get_img_size(img_path):
562
+ '''
563
+ return: [H,W]
564
+ '''
565
+ if not os.path.exists(img_path):
566
+ print(f"ERROR: img file {img_path} not exists.")
567
+ return [0,0,3]
568
+ else:
569
+ with PIL.Image.open(img_path) as im:
570
+ return list(im.size)[::-1]
571
+ #return list(wmli.imread(img_path).shape)
@@ -0,0 +1,17 @@
1
+ from .labelme_toolkit import *
2
+ from .fast_labelme import *
3
+ from .pascal_voc_toolkit import *
4
+ from .coco_toolkit import *
5
+ from .object365v2_toolkit import *
6
+ from .baidu_mask_toolkit import *
7
+ from .labelmemckeypoints_dataset import LabelmeMCKeypointsDataset
8
+ from .common import get_auto_dataset_suffix,check_dataset_dir
9
+ from .image_folder import ImageFolder
10
+
11
+ def get_auto_dataset_type(data_dir):
12
+ for f in wmlu.find_files(data_dir,suffix=".json"):
13
+ return FastLabelMeData
14
+ for f in wmlu.find_files(data_dir,suffix=".xml"):
15
+ return PascalVOCData
16
+
17
+ return PascalVOCData