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,146 @@
1
+ import wml.img_utils as wmli
2
+ import wml.object_detection2.bboxes as odb
3
+ import cv2 as cv
4
+ import numpy as np
5
+ from wml.semantic.mask_utils import cut_mask
6
+
7
+ def motion_blur(image, degree=10, angle=20):
8
+ image = np.array(image)
9
+ # 这里生成任意角度的运动模糊kernel的矩阵, degree越大,模糊程度越高
10
+ M = cv.getRotationMatrix2D((degree / 2, degree / 2), angle, 1)
11
+ motion_blur_kernel = np.diag(np.ones(degree))
12
+ motion_blur_kernel = cv.warpAffine(motion_blur_kernel, M, (degree, degree))
13
+
14
+ motion_blur_kernel = motion_blur_kernel / degree
15
+ blurred = cv.filter2D(image, -1, motion_blur_kernel)
16
+ # convert to uint8
17
+ cv.normalize(blurred, blurred, 0, 255, cv.NORM_MINMAX)
18
+ blurred = np.array(blurred, dtype=np.uint8)
19
+ return blurred
20
+
21
+ '''
22
+ cnt is a contour in a image, cut the area of rect
23
+ cnt:[[x,y],[x,y],...]
24
+ rect:[ymin,xmin,ymax,xmax]
25
+ output:
26
+ the new contours in sub image
27
+ '''
28
+ def cut_contour(cnt,rect):
29
+ bbox = bbox_of_contour(cnt)
30
+ width = max(bbox[3],rect[3])
31
+ height = max(bbox[2],rect[2])
32
+ img = np.zeros(shape=(height,width),dtype=np.uint8)
33
+ segmentation = cv.drawContours(img,[cnt],-1,color=(1),thickness=cv.FILLED)
34
+ cuted_img = wmli.sub_image(segmentation,rect)
35
+ contours,hierarchy = cv.findContours(cuted_img,cv.CV_RETR_LIST,cv.CHAIN_APPROX_SIMPLE)
36
+ return contours
37
+
38
+ '''
39
+ find the contours in rect of segmentation
40
+ segmentation:[H,W] value is 1 or 0
41
+ rect:[ymin,xmin,ymax,xmax]
42
+ output:
43
+ the new contours in sub image and correspond bbox
44
+ '''
45
+ def cut_contourv2(segmentation,rect):
46
+ org_contours,org_hierarchy = cv.findContours(segmentation,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)
47
+ max_area = np.sum(segmentation)
48
+ cuted_img = wmli.sub_image(segmentation,rect)
49
+ contours,hierarchy = cv.findContours(cuted_img,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)
50
+ boxes = []
51
+ ratio = []
52
+ for cnt in contours:
53
+ boxes.append(bbox_of_contour(cnt))
54
+ ratio.append(cv.contourArea(cnt)/max_area)
55
+ return contours,boxes,ratio
56
+
57
+ def remove_class_in_image(bboxes,labels,labels_to_remove,image,default_value=127,scale=1.1):
58
+ bboxes = bboxes.astype(np.int32)
59
+ mask = np.ones_like(labels,dtype=np.bool)
60
+ for l in labels_to_remove:
61
+ tm = labels==l
62
+ mask = np.logical_and(tm,mask)
63
+ keep_mask = np.logical_not(mask)
64
+ keep_bboxes = bboxes[keep_mask]
65
+ remove_bboxes = bboxes[mask]
66
+ img_mask = np.ones(image.shape[:2],dtype=np.bool)
67
+
68
+ wmli.remove_boxes_of_img(img_mask,remove_bboxes,False)
69
+ if scale>1.0:
70
+ t_keep_bboxes = npscale_bboxes(keep_bboxes,scale).astype(np.int32)
71
+ else:
72
+ t_keep_bboxes = keep_bboxes
73
+ wmli.remove_boxes_of_img(img_mask,t_keep_bboxes,True)
74
+
75
+ img_mask = np.expand_dims(img_mask,axis=-1)
76
+ img_mask = np.tile(img_mask,[1,1,3])
77
+ remove_image = np.ones_like(image)*default_value
78
+ image = np.where(img_mask,image,remove_image)
79
+ return image,keep_bboxes,labels[keep_mask]
80
+
81
+ def remove_class(bboxes,labels,scores=None,labels_to_remove=[]):
82
+ bboxes = bboxes.astype(np.int32)
83
+ mask = np.ones_like(labels,dtype=np.bool)
84
+ for i,l in enumerate(labels):
85
+ if l in labels_to_remove:
86
+ mask[i] = False
87
+ bboxes = bboxes[mask]
88
+ labels = labels[mask]
89
+ if scores is not None:
90
+ scores = scores[mask]
91
+
92
+ return bboxes,labels,scores,mask
93
+
94
+
95
+ def cut_annotation(cut_bbox,img,labels,bboxes,masks=None,adjust_bbox=True,keep_ratio=0):
96
+ '''
97
+ cut_bbox: [y0,x0,y1,x1]
98
+ img: [H,W,3/1]
99
+ bboxes: [N,4] [y0,x0,y1,x1]
100
+ masks: [N,H,W]
101
+ '''
102
+ cut_bbox = list(cut_bbox)
103
+ if adjust_bbox:
104
+ b_w = cut_bbox[3]-cut_bbox[1]
105
+ b_h = cut_bbox[2]-cut_bbox[0]
106
+ cut_bbox[0] = min(img.shape[0],cut_bbox[2])-b_h
107
+ cut_bbox[1] = min(img.shape[1],cut_bbox[3])-b_w
108
+
109
+ cut_bbox[0] = max(0,cut_bbox[0])
110
+ cut_bbox[1] = max(0,cut_bbox[1])
111
+
112
+ cut_bbox[2] = min(cut_bbox[2],img.shape[0])
113
+ cut_bbox[3] = min(cut_bbox[3],img.shape[1])
114
+
115
+ new_bboxes = []
116
+ new_labels = []
117
+ new_img = wmli.sub_image(img,cut_bbox)
118
+ if masks is not None:
119
+ new_masks = []
120
+ for i in range(len(labels)):
121
+ n_mask,n_bbox,ratio = cut_mask(masks[i],cut_bbox)
122
+ if n_mask is not None and n_bbox is not None and ratio>keep_ratio:
123
+ new_bboxes.append(n_bbox)
124
+ new_labels.append(labels[i])
125
+ new_masks.append(n_mask)
126
+ if len(new_labels)>0:
127
+ new_labels = np.concatenate(new_labels,axis=0)
128
+ new_bboxes = np.concatenate(new_bboxes,axis=0)
129
+ new_masks = np.concatenate(new_masks,axis=0)
130
+ else:
131
+ new_labels = np.zeros([0],dtype=labels.dtype)
132
+ new_bboxes = np.zeros([0,4],dtype=bboxes.dtype)
133
+ new_masks = np.zeros([0,new_img.shape[0],new_img.shape[1]],dtype=masks.dtype)
134
+ else:
135
+ new_masks = None
136
+ bbox_area = odb.area(bboxes)
137
+ new_bboxes = odb.cut_boxes_by_box0(box0=cut_bbox,box1=bboxes)
138
+ new_bbox_area = odb.area(new_bboxes)
139
+ ratios = new_bbox_area/np.maximum(bbox_area,1)
140
+ keep = ratios>keep_ratio
141
+ new_labels = labels[keep]
142
+ new_bboxes = new_bboxes[keep]
143
+ offset = np.reshape(np.array([cut_bbox[0],cut_bbox[1],cut_bbox[0],cut_bbox[1]],dtype=new_bboxes.dtype),[1,4])
144
+ new_bboxes = new_bboxes-offset
145
+
146
+ return new_img,new_labels,new_bboxes,new_masks
@@ -0,0 +1,292 @@
1
+ import cv2
2
+ import numpy as np
3
+ import math
4
+
5
+ def npget_bbox(keypoints,threshold=0.02):
6
+ '''
7
+
8
+ Args:
9
+ keypoints: [N,3] or [N,2] ,[x,y,visible]
10
+ threshold:
11
+
12
+ Returns:
13
+ [xmin,ymin,xmax,ymax]
14
+
15
+ '''
16
+ assert len(keypoints.shape)==2,f"ERROR kps shape {keypoints.shape}"
17
+
18
+ if keypoints.shape[-1]>=3:
19
+ mask = keypoints[:,2]>threshold
20
+ if np.any(mask):
21
+ keypoints = keypoints[mask]
22
+ else:
23
+ return None
24
+ xmin = np.min(keypoints[:,0])
25
+ xmax = np.max(keypoints[:,0])
26
+ ymin = np.min(keypoints[:,1])
27
+ ymax = np.max(keypoints[:,1])
28
+ return np.array([xmin,ymin,xmax,ymax],dtype=np.float32)
29
+
30
+ def expand_bbox_by_kps(bbox,keypoints,threshold=0.02):
31
+ '''
32
+
33
+ Args:
34
+ bbox: [xmin,ymin,xmax,ymax]
35
+ keypoints: [[x,y,score],...]
36
+ threshold:
37
+
38
+ Returns:
39
+ [xmin,ymin,xmax,ymax]
40
+
41
+ '''
42
+ kp_bbox = npget_bbox(keypoints,threshold=threshold)
43
+ if kp_bbox is None:
44
+ return bbox
45
+ xmin,ymin,xmax,ymax = bbox
46
+ xmin = np.minimum(xmin,kp_bbox[0])
47
+ ymin = np.minimum(ymin,kp_bbox[1])
48
+ xmax = np.maximum(xmax,kp_bbox[2])
49
+ ymax = np.maximum(ymax,kp_bbox[3])
50
+
51
+ return np.array([xmin,ymin,xmax,ymax],dtype=np.float32)
52
+
53
+ def expand_yxyx_bbox_by_kps(bbox,keypoints,threshold=0.02):
54
+ '''
55
+
56
+ Args:
57
+ bbox: [ymin,xmin,ymax,xmax]
58
+ keypoints: [[x,y,score],...]
59
+ threshold:
60
+
61
+ Returns:
62
+ [ymin,xmin,ymax,xmax]
63
+
64
+ '''
65
+ kp_bbox = npget_bbox(keypoints, threshold=threshold)
66
+ if kp_bbox is None:
67
+ return bbox
68
+ ymin, xmin, ymax, xmax = bbox
69
+ xmin = np.minimum(xmin, kp_bbox[0])
70
+ ymin = np.minimum(ymin, kp_bbox[1])
71
+ xmax = np.maximum(xmax, kp_bbox[2])
72
+ ymax = np.maximum(ymax, kp_bbox[3])
73
+
74
+ return np.array([ymin, xmin, ymax, xmax], dtype=np.float32)
75
+
76
+
77
+ def npbatchget_bboxes(keypoints,threshold=0.02):
78
+ if not isinstance(keypoints,np.ndarray):
79
+ keypoints = np.array(keypoints)
80
+
81
+ if len(keypoints.shape)==2:
82
+ return npget_bbox(keypoints,threshold)
83
+
84
+ bboxes = []
85
+ for kps in keypoints:
86
+ bboxes.append(npget_bbox(kps,threshold))
87
+ return np.array(bboxes)
88
+
89
+ def keypoint_distance(kp0,kp1,use_score=True,score_threshold=0.1,max_dis=1e8):
90
+ '''
91
+
92
+ Args:
93
+ kp0: [NP_NR,2/3] (x,y) or (x,y,score)
94
+ kp1: [NP_NR,2/3] (x,y) or (x,y,score)
95
+ use_score:
96
+ score_threshold:
97
+ max_dis:
98
+
99
+ Returns:
100
+ '''
101
+ KP_NR = kp0.shape[0]
102
+ NR_THRESHOLD = KP_NR/4
103
+ def point_dis(p0,p1):
104
+ dx = p0[0]-p1[0]
105
+ dy = p0[1]-p1[1]
106
+ return math.sqrt(dx*dx+dy*dy)
107
+
108
+ if use_score:
109
+ count_nr = 0
110
+ sum_dis = 0.0
111
+ for i in range(KP_NR):
112
+ if kp0[i][2]>score_threshold and kp1[i][2]>score_threshold:
113
+ count_nr += 1
114
+ sum_dis += point_dis(kp0[i],kp1[i])
115
+ if count_nr<=NR_THRESHOLD:
116
+ return max_dis
117
+ else:
118
+ return sum_dis/count_nr
119
+ else:
120
+ sum_dis = 0.0
121
+ for i in range(KP_NR):
122
+ sum_dis += point_dis(kp0[i],kp1[i])
123
+
124
+ return sum_dis/KP_NR
125
+
126
+ def keypoint_distancev2(kp0,kp1,bbox0,bbox1,use_score=True,score_threshold=0.1,max_dis=1e8):
127
+ dis = keypoint_distance(kp0,kp1,use_score,score_threshold,max_dis)
128
+ bboxes = np.stack([bbox0,bbox1],axis=0)
129
+ hw = bboxes[...,2:]-bboxes[...,:2]
130
+ size = np.maximum(1e-8,hw[...,0]*hw[...,1])
131
+ size = np.sqrt(size)
132
+ size = np.mean(size)
133
+ return dis/size
134
+
135
+
136
+ def keypoints_distance(kps,use_score=True,score_threshold=0.1,max_dis=1e8):
137
+ '''
138
+
139
+ Args:
140
+ kps: [N,KP_NR,3/2] (x,y) or (x,y,score)
141
+ use_score:
142
+ score_threshold:
143
+
144
+ Returns:
145
+
146
+ '''
147
+
148
+ N = kps.shape[0]
149
+ res = np.zeros([N],dtype=np.float32)
150
+
151
+ for i in range(1,N):
152
+ res[i] = keypoint_distance(kps[i-1],kps[i],use_score,score_threshold,max_dis)
153
+
154
+ return res
155
+
156
+ def keypoints_distancev2(kps,bboxes,use_score=True,score_threshold=0.1,max_dis=1e8):
157
+ '''
158
+
159
+ Args:
160
+ kps: [N,KP_NR,2/3]
161
+ bboxes: [N,4] [ymin,xmin,ymax,xmax]
162
+ use_score:
163
+ score_threshold:
164
+ max_dis:
165
+
166
+ Returns:
167
+
168
+ '''
169
+ dis = keypoints_distance(kps,use_score,score_threshold,max_dis)
170
+
171
+ hw = bboxes[...,2:]-bboxes[...,:2]
172
+ size = np.maximum(1e-8,hw[...,0]*hw[...,1])
173
+ size = np.sqrt(size)
174
+ dis = dis/size
175
+ return dis
176
+
177
+ def affine_transform(pt, t):
178
+ new_pt = np.array([pt[0], pt[1], 1.]).T
179
+ new_pt = np.dot(t, new_pt)
180
+ return new_pt[:2]
181
+
182
+ def rotate(angle,img,kps,bbox,scale=1.0):
183
+ '''
184
+
185
+ Args:
186
+ angle: [-360,360]
187
+ img: [RGB]
188
+ kps: [N,2]/[N,3]
189
+ bbox: [xmin,ymin,xmax,ymax]
190
+
191
+ Returns:
192
+
193
+ '''
194
+ cx = (bbox[0]+bbox[2])/2
195
+ cy = (bbox[1] + bbox[3]) / 2
196
+ matrix = cv2.getRotationMatrix2D([cx,cy],angle,scale)
197
+ img = cv2.warpAffine(img,matrix,dsize=(img.shape[1],img.shape[0]),
198
+ flags=cv2.INTER_LINEAR)
199
+ num_joints = kps.shape[0]
200
+
201
+ def is_good_point(p):
202
+ return p[0]>=0 and p[1]>=0 and p[0]<img.shape[1] and p[1]<img.shape[0]
203
+
204
+ for i in range(num_joints):
205
+ if kps[i, 2] > 0.0:
206
+ kps[i, 0:2] = affine_transform(kps[i, 0:2], matrix)
207
+ if not is_good_point(kps[i]):
208
+ kps[i,:] = 0
209
+ points = [bbox[:2],[bbox[0],bbox[3]],bbox[2:],[bbox[2],bbox[1]]]
210
+ res_points = []
211
+ for p in points:
212
+ p = affine_transform(np.array(p),matrix)
213
+ res_points.append(p)
214
+ res_points = np.array(res_points)
215
+ x0y0 = np.maximum(np.min(res_points,axis=0),0)
216
+ x1y1 = np.minimum(np.max(res_points,axis=0),[img.shape[1]-1,img.shape[0]-1])
217
+ bbox = np.concatenate([x0y0,x1y1],axis=0)
218
+
219
+ return img,kps,bbox
220
+
221
+ def fliplr_joints(joints, width, matched_parts,joints_vis):
222
+ """
223
+ flip coords
224
+ """
225
+ # Flip horizontal
226
+ joints[:, 0] = width - joints[:, 0] - 1
227
+
228
+ # Change left-right parts
229
+ for pair in matched_parts:
230
+ joints[pair[0], :], joints[pair[1], :] = \
231
+ joints[pair[1], :], joints[pair[0], :].copy()
232
+ if joints_vis is not None:
233
+ joints_vis[pair[0], :], joints_vis[pair[1], :] = \
234
+ joints_vis[pair[1], :], joints_vis[pair[0], :].copy()
235
+
236
+ return joints,joints_vis
237
+
238
+ def flip(img,kps,joints_vis,matched_parts,bbox=None):
239
+ '''
240
+
241
+ Args:
242
+ img:
243
+ kps: [N,3] x,y,vis
244
+ joints_vis: [N,3]
245
+ matched_parts: [[id0_0,id0_1],...]
246
+ bboxes: [xmin,ymin,xmax,ymax]
247
+
248
+ Returns:
249
+
250
+ '''
251
+ img = img[:, ::-1, :]
252
+ joints, joints_vis = fliplr_joints(
253
+ kps,img.shape[1], matched_parts,joints_vis)
254
+ if bbox is not None:
255
+ xmax = img.shape[1] - bbox[0] - 1
256
+ bbox[0] = img.shape[1] - bbox[2] - 1
257
+ bbox[2] = xmax
258
+
259
+ return img,joints,joints_vis,bbox
260
+
261
+
262
+ def cut2size(kps,bbox,dst_size):
263
+ '''
264
+ bbox:[xmin,ymin,xmax,ymax]
265
+ dst_size:[W,H]
266
+ kps:[N,3]/[N,2]
267
+ '''
268
+ kps[...,:2] = kps[...,:2]-np.array([[bbox[0],bbox[1]]],dtype=np.float32)
269
+ bbox_w = bbox[2]-bbox[0]
270
+ bbox_h = bbox[3]-bbox[1]
271
+ if bbox_w<1e-8 or bbox_h<1e-8:
272
+ print(f"object_detection2.keypoints: ERROR bbox in cut2size.")
273
+ bbox_w = max(1.0,bbox_w)
274
+ bbox_h = max(1.0,bbox_h)
275
+ kps[...,:2] = kps[...,:2]*np.array([[dst_size[0]/bbox_w,dst_size[1]/bbox_h]],dtype=np.float32)
276
+ return kps
277
+
278
+
279
+ def mckps_distance_matrix(kps0,kps1):
280
+ '''
281
+ kps0: [N,2]
282
+ kps1: [M,2]
283
+ return:
284
+ [N,M]
285
+ '''
286
+ kps0 = np.expand_dims(kps0,axis=1)
287
+ kps1 = np.expand_dims(kps1,axis=0)
288
+ delta = kps0-kps1
289
+ pdelta = np.square(delta)
290
+ ssquare = np.sum(pdelta,axis=-1,keepdims=False)
291
+ dis = np.sqrt(ssquare)
292
+ return dis
@@ -0,0 +1,120 @@
1
+ #coding=utf-8
2
+ import numpy as np
3
+
4
+ '''
5
+ mask: [N,H,W] value is 0 or 1
6
+ labels: [N] labels of mask
7
+ return:
8
+ [H,W] value is labels' value
9
+ '''
10
+ def dense_mask_to_sparse_mask(mask:np.ndarray,labels,default_label=0):
11
+ if len(labels) == 0 and not isinstance(mask,np.ndarray):
12
+ return None
13
+ elif len(labels)==0:
14
+ _,H,W = mask.shape
15
+ return np.ones([H,W],dtype=np.int32)*default_label
16
+ else:
17
+ N,H,W = mask.shape
18
+ res_mask = np.ones([H,W],dtype=np.int32)*default_label
19
+ for i in range(N):
20
+ pos_mask = mask[i].astype(np.bool)
21
+ res_mask[pos_mask] = labels[i]
22
+ return res_mask
23
+
24
+ def dense_mask_to_sparse_maskv2(mask:np.ndarray,labels,labels_order,default_label=0):
25
+ '''
26
+ generate the mask by labels order
27
+ Args:
28
+ mask:
29
+ labels:
30
+ labels_order:
31
+ default_label:
32
+
33
+ Returns:
34
+
35
+ '''
36
+ labels = list(labels)
37
+ if len(labels) == 0 and not isinstance(mask,np.ndarray):
38
+ return None
39
+ elif len(labels)==0:
40
+ _,H,W = mask.shape
41
+ return np.ones([H,W],dtype=np.int32)*default_label
42
+ else:
43
+ N,H,W = mask.shape
44
+ res_mask = np.ones([H,W],dtype=np.int32)*default_label
45
+ for l in labels_order:
46
+ if l not in labels:
47
+ continue
48
+ for i in range(N):
49
+ if labels[i] != l:
50
+ continue
51
+ pos_mask = mask[i].astype(np.bool)
52
+ res_mask[pos_mask] = l
53
+ return res_mask
54
+
55
+
56
+ '''
57
+ mask: [N,H,W] value is 0 or 1
58
+ labels: [N] labels of mask
59
+ small object overwrite big object
60
+ '''
61
+ def dense_mask_to_sparse_maskv3(mask:np.ndarray,labels,default_label=0):
62
+ if len(labels) == 0 and not isinstance(mask,np.ndarray):
63
+ return None
64
+ elif len(labels)==0:
65
+ _,H,W = mask.shape
66
+ return np.ones([H,W],dtype=np.int32)*default_label
67
+ else:
68
+ N,H,W = mask.shape
69
+ nrs = np.sum(mask,axis=(1,2))
70
+ orders = np.argsort(-nrs)
71
+ res_mask = np.ones([H,W],dtype=np.int32)*default_label
72
+ for i in orders:
73
+ pos_mask = mask[i].astype(np.bool)
74
+ res_mask[pos_mask] = labels[i]
75
+ return res_mask
76
+
77
+ def get_bboxes_by_mask(masks):
78
+ '''
79
+ masks: [N,H,W]
80
+ return :
81
+ [N,4] (xmin,ymin,xmax,ymax)
82
+ '''
83
+ if len(masks) == 0:
84
+ return np.zeros([0,4],dtype=np.float32)
85
+
86
+ bboxes = []
87
+ for i in range(masks.shape[0]):
88
+ cur_mask = masks[i]
89
+ idx = np.nonzero(cur_mask)
90
+ xs = idx[1]
91
+ ys = idx[0]
92
+ if len(xs)==0:
93
+ bboxes.append(np.zeros([4],dtype=np.float32))
94
+ else:
95
+ x0 = np.min(xs)
96
+ y0 = np.min(ys)
97
+ x1 = np.max(xs)
98
+ y1 = np.max(ys)
99
+ bboxes.append(np.array([x0,y0,x1,y1],dtype=np.float32))
100
+
101
+ bboxes = np.array(bboxes)
102
+
103
+ return bboxes
104
+
105
+ def crop_masks_by_bboxes(masks,bboxes):
106
+ '''
107
+ masks: [N,H,W]
108
+ bboxes: [N,4] (x0,y0,x1,y1), absolute coordinate
109
+ '''
110
+ shape = masks.shape[1:]
111
+ bboxes[:,0:4:2] = np.clip(bboxes[:,0:4:2],0.0,shape[1])
112
+ bboxes[:,1:4:2] = np.clip(bboxes[:,1:4:2],0.0,shape[0])
113
+ bboxes = bboxes.astype(np.int32)
114
+ res = []
115
+ for i in range(bboxes.shape[0]):
116
+ x0,y0,x1,y1 = bboxes[i]
117
+ m = masks[i,y0:y1,x0:x1].copy()
118
+ res.append(m)
119
+
120
+ return res
@@ -0,0 +1,3 @@
1
+ from .toolkit import *
2
+ from .mckps_toolkit import *
3
+ from .classifier_toolkit import *
@@ -0,0 +1,15 @@
1
+ from wml.thirdparty.registry import Registry
2
+ import copy
3
+
4
+ METRICS_REGISTRY = Registry("Metrics")
5
+ CLASSIFIER_METRICS_REGISTRY = Registry("ClassifierMetrics")
6
+
7
+ def build_metrics(cfg):
8
+ cfg = copy.deepcopy(cfg)
9
+ type_str = cfg.pop("type")
10
+ return METRICS_REGISTRY.get(type_str)(**cfg)
11
+
12
+ def build_classifier_metrics(cfg):
13
+ cfg = copy.deepcopy(cfg)
14
+ type_str = cfg.pop("type")
15
+ return CLASSIFIER_METRICS_REGISTRY.get(type_str)(**cfg)