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.
- python_wml-3.0.0.dist-info/LICENSE +23 -0
- python_wml-3.0.0.dist-info/METADATA +51 -0
- python_wml-3.0.0.dist-info/RECORD +164 -0
- python_wml-3.0.0.dist-info/WHEEL +5 -0
- python_wml-3.0.0.dist-info/top_level.txt +1 -0
- wml/__init__.py +0 -0
- wml/basic_data_def/__init__.py +2 -0
- wml/basic_data_def/detection_data_def.py +279 -0
- wml/basic_data_def/io_data_def.py +2 -0
- wml/basic_img_utils.py +816 -0
- wml/img_patch.py +92 -0
- wml/img_utils.py +571 -0
- wml/iotoolkit/__init__.py +17 -0
- wml/iotoolkit/aic_keypoint.py +115 -0
- wml/iotoolkit/baidu_mask_toolkit.py +244 -0
- wml/iotoolkit/base_dataset.py +210 -0
- wml/iotoolkit/bboxes_statistics.py +515 -0
- wml/iotoolkit/build.py +0 -0
- wml/iotoolkit/cityscapes_toolkit.py +183 -0
- wml/iotoolkit/classification_data_statistics.py +25 -0
- wml/iotoolkit/coco_data_fwd.py +225 -0
- wml/iotoolkit/coco_keypoints.py +118 -0
- wml/iotoolkit/coco_keypoints_fmt2.py +103 -0
- wml/iotoolkit/coco_toolkit.py +397 -0
- wml/iotoolkit/coco_wholebody.py +269 -0
- wml/iotoolkit/common.py +108 -0
- wml/iotoolkit/crowd_pose.py +146 -0
- wml/iotoolkit/fast_labelme.py +110 -0
- wml/iotoolkit/image_folder.py +95 -0
- wml/iotoolkit/imgs_cache.py +58 -0
- wml/iotoolkit/imgs_reader_mt.py +73 -0
- wml/iotoolkit/labelme_base.py +102 -0
- wml/iotoolkit/labelme_json_to_img.py +49 -0
- wml/iotoolkit/labelme_toolkit.py +117 -0
- wml/iotoolkit/labelme_toolkit_fwd.py +733 -0
- wml/iotoolkit/labelmemckeypoints_dataset.py +169 -0
- wml/iotoolkit/lspet.py +48 -0
- wml/iotoolkit/mapillary_vistas_toolkit.py +269 -0
- wml/iotoolkit/mat_data.py +90 -0
- wml/iotoolkit/mckeypoints_statistics.py +28 -0
- wml/iotoolkit/mot_datasets.py +62 -0
- wml/iotoolkit/mpii.py +108 -0
- wml/iotoolkit/npmckeypoints_dataset.py +164 -0
- wml/iotoolkit/o365_to_coco.py +136 -0
- wml/iotoolkit/object365_toolkit.py +156 -0
- wml/iotoolkit/object365v2_toolkit.py +71 -0
- wml/iotoolkit/pascal_voc_data.py +51 -0
- wml/iotoolkit/pascal_voc_toolkit.py +194 -0
- wml/iotoolkit/pascal_voc_toolkit_fwd.py +473 -0
- wml/iotoolkit/penn_action.py +57 -0
- wml/iotoolkit/rawframe_dataset.py +129 -0
- wml/iotoolkit/rewrite_pascal_voc.py +28 -0
- wml/iotoolkit/semantic_data.py +49 -0
- wml/iotoolkit/split_file_by_type.py +29 -0
- wml/iotoolkit/sports_mot_datasets.py +78 -0
- wml/iotoolkit/vis_objectdetection_dataset.py +70 -0
- wml/iotoolkit/vis_torch_data.py +39 -0
- wml/iotoolkit/yolo_toolkit.py +38 -0
- wml/object_detection2/__init__.py +4 -0
- wml/object_detection2/basic_visualization.py +37 -0
- wml/object_detection2/bboxes.py +812 -0
- wml/object_detection2/data_process_toolkit.py +146 -0
- wml/object_detection2/keypoints.py +292 -0
- wml/object_detection2/mask.py +120 -0
- wml/object_detection2/metrics/__init__.py +3 -0
- wml/object_detection2/metrics/build.py +15 -0
- wml/object_detection2/metrics/classifier_toolkit.py +440 -0
- wml/object_detection2/metrics/common.py +71 -0
- wml/object_detection2/metrics/mckps_toolkit.py +338 -0
- wml/object_detection2/metrics/toolkit.py +1953 -0
- wml/object_detection2/npod_toolkit.py +361 -0
- wml/object_detection2/odtools.py +243 -0
- wml/object_detection2/standard_names.py +75 -0
- wml/object_detection2/visualization.py +956 -0
- wml/object_detection2/wmath.py +34 -0
- wml/semantic/__init__.py +0 -0
- wml/semantic/basic_toolkit.py +65 -0
- wml/semantic/mask_utils.py +156 -0
- wml/semantic/semantic_test.py +21 -0
- wml/semantic/structures.py +1 -0
- wml/semantic/toolkit.py +105 -0
- wml/semantic/visualization_utils.py +658 -0
- wml/threadtoolkit.py +50 -0
- wml/walgorithm.py +228 -0
- wml/wcollections.py +212 -0
- wml/wfilesystem.py +487 -0
- wml/wml_utils.py +657 -0
- wml/wstructures/__init__.py +4 -0
- wml/wstructures/common.py +9 -0
- wml/wstructures/keypoints_train_toolkit.py +149 -0
- wml/wstructures/kps_structures.py +579 -0
- wml/wstructures/mask_structures.py +1161 -0
- wml/wtorch/__init__.py +8 -0
- wml/wtorch/bboxes.py +104 -0
- wml/wtorch/classes_suppression.py +24 -0
- wml/wtorch/conv_module.py +181 -0
- wml/wtorch/conv_ws.py +144 -0
- wml/wtorch/data/__init__.py +16 -0
- wml/wtorch/data/_utils/__init__.py +45 -0
- wml/wtorch/data/_utils/collate.py +183 -0
- wml/wtorch/data/_utils/fetch.py +47 -0
- wml/wtorch/data/_utils/pin_memory.py +121 -0
- wml/wtorch/data/_utils/signal_handling.py +72 -0
- wml/wtorch/data/_utils/worker.py +227 -0
- wml/wtorch/data/base_data_loader_iter.py +93 -0
- wml/wtorch/data/dataloader.py +501 -0
- wml/wtorch/data/datapipes/__init__.py +1 -0
- wml/wtorch/data/datapipes/iter/__init__.py +12 -0
- wml/wtorch/data/datapipes/iter/batch.py +126 -0
- wml/wtorch/data/datapipes/iter/callable.py +92 -0
- wml/wtorch/data/datapipes/iter/listdirfiles.py +37 -0
- wml/wtorch/data/datapipes/iter/loadfilesfromdisk.py +30 -0
- wml/wtorch/data/datapipes/iter/readfilesfromtar.py +60 -0
- wml/wtorch/data/datapipes/iter/readfilesfromzip.py +63 -0
- wml/wtorch/data/datapipes/iter/sampler.py +94 -0
- wml/wtorch/data/datapipes/utils/__init__.py +0 -0
- wml/wtorch/data/datapipes/utils/common.py +65 -0
- wml/wtorch/data/dataset.py +354 -0
- wml/wtorch/data/datasets/__init__.py +4 -0
- wml/wtorch/data/datasets/common.py +53 -0
- wml/wtorch/data/datasets/listdirfilesdataset.py +36 -0
- wml/wtorch/data/datasets/loadfilesfromdiskdataset.py +30 -0
- wml/wtorch/data/distributed.py +135 -0
- wml/wtorch/data/multi_processing_data_loader_iter.py +866 -0
- wml/wtorch/data/sampler.py +267 -0
- wml/wtorch/data/single_process_data_loader_iter.py +24 -0
- wml/wtorch/data/test_data_loader.py +26 -0
- wml/wtorch/dataset_toolkit.py +67 -0
- wml/wtorch/depthwise_separable_conv_module.py +98 -0
- wml/wtorch/dist.py +591 -0
- wml/wtorch/dropblock/__init__.py +6 -0
- wml/wtorch/dropblock/dropblock.py +228 -0
- wml/wtorch/dropblock/dropout.py +40 -0
- wml/wtorch/dropblock/scheduler.py +48 -0
- wml/wtorch/ema.py +61 -0
- wml/wtorch/fc_module.py +73 -0
- wml/wtorch/functional.py +34 -0
- wml/wtorch/iter_dataset.py +26 -0
- wml/wtorch/loss.py +69 -0
- wml/wtorch/nets/__init__.py +0 -0
- wml/wtorch/nets/ckpt_toolkit.py +219 -0
- wml/wtorch/nets/fpn.py +276 -0
- wml/wtorch/nets/hrnet/__init__.py +0 -0
- wml/wtorch/nets/hrnet/config.py +2 -0
- wml/wtorch/nets/hrnet/hrnet.py +494 -0
- wml/wtorch/nets/misc.py +249 -0
- wml/wtorch/nets/resnet/__init__.py +0 -0
- wml/wtorch/nets/resnet/layers/__init__.py +17 -0
- wml/wtorch/nets/resnet/layers/aspp.py +144 -0
- wml/wtorch/nets/resnet/layers/batch_norm.py +231 -0
- wml/wtorch/nets/resnet/layers/blocks.py +111 -0
- wml/wtorch/nets/resnet/layers/wrappers.py +110 -0
- wml/wtorch/nets/resnet/r50_config.py +38 -0
- wml/wtorch/nets/resnet/resnet.py +691 -0
- wml/wtorch/nets/shape_spec.py +20 -0
- wml/wtorch/nets/simple_fpn.py +101 -0
- wml/wtorch/nms.py +109 -0
- wml/wtorch/nn.py +896 -0
- wml/wtorch/ocr_block.py +193 -0
- wml/wtorch/summary.py +331 -0
- wml/wtorch/train_toolkit.py +603 -0
- wml/wtorch/transformer_blocks.py +266 -0
- wml/wtorch/utils.py +719 -0
- 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
|