├── .gitignore ├── Data-enhancement ├── DataAugForObjectDetection │ ├── DataAugmentforLabelImg.py │ └── data │ │ ├── Annotations │ │ └── 0001.xml │ │ └── Images │ │ └── 0001.jpg ├── DataAugForObjectSegmentation │ ├── DataAugmentforLabelMe.py │ ├── __init__.py │ └── data │ │ ├── 0001.jpg │ │ └── 0001.json ├── Imgs │ ├── Camera_1.jpg │ ├── Camera_1_1.jpg │ ├── Camera_1_10.jpg │ ├── Camera_1_11.jpg │ ├── Camera_1_12.jpg │ ├── Camera_1_13.jpg │ ├── Camera_1_2.jpg │ ├── Camera_1_3.jpg │ ├── Camera_1_4.jpg │ ├── Camera_1_5.jpg │ ├── Camera_1_6.jpg │ ├── Camera_1_7.jpg │ ├── Camera_1_8.jpg │ └── Camera_1_9.jpg ├── README.md └── rename_file.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectDetection/DataAugmentforLabelImg.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 -*- 2 | ############################################################## 3 | # description: 4 | # data augmentation for obeject detection 5 | # author: 6 | # pureyang 2019-08-26 7 | # 参考:https://github.com/maozezhong/CV_ToolBox/blob/master/DataAugForObjectDetection 8 | 9 | ############################################################## 10 | 11 | # 包括: 12 | # 1. 裁剪(需改变bbox) 13 | # 2. 平移(需改变bbox) 14 | # 3. 改变亮度 15 | # 4. 加噪声 16 | # 5. 旋转角度(需要改变bbox) 17 | # 6. 镜像(需要改变bbox) 18 | # 7. cutout 19 | # 注意: 20 | # random.seed(),相同的seed,产生的随机数是一样的!! 21 | 22 | 23 | import time 24 | import random 25 | import copy 26 | import cv2 27 | import os 28 | import math 29 | import numpy as np 30 | from skimage.util import random_noise 31 | from lxml import etree, objectify 32 | import xml.etree.ElementTree as ET 33 | import argparse 34 | 35 | 36 | # 显示图片 37 | def show_pic(img, bboxes=None): 38 | ''' 39 | 输入: 40 | img:图像array 41 | bboxes:图像的所有boudning box list, 格式为[[x_min, y_min, x_max, y_max]....] 42 | names:每个box对应的名称 43 | ''' 44 | for i in range(len(bboxes)): 45 | bbox = bboxes[i] 46 | x_min = bbox[0] 47 | y_min = bbox[1] 48 | x_max = bbox[2] 49 | y_max = bbox[3] 50 | cv2.rectangle(img, (int(x_min), int(y_min)), (int(x_max), int(y_max)), (0, 255, 0), 3) 51 | cv2.namedWindow('pic', 0) # 1表示原图 52 | cv2.moveWindow('pic', 0, 0) 53 | cv2.resizeWindow('pic', 1200, 800) # 可视化的图片大小 54 | cv2.imshow('pic', img) 55 | cv2.waitKey(0) 56 | cv2.destroyAllWindows() 57 | 58 | 59 | # 图像均为cv2读取 60 | class DataAugmentForObjectDetection(): 61 | def __init__(self, rotation_rate=0.5, max_rotation_angle=5, 62 | crop_rate=0.5, shift_rate=0.5, change_light_rate=0.5, 63 | add_noise_rate=0.5, flip_rate=0.5, 64 | cutout_rate=0.5, cut_out_length=50, cut_out_holes=1, cut_out_threshold=0.5, 65 | is_addNoise=True, is_changeLight=True, is_cutout=True, is_rotate_img_bbox=True, 66 | is_crop_img_bboxes=True, is_shift_pic_bboxes=True, is_filp_pic_bboxes=True): 67 | 68 | # 配置各个操作的属性 69 | self.rotation_rate = rotation_rate 70 | self.max_rotation_angle = max_rotation_angle 71 | self.crop_rate = crop_rate 72 | self.shift_rate = shift_rate 73 | self.change_light_rate = change_light_rate 74 | self.add_noise_rate = add_noise_rate 75 | self.flip_rate = flip_rate 76 | self.cutout_rate = cutout_rate 77 | 78 | self.cut_out_length = cut_out_length 79 | self.cut_out_holes = cut_out_holes 80 | self.cut_out_threshold = cut_out_threshold 81 | 82 | # 是否使用某种增强方式 83 | self.is_addNoise = is_addNoise 84 | self.is_changeLight = is_changeLight 85 | self.is_cutout = is_cutout 86 | self.is_rotate_img_bbox = is_rotate_img_bbox 87 | self.is_crop_img_bboxes = is_crop_img_bboxes 88 | self.is_shift_pic_bboxes = is_shift_pic_bboxes 89 | self.is_filp_pic_bboxes = is_filp_pic_bboxes 90 | 91 | # 加噪声 92 | def _addNoise(self, img): 93 | ''' 94 | 输入: 95 | img:图像array 96 | 输出: 97 | 加噪声后的图像array,由于输出的像素是在[0,1]之间,所以得乘以255 98 | ''' 99 | # return cv2.GaussianBlur(img, (11, 11), 0) 100 | return random_noise(img, mode='gaussian', seed=int(time.time()), clip=True) * 255 101 | 102 | # 调整亮度 103 | def _changeLight(self, img): 104 | alpha = random.uniform(0.35, 1) 105 | blank = np.zeros(img.shape, img.dtype) 106 | return cv2.addWeighted(img, alpha, blank, 1 - alpha, 0) 107 | 108 | # cutout 109 | def _cutout(self, img, bboxes, length=100, n_holes=1, threshold=0.5): 110 | ''' 111 | 原版本:https://github.com/uoguelph-mlrg/Cutout/blob/master/util/cutout.py 112 | Randomly mask out one or more patches from an image. 113 | Args: 114 | img : a 3D numpy array,(h,w,c) 115 | bboxes : 框的坐标 116 | n_holes (int): Number of patches to cut out of each image. 117 | length (int): The length (in pixels) of each square patch. 118 | ''' 119 | 120 | def cal_iou(boxA, boxB): 121 | ''' 122 | boxA, boxB为两个框,返回iou 123 | boxB为bouding box 124 | ''' 125 | # determine the (x, y)-coordinates of the intersection rectangle 126 | xA = max(boxA[0], boxB[0]) 127 | yA = max(boxA[1], boxB[1]) 128 | xB = min(boxA[2], boxB[2]) 129 | yB = min(boxA[3], boxB[3]) 130 | 131 | if xB <= xA or yB <= yA: 132 | return 0.0 133 | 134 | # compute the area of intersection rectangle 135 | interArea = (xB - xA + 1) * (yB - yA + 1) 136 | 137 | # compute the area of both the prediction and ground-truth 138 | # rectangles 139 | boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1) 140 | boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1) 141 | iou = interArea / float(boxBArea) 142 | return iou 143 | 144 | # 得到h和w 145 | if img.ndim == 3: 146 | h, w, c = img.shape 147 | else: 148 | _, h, w, c = img.shape 149 | mask = np.ones((h, w, c), np.float32) 150 | for n in range(n_holes): 151 | chongdie = True # 看切割的区域是否与box重叠太多 152 | while chongdie: 153 | y = np.random.randint(h) 154 | x = np.random.randint(w) 155 | 156 | y1 = np.clip(y - length // 2, 0, 157 | h) # numpy.clip(a, a_min, a_max, out=None), clip这个函数将将数组中的元素限制在a_min, a_max之间,大于a_max的就使得它等于 a_max,小于a_min,的就使得它等于a_min 158 | y2 = np.clip(y + length // 2, 0, h) 159 | x1 = np.clip(x - length // 2, 0, w) 160 | x2 = np.clip(x + length // 2, 0, w) 161 | 162 | chongdie = False 163 | for box in bboxes: 164 | if cal_iou([x1, y1, x2, y2], box) > threshold: 165 | chongdie = True 166 | break 167 | mask[y1: y2, x1: x2, :] = 0. 168 | img = img * mask 169 | return img 170 | 171 | # 旋转 172 | def _rotate_img_bbox(self, img, bboxes, angle=5, scale=1.): 173 | ''' 174 | 参考:https://blog.csdn.net/u014540717/article/details/53301195crop_rate 175 | 输入: 176 | img:图像array,(h,w,c) 177 | bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值 178 | angle:旋转角度 179 | scale:默认1 180 | 输出: 181 | rot_img:旋转后的图像array 182 | rot_bboxes:旋转后的boundingbox坐标list 183 | ''' 184 | # ---------------------- 旋转图像 ---------------------- 185 | w = img.shape[1] 186 | h = img.shape[0] 187 | # 角度变弧度 188 | rangle = np.deg2rad(angle) # angle in radians 189 | # now calculate new image width and height 190 | nw = (abs(np.sin(rangle) * h) + abs(np.cos(rangle) * w)) * scale 191 | nh = (abs(np.cos(rangle) * h) + abs(np.sin(rangle) * w)) * scale 192 | # ask OpenCV for the rotation matrix 193 | rot_mat = cv2.getRotationMatrix2D((nw * 0.5, nh * 0.5), angle, scale) 194 | # calculate the move from the old center to the new center combined 195 | # with the rotation 196 | rot_move = np.dot(rot_mat, np.array([(nw - w) * 0.5, (nh - h) * 0.5, 0])) 197 | # the move only affects the translation, so update the translation 198 | rot_mat[0, 2] += rot_move[0] 199 | rot_mat[1, 2] += rot_move[1] 200 | # 仿射变换 201 | rot_img = cv2.warpAffine(img, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4) 202 | 203 | # ---------------------- 矫正bbox坐标 ---------------------- 204 | # rot_mat是最终的旋转矩阵 205 | # 获取原始bbox的四个中点,然后将这四个点转换到旋转后的坐标系下 206 | rot_bboxes = list() 207 | for bbox in bboxes: 208 | xmin = bbox[0] 209 | ymin = bbox[1] 210 | xmax = bbox[2] 211 | ymax = bbox[3] 212 | point1 = np.dot(rot_mat, np.array([(xmin + xmax) / 2, ymin, 1])) 213 | point2 = np.dot(rot_mat, np.array([xmax, (ymin + ymax) / 2, 1])) 214 | point3 = np.dot(rot_mat, np.array([(xmin + xmax) / 2, ymax, 1])) 215 | point4 = np.dot(rot_mat, np.array([xmin, (ymin + ymax) / 2, 1])) 216 | # 合并np.array 217 | concat = np.vstack((point1, point2, point3, point4)) 218 | # 改变array类型 219 | concat = concat.astype(np.int32) 220 | # 得到旋转后的坐标 221 | rx, ry, rw, rh = cv2.boundingRect(concat) 222 | rx_min = rx 223 | ry_min = ry 224 | rx_max = rx + rw 225 | ry_max = ry + rh 226 | # 加入list中 227 | rot_bboxes.append([rx_min, ry_min, rx_max, ry_max]) 228 | 229 | return rot_img, rot_bboxes 230 | 231 | # 裁剪 232 | def _crop_img_bboxes(self, img, bboxes): 233 | ''' 234 | 裁剪后的图片要包含所有的框 235 | 输入: 236 | img:图像array 237 | bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值 238 | 输出: 239 | crop_img:裁剪后的图像array 240 | crop_bboxes:裁剪后的bounding box的坐标list 241 | ''' 242 | # ---------------------- 裁剪图像 ---------------------- 243 | w = img.shape[1] 244 | h = img.shape[0] 245 | x_min = w # 裁剪后的包含所有目标框的最小的框 246 | x_max = 0 247 | y_min = h 248 | y_max = 0 249 | for bbox in bboxes: 250 | x_min = min(x_min, bbox[0]) 251 | y_min = min(y_min, bbox[1]) 252 | x_max = max(x_max, bbox[2]) 253 | y_max = max(y_max, bbox[3]) 254 | 255 | d_to_left = x_min # 包含所有目标框的最小框到左边的距离 256 | d_to_right = w - x_max # 包含所有目标框的最小框到右边的距离 257 | d_to_top = y_min # 包含所有目标框的最小框到顶端的距离 258 | d_to_bottom = h - y_max # 包含所有目标框的最小框到底部的距离 259 | 260 | # 随机扩展这个最小框 261 | crop_x_min = int(x_min - random.uniform(0, d_to_left)) 262 | crop_y_min = int(y_min - random.uniform(0, d_to_top)) 263 | crop_x_max = int(x_max + random.uniform(0, d_to_right)) 264 | crop_y_max = int(y_max + random.uniform(0, d_to_bottom)) 265 | 266 | # 随机扩展这个最小框 , 防止别裁的太小 267 | # crop_x_min = int(x_min - random.uniform(d_to_left//2, d_to_left)) 268 | # crop_y_min = int(y_min - random.uniform(d_to_top//2, d_to_top)) 269 | # crop_x_max = int(x_max + random.uniform(d_to_right//2, d_to_right)) 270 | # crop_y_max = int(y_max + random.uniform(d_to_bottom//2, d_to_bottom)) 271 | 272 | # 确保不要越界 273 | crop_x_min = max(0, crop_x_min) 274 | crop_y_min = max(0, crop_y_min) 275 | crop_x_max = min(w, crop_x_max) 276 | crop_y_max = min(h, crop_y_max) 277 | 278 | crop_img = img[crop_y_min:crop_y_max, crop_x_min:crop_x_max] 279 | 280 | # ---------------------- 裁剪boundingbox ---------------------- 281 | # 裁剪后的boundingbox坐标计算 282 | crop_bboxes = list() 283 | for bbox in bboxes: 284 | crop_bboxes.append([bbox[0] - crop_x_min, bbox[1] - crop_y_min, bbox[2] - crop_x_min, bbox[3] - crop_y_min]) 285 | 286 | return crop_img, crop_bboxes 287 | 288 | # 平移 289 | def _shift_pic_bboxes(self, img, bboxes): 290 | ''' 291 | 参考:https://blog.csdn.net/sty945/article/details/79387054 292 | 平移后的图片要包含所有的框 293 | 输入: 294 | img:图像array 295 | bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值 296 | 输出: 297 | shift_img:平移后的图像array 298 | shift_bboxes:平移后的bounding box的坐标list 299 | ''' 300 | # ---------------------- 平移图像 ---------------------- 301 | w = img.shape[1] 302 | h = img.shape[0] 303 | x_min = w # 裁剪后的包含所有目标框的最小的框 304 | x_max = 0 305 | y_min = h 306 | y_max = 0 307 | for bbox in bboxes: 308 | x_min = min(x_min, bbox[0]) 309 | y_min = min(y_min, bbox[1]) 310 | x_max = max(x_max, bbox[2]) 311 | y_max = max(y_max, bbox[3]) 312 | 313 | d_to_left = x_min # 包含所有目标框的最大左移动距离 314 | d_to_right = w - x_max # 包含所有目标框的最大右移动距离 315 | d_to_top = y_min # 包含所有目标框的最大上移动距离 316 | d_to_bottom = h - y_max # 包含所有目标框的最大下移动距离 317 | 318 | x = random.uniform(-(d_to_left - 1) / 3, (d_to_right - 1) / 3) 319 | y = random.uniform(-(d_to_top - 1) / 3, (d_to_bottom - 1) / 3) 320 | 321 | M = np.float32([[1, 0, x], [0, 1, y]]) # x为向左或右移动的像素值,正为向右负为向左; y为向上或者向下移动的像素值,正为向下负为向上 322 | shift_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0])) 323 | 324 | # ---------------------- 平移boundingbox ---------------------- 325 | shift_bboxes = list() 326 | for bbox in bboxes: 327 | shift_bboxes.append([bbox[0] + x, bbox[1] + y, bbox[2] + x, bbox[3] + y]) 328 | 329 | return shift_img, shift_bboxes 330 | 331 | # 镜像 332 | def _filp_pic_bboxes(self, img, bboxes): 333 | ''' 334 | 参考:https://blog.csdn.net/jningwei/article/details/78753607 335 | 平移后的图片要包含所有的框 336 | 输入: 337 | img:图像array 338 | bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值 339 | 输出: 340 | flip_img:平移后的图像array 341 | flip_bboxes:平移后的bounding box的坐标list 342 | ''' 343 | # ---------------------- 翻转图像 ---------------------- 344 | 345 | flip_img = copy.deepcopy(img) 346 | h, w, _ = img.shape 347 | 348 | sed = random.random() 349 | 350 | if 0 < sed < 0.33: # 0.33的概率水平翻转,0.33的概率垂直翻转,0.33是对角反转 351 | flip_img = cv2.flip(flip_img, 0) # _flip_x 352 | inver = 0 353 | elif 0.33 < sed < 0.66: 354 | flip_img = cv2.flip(flip_img, 1) # _flip_y 355 | inver = 1 356 | else: 357 | flip_img = cv2.flip(flip_img, -1) # flip_x_y 358 | inver = -1 359 | 360 | # ---------------------- 调整boundingbox ---------------------- 361 | flip_bboxes = list() 362 | for box in bboxes: 363 | x_min = box[0] 364 | y_min = box[1] 365 | x_max = box[2] 366 | y_max = box[3] 367 | 368 | if inver == 0: 369 | #0:垂直翻转 370 | flip_bboxes.append([x_min, h - y_max, x_max, h - y_min]) 371 | elif inver == 1: 372 | # 1:水平翻转 373 | flip_bboxes.append([w - x_max, y_min, w - x_min, y_max]) 374 | elif inver == -1: 375 | # -1:水平垂直翻转 376 | flip_bboxes.append([w - x_max, h - y_max, w - x_min, h - y_min]) 377 | return flip_img, flip_bboxes 378 | 379 | # 图像增强方法 380 | def dataAugment(self, img, bboxes): 381 | ''' 382 | 图像增强 383 | 输入: 384 | img:图像array 385 | bboxes:该图像的所有框坐标 386 | 输出: 387 | img:增强后的图像 388 | bboxes:增强后图片对应的box 389 | ''' 390 | change_num = 0 # 改变的次数 391 | # print('------') 392 | while change_num < 1: # 默认至少有一种数据增强生效 393 | 394 | if self.is_rotate_img_bbox: 395 | if random.random() > self.rotation_rate: # 旋转 396 | change_num += 1 397 | angle = random.uniform(-self.max_rotation_angle, self.max_rotation_angle) 398 | scale = random.uniform(0.7, 0.8) 399 | img, bboxes = self._rotate_img_bbox(img, bboxes, angle, scale) 400 | 401 | if self.is_shift_pic_bboxes: 402 | if random.random() < self.shift_rate: # 平移 403 | change_num += 1 404 | img, bboxes = self._shift_pic_bboxes(img, bboxes) 405 | 406 | if self.is_changeLight: 407 | if random.random() > self.change_light_rate: # 改变亮度 408 | change_num += 1 409 | img = self._changeLight(img) 410 | 411 | if self.is_addNoise: 412 | if random.random() < self.add_noise_rate: # 加噪声 413 | change_num += 1 414 | img = self._addNoise(img) 415 | if self.is_cutout: 416 | if random.random() < self.cutout_rate: # cutout 417 | change_num += 1 418 | img = self._cutout(img, bboxes, length=self.cut_out_length, n_holes=self.cut_out_holes, 419 | threshold=self.cut_out_threshold) 420 | if self.is_filp_pic_bboxes: 421 | if random.random() < self.flip_rate: # 翻转 422 | change_num += 1 423 | img, bboxes = self._filp_pic_bboxes(img, bboxes) 424 | 425 | return img, bboxes 426 | 427 | 428 | # xml解析工具 429 | class ToolHelper(): 430 | # 从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]] 431 | def parse_xml(self, path): 432 | ''' 433 | 输入: 434 | xml_path: xml的文件路径 435 | 输出: 436 | 从xml文件中提取bounding box信息, 格式为[[x_min, y_min, x_max, y_max, name]] 437 | ''' 438 | tree = ET.parse(path) 439 | root = tree.getroot() 440 | objs = root.findall('object') 441 | coords = list() 442 | for ix, obj in enumerate(objs): 443 | name = obj.find('name').text 444 | box = obj.find('bndbox') 445 | x_min = int(box[0].text) 446 | y_min = int(box[1].text) 447 | x_max = int(box[2].text) 448 | y_max = int(box[3].text) 449 | coords.append([x_min, y_min, x_max, y_max, name]) 450 | return coords 451 | 452 | # 保存图片结果 453 | def save_img(self, file_name, save_folder, img): 454 | cv2.imwrite(os.path.join(save_folder, file_name), img) 455 | 456 | # 保持xml结果 457 | def save_xml(self, file_name, save_folder, img_info, height, width, channel, bboxs_info): 458 | ''' 459 | :param file_name:文件名 460 | :param save_folder:#保存的xml文件的结果 461 | :param height:图片的信息 462 | :param width:图片的宽度 463 | :param channel:通道 464 | :return: 465 | ''' 466 | folder_name, img_name = img_info # 得到图片的信息 467 | 468 | E = objectify.ElementMaker(annotate=False) 469 | 470 | anno_tree = E.annotation( 471 | E.folder(folder_name), 472 | E.filename(img_name), 473 | E.path(os.path.join(folder_name, img_name)), 474 | E.source( 475 | E.database('Unknown'), 476 | ), 477 | E.size( 478 | E.width(width), 479 | E.height(height), 480 | E.depth(channel) 481 | ), 482 | E.segmented(0), 483 | ) 484 | 485 | labels, bboxs = bboxs_info # 得到边框和标签信息 486 | for label, box in zip(labels, bboxs): 487 | anno_tree.append( 488 | E.object( 489 | E.name(label), 490 | E.pose('Unspecified'), 491 | E.truncated('0'), 492 | E.difficult('0'), 493 | E.bndbox( 494 | E.xmin(box[0]), 495 | E.ymin(box[1]), 496 | E.xmax(box[2]), 497 | E.ymax(box[3]) 498 | ) 499 | )) 500 | 501 | etree.ElementTree(anno_tree).write(os.path.join(save_folder, file_name), pretty_print=True) 502 | 503 | 504 | if __name__ == '__main__': 505 | 506 | need_aug_num = 10 # 每张图片需要增强的次数 507 | 508 | is_endwidth_dot = True # 文件是否以.jpg或者png结尾 509 | 510 | dataAug = DataAugmentForObjectDetection() # 数据增强工具类 511 | 512 | toolhelper = ToolHelper() # 工具 513 | 514 | # 获取相关参数 515 | parser = argparse.ArgumentParser() 516 | parser.add_argument('--source_img_path', type=str, default='data/Images') 517 | parser.add_argument('--source_xml_path', type=str, default='data/Annotations') 518 | parser.add_argument('--save_img_path', type=str, default='data/Images2') 519 | parser.add_argument('--save_xml_path', type=str, default='data/Annotations2') 520 | args = parser.parse_args() 521 | source_img_path = args.source_img_path # 图片原始位置 522 | source_xml_path = args.source_xml_path # xml的原始位置 523 | 524 | save_img_path = args.save_img_path # 图片增强结果保存文件 525 | save_xml_path = args.save_xml_path # xml增强结果保存文件 526 | 527 | # 如果保存文件夹不存在就创建 528 | if not os.path.exists(save_img_path): 529 | os.mkdir(save_img_path) 530 | 531 | if not os.path.exists(save_xml_path): 532 | os.mkdir(save_xml_path) 533 | 534 | for parent, _, files in os.walk(source_img_path): 535 | files.sort() 536 | for file in files: 537 | cnt = 0 538 | pic_path = os.path.join(parent, file) 539 | xml_path = os.path.join(source_xml_path, file[:-4] + '.xml') 540 | values = toolhelper.parse_xml(xml_path) # 解析得到box信息,格式为[[x_min,y_min,x_max,y_max,name]] 541 | coords = [v[:4] for v in values] # 得到框 542 | labels = [v[-1] for v in values] # 对象的标签 543 | 544 | # 如果图片是有后缀的 545 | if is_endwidth_dot: 546 | # 找到文件的最后名字 547 | dot_index = file.rfind('.') 548 | _file_prefix = file[:dot_index] # 文件名的前缀 549 | _file_suffix = file[dot_index:] # 文件名的后缀 550 | img = cv2.imread(pic_path) 551 | 552 | # show_pic(img, coords) # 显示原图 553 | while cnt < need_aug_num: # 继续增强 554 | auged_img, auged_bboxes = dataAug.dataAugment(img, coords) 555 | auged_bboxes_int = np.array(auged_bboxes).astype(np.int32) 556 | height, width, channel = auged_img.shape # 得到图片的属性 557 | img_name = '{}_{}{}'.format(_file_prefix, cnt + 1, _file_suffix) # 图片保存的信息 558 | toolhelper.save_img(img_name, save_img_path, 559 | auged_img) # 保存增强图片 560 | 561 | toolhelper.save_xml('{}_{}.xml'.format(_file_prefix, cnt + 1), 562 | save_xml_path, (save_img_path, img_name), height, width, channel, 563 | (labels, auged_bboxes_int)) # 保存xml文件 564 | # show_pic(auged_img, auged_bboxes) # 强化后的图 565 | print(img_name) 566 | cnt += 1 # 继续增强下一张 567 | -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectDetection/data/Annotations/0001.xml: -------------------------------------------------------------------------------- 1 | 2 | Desktop 3 | 0001.jpg 4 | /home/nvidia/Desktop/0001.jpg 5 | 6 | Unknown 7 | 8 | 9 | 450 10 | 354 11 | 3 12 | 13 | 0 14 | 15 | dog 16 | Unspecified 17 | 0 18 | 0 19 | 20 | 105 21 | 41 22 | 277 23 | 315 24 | 25 | 26 | 27 | star 28 | Unspecified 29 | 0 30 | 0 31 | 32 | 270 33 | 288 34 | 436 35 | 337 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectDetection/data/Images/0001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/DataAugForObjectDetection/data/Images/0001.jpg -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectSegmentation/DataAugmentforLabelMe.py: -------------------------------------------------------------------------------- 1 | # encoding='UTF-8' 2 | # author: pureyang 3 | # TIME: 2019/8/26 下午5:22 4 | # Description:data augmentation for Object Segmentation 5 | ############################################################## 6 | 7 | # 包括: 8 | # 1. 改变亮度 9 | # 2. 加噪声 10 | # 3. 加随机点 11 | # 4. 镜像(需要改变points) 12 | 13 | import time 14 | import random 15 | import cv2 16 | import os 17 | import numpy as np 18 | from skimage.util import random_noise 19 | import base64 20 | import json 21 | import re 22 | from copy import deepcopy 23 | import argparse 24 | 25 | 26 | # 图像均为cv2读取 27 | class DataAugmentForObjectDetection(): 28 | def __init__(self, change_light_rate=0.5, 29 | add_noise_rate=0.5, random_point=0.5, flip_rate=0.5, shift_rate=0.5, rand_point_percent=0.03, 30 | is_addNoise=True, is_changeLight=True, is_random_point=True, is_shift_pic_bboxes=True, 31 | is_filp_pic_bboxes=True): 32 | # 配置各个操作的属性 33 | self.change_light_rate = change_light_rate 34 | self.add_noise_rate = add_noise_rate 35 | self.random_point = random_point 36 | self.flip_rate = flip_rate 37 | self.shift_rate = shift_rate 38 | 39 | self.rand_point_percent = rand_point_percent 40 | 41 | # 是否使用某种增强方式 42 | self.is_addNoise = is_addNoise 43 | self.is_changeLight = is_changeLight 44 | self.is_random_point = is_random_point 45 | self.is_filp_pic_bboxes = is_filp_pic_bboxes 46 | self.is_shift_pic_bboxes = is_shift_pic_bboxes 47 | 48 | # 加噪声 49 | def _addNoise(self, img): 50 | return random_noise(img, seed=int(time.time())) * 255 51 | 52 | # 调整亮度 53 | def _changeLight(self, img): 54 | alpha = random.uniform(0.35, 1) 55 | blank = np.zeros(img.shape, img.dtype) 56 | return cv2.addWeighted(img, alpha, blank, 1 - alpha, 0) 57 | 58 | # 随机的改变点的值 59 | def _addRandPoint(self, img): 60 | percent = self.rand_point_percent 61 | num = int(percent * img.shape[0] * img.shape[1]) 62 | for i in range(num): 63 | rand_x = random.randint(0, img.shape[0] - 1) 64 | rand_y = random.randint(0, img.shape[1] - 1) 65 | if random.randint(0, 1) == 0: 66 | img[rand_x, rand_y] = 0 67 | else: 68 | img[rand_x, rand_y] = 255 69 | return img 70 | 71 | # 平移 72 | def _shift_pic_bboxes(self, img, json_info): 73 | 74 | # ---------------------- 平移图像 ---------------------- 75 | h, w, _ = img.shape 76 | x_min = w 77 | x_max = 0 78 | y_min = h 79 | y_max = 0 80 | 81 | shapes = json_info['shapes'] 82 | for shape in shapes: 83 | points = np.array(shape['points']) 84 | x_min = min(x_min, points[:, 0].min()) 85 | y_min = min(y_min, points[:, 1].min()) 86 | x_max = max(x_max, points[:, 0].max()) 87 | y_max = max(y_max, points[:, 0].max()) 88 | 89 | d_to_left = x_min # 包含所有目标框的最大左移动距离 90 | d_to_right = w - x_max # 包含所有目标框的最大右移动距离 91 | d_to_top = y_min # 包含所有目标框的最大上移动距离 92 | d_to_bottom = h - y_max # 包含所有目标框的最大下移动距离 93 | 94 | x = random.uniform(-(d_to_left - 1) / 3, (d_to_right - 1) / 3) 95 | y = random.uniform(-(d_to_top - 1) / 3, (d_to_bottom - 1) / 3) 96 | 97 | M = np.float32([[1, 0, x], [0, 1, y]]) # x为向左或右移动的像素值,正为向右负为向左; y为向上或者向下移动的像素值,正为向下负为向上 98 | shift_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0])) 99 | 100 | # ---------------------- 平移boundingbox ---------------------- 101 | for shape in shapes: 102 | for p in shape['points']: 103 | p[0] += x 104 | p[1] += y 105 | return shift_img, json_info 106 | 107 | # 镜像 108 | def _filp_pic_bboxes(self, img, json_info): 109 | 110 | # ---------------------- 翻转图像 ---------------------- 111 | h, w, _ = img.shape 112 | 113 | sed = random.random() 114 | 115 | if 0 < sed < 0.33: # 0.33的概率水平翻转,0.33的概率垂直翻转,0.33是对角反转 116 | flip_img = cv2.flip(img, 0) # _flip_x 117 | inver = 0 118 | elif 0.33 < sed < 0.66: 119 | flip_img = cv2.flip(img, 1) # _flip_y 120 | inver = 1 121 | else: 122 | flip_img = cv2.flip(img, -1) # flip_x_y 123 | inver = -1 124 | 125 | # ---------------------- 调整boundingbox ---------------------- 126 | shapes = json_info['shapes'] 127 | for shape in shapes: 128 | for p in shape['points']: 129 | if inver == 0: 130 | p[1] = h - p[1] 131 | elif inver == 1: 132 | p[0] = w - p[0] 133 | elif inver == -1: 134 | p[0] = w - p[0] 135 | p[1] = h - p[1] 136 | 137 | return flip_img, json_info 138 | 139 | # 图像增强方法 140 | def dataAugment(self, img, dic_info): 141 | 142 | change_num = 0 # 改变的次数 143 | while change_num < 1: # 默认至少有一种数据增强生效 144 | 145 | if self.is_changeLight: 146 | if random.random() > self.change_light_rate: # 改变亮度 147 | change_num += 1 148 | img = self._changeLight(img) 149 | 150 | if self.is_addNoise: 151 | if random.random() < self.add_noise_rate: # 加噪声 152 | change_num += 1 153 | img = self._addNoise(img) 154 | if self.is_random_point: 155 | if random.random() < self.random_point: # 加随机点 156 | change_num += 1 157 | img = self._addRandPoint(img) 158 | if self.is_shift_pic_bboxes: 159 | if random.random() < self.shift_rate: # 平移 160 | change_num += 1 161 | img, dic_info = self._shift_pic_bboxes(img, dic_info) 162 | if self.is_filp_pic_bboxes or 1: 163 | if random.random() < self.flip_rate: # 翻转 164 | change_num += 1 165 | img, bboxes = self._filp_pic_bboxes(img, dic_info) 166 | 167 | return img, dic_info 168 | 169 | 170 | # xml解析工具 171 | class ToolHelper(): 172 | # 从json文件中提取原始标定的信息 173 | def parse_json(self, path): 174 | with open(path)as f: 175 | json_data = json.load(f) 176 | return json_data 177 | 178 | # 对图片进行字符编码 179 | def img2str(self, img_name): 180 | with open(img_name, "rb")as f: 181 | base64_data = str(base64.b64encode(f.read())) 182 | match_pattern = re.compile(r'b\'(.*)\'') 183 | base64_data = match_pattern.match(base64_data).group(1) 184 | return base64_data 185 | 186 | # 保存图片结果 187 | def save_img(self, save_path, img): 188 | cv2.imwrite(save_path, img) 189 | 190 | # 保持json结果 191 | 192 | def save_json(self, file_name, save_folder, dic_info): 193 | with open(os.path.join(save_folder, file_name), 'w') as f: 194 | json.dump(dic_info, f, indent=2) 195 | 196 | 197 | if __name__ == '__main__': 198 | 199 | need_aug_num = 3 # 每张图片需要增强的次数 200 | 201 | toolhelper = ToolHelper() # 工具 202 | 203 | is_endwidth_dot = True # 文件是否以.jpg或者png结尾 204 | 205 | dataAug = DataAugmentForObjectDetection() # 数据增强工具类 206 | 207 | # 获取相关参数 208 | parser = argparse.ArgumentParser() 209 | parser.add_argument('--source_img_json_path', type=str, default='data') 210 | parser.add_argument('--save_img_json_path', type=str, default='data2') 211 | args = parser.parse_args() 212 | source_img_json_path = args.source_img_json_path # 图片和json文件原始位置 213 | save_img_json_path = args.save_img_json_path # 图片增强结果保存文件 214 | 215 | # 如果保存文件夹不存在就创建 216 | if not os.path.exists(save_img_json_path): 217 | os.mkdir(save_img_json_path) 218 | 219 | for parent, _, files in os.walk(source_img_json_path): 220 | files.sort() # 排序一下 221 | for file in files: 222 | if file.endswith('jpg') or file.endswith('png'): 223 | cnt = 0 224 | pic_path = os.path.join(parent, file) 225 | json_path = os.path.join(parent, file[:-4] + '.json') 226 | json_dic = toolhelper.parse_json(json_path) 227 | # 如果图片是有后缀的 228 | if is_endwidth_dot: 229 | # 找到文件的最后名字 230 | dot_index = file.rfind('.') 231 | _file_prefix = file[:dot_index] # 文件名的前缀 232 | _file_suffix = file[dot_index:] # 文件名的后缀 233 | img = cv2.imread(pic_path) 234 | 235 | while cnt < need_aug_num: # 继续增强 236 | auged_img, json_info = dataAug.dataAugment(deepcopy(img), deepcopy(json_dic)) 237 | img_name = '{}_{}{}'.format(_file_prefix, cnt + 1, _file_suffix) # 图片保存的信息 238 | img_save_path = os.path.join(save_img_json_path, img_name) 239 | toolhelper.save_img(img_save_path, auged_img) # 保存增强图片 240 | 241 | json_info['imagePath'] = img_name 242 | base64_data = toolhelper.img2str(img_save_path) 243 | json_info['imageData'] = base64_data 244 | toolhelper.save_json('{}_{}.json'.format(_file_prefix, cnt + 1), 245 | save_img_json_path, json_info) # 保存xml文件 246 | print(img_name) 247 | cnt += 1 # 继续增强下一张 248 | -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectSegmentation/__init__.py: -------------------------------------------------------------------------------- 1 | #encoding='UTF-8' 2 | #author: py 3 | #TIME: 2019/8/24 上午11:21 4 | #Description: 5 | -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectSegmentation/data/0001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/DataAugForObjectSegmentation/data/0001.jpg -------------------------------------------------------------------------------- /Data-enhancement/DataAugForObjectSegmentation/data/0001.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.16.3", 3 | "flags": {}, 4 | "shapes": [ 5 | { 6 | "label": "dog", 7 | "line_color": null, 8 | "fill_color": null, 9 | "points": [ 10 | [ 11 | 174.96113074204948, 12 | 60.42402826855123 13 | ], 14 | [ 15 | 185.56183745583039, 16 | 63.25088339222615 17 | ], 18 | [ 19 | 191.2155477031802, 20 | 65.01766784452296 21 | ], 22 | [ 23 | 196.51590106007066, 24 | 67.49116607773851 25 | ], 26 | [ 27 | 202.87632508833923, 28 | 68.90459363957596 29 | ], 30 | [ 31 | 211.35689045936394, 32 | 69.96466431095406 33 | ], 34 | [ 35 | 213.8303886925795, 36 | 69.6113074204947 37 | ], 38 | [ 39 | 220.89752650176678, 40 | 69.25795053003533 41 | ], 42 | [ 43 | 229.02473498233218, 44 | 68.55123674911661 45 | ], 46 | [ 47 | 232.91166077738518, 48 | 68.19787985865725 49 | ], 50 | [ 51 | 238.565371024735, 52 | 69.6113074204947 53 | ], 54 | [ 55 | 241.74558303886926, 56 | 65.01766784452296 57 | ], 58 | [ 59 | 244.5724381625442, 60 | 59.01060070671378 61 | ], 62 | [ 63 | 249.51943462897526, 64 | 52.65017667844523 65 | ], 66 | [ 67 | 250.226148409894, 68 | 49.11660777385159 69 | ], 70 | [ 71 | 255.17314487632507, 72 | 43.81625441696113 73 | ], 74 | [ 75 | 257.6466431095406, 76 | 43.109540636042404 77 | ], 78 | [ 79 | 259.7667844522968, 80 | 42.75618374558304 81 | ], 82 | [ 83 | 265.0671378091873, 84 | 43.109540636042404 85 | ], 86 | [ 87 | 268.24734982332154, 88 | 48.40989399293286 89 | ], 90 | [ 91 | 269.3074204946996, 92 | 52.65017667844523 93 | ], 94 | [ 95 | 275.6678445229682, 96 | 60.07067137809187 97 | ], 98 | [ 99 | 275.6678445229682, 100 | 65.37102473498233 101 | ], 102 | [ 103 | 274.9611307420495, 104 | 72.79151943462897 105 | ], 106 | [ 107 | 273.1943462897526, 108 | 78.4452296819788 109 | ], 110 | [ 111 | 274.25441696113074, 112 | 83.74558303886926 113 | ], 114 | [ 115 | 274.25441696113074, 116 | 87.98586572438163 117 | ], 118 | [ 119 | 275.3144876325088, 120 | 92.226148409894 121 | ], 122 | [ 123 | 278.4946996466431, 124 | 97.52650176678445 125 | ], 126 | [ 127 | 276.02120141342755, 128 | 102.8268551236749 129 | ], 130 | [ 131 | 274.9611307420495, 132 | 107.06713780918727 133 | ], 134 | [ 135 | 272.8409893992933, 136 | 113.07420494699646 137 | ], 138 | [ 139 | 272.8409893992933, 140 | 119.78798586572438 141 | ], 142 | [ 143 | 269.3074204946996, 144 | 126.14840989399293 145 | ], 146 | [ 147 | 267.8939929328622, 148 | 133.56890459363956 149 | ], 150 | [ 151 | 264.71378091872793, 152 | 139.2226148409894 153 | ], 154 | [ 155 | 263.30035335689047, 156 | 145.2296819787986 157 | ], 158 | [ 159 | 263.30035335689047, 160 | 150.17667844522967 161 | ], 162 | [ 163 | 263.6537102473498, 164 | 156.8904593639576 165 | ], 166 | [ 167 | 263.30035335689047, 168 | 166.07773851590105 169 | ], 170 | [ 171 | 263.6537102473498, 172 | 176.67844522968198 173 | ], 174 | [ 175 | 263.6537102473498, 176 | 185.51236749116606 177 | ], 178 | [ 179 | 264.0070671378092, 180 | 193.9929328621908 181 | ], 182 | [ 183 | 264.0070671378092, 184 | 198.23321554770317 185 | ], 186 | [ 187 | 264.0070671378092, 188 | 206.7137809187279 189 | ], 190 | [ 191 | 264.71378091872793, 192 | 209.5406360424028 193 | ], 194 | [ 195 | 265.773851590106, 196 | 214.13427561837455 197 | ], 198 | [ 199 | 265.773851590106, 200 | 225.79505300353355 201 | ], 202 | [ 203 | 260.82685512367493, 204 | 233.2155477031802 205 | ], 206 | [ 207 | 254.113074204947, 208 | 233.92226148409893 209 | ], 210 | [ 211 | 255.52650176678446, 212 | 238.1625441696113 213 | ], 214 | [ 215 | 250.57950530035333, 216 | 245.58303886925793 217 | ], 218 | [ 219 | 247.75265017667846, 220 | 254.41696113074204 221 | ], 222 | [ 223 | 244.2190812720848, 224 | 258.65724381625444 225 | ], 226 | [ 227 | 241.74558303886926, 228 | 259.3639575971731 229 | ], 230 | [ 231 | 229.73144876325085, 232 | 259.3639575971731 233 | ], 234 | [ 235 | 227.25795053003532, 236 | 260.42402826855124 237 | ], 238 | [ 239 | 214.89045936395758, 240 | 250.8833922261484 241 | ], 242 | [ 243 | 211.0035335689046, 244 | 250.53003533568904 245 | ], 246 | [ 247 | 209.23674911660777, 248 | 259.7173144876325 249 | ], 250 | [ 251 | 205.34982332155477, 252 | 269.2579505300353 253 | ], 254 | [ 255 | 202.87632508833923, 256 | 278.4452296819788 257 | ], 258 | [ 259 | 201.81625441696113, 260 | 285.86572438162545 261 | ], 262 | [ 263 | 202.87632508833923, 264 | 298.58657243816253 265 | ], 266 | [ 267 | 200.75618374558303, 268 | 307.0671378091873 269 | ], 270 | [ 271 | 201.1095406360424, 272 | 312.01413427561835 273 | ], 274 | [ 275 | 197.2226148409894, 276 | 315.547703180212 277 | ], 278 | [ 279 | 186.26855123674912, 280 | 314.48763250883394 281 | ], 282 | [ 283 | 180.61484098939928, 284 | 314.48763250883394 285 | ], 286 | [ 287 | 173.547703180212, 288 | 310.24734982332154 289 | ], 290 | [ 291 | 169.660777385159, 292 | 300.70671378091873 293 | ], 294 | [ 295 | 168.95406360424028, 296 | 288.339222614841 297 | ], 298 | [ 299 | 167.5406360424028, 300 | 274.5583038869258 301 | ], 302 | [ 303 | 169.30742049469964, 304 | 262.54416961130744 305 | ], 306 | [ 307 | 166.8339222614841, 308 | 256.18374558303884 309 | ], 310 | [ 311 | 160.12014134275617, 312 | 249.46996466431094 313 | ], 314 | [ 315 | 156.9399293286219, 316 | 249.1166077738516 317 | ], 318 | [ 319 | 149.51943462897526, 320 | 249.1166077738516 321 | ], 322 | [ 323 | 145.2791519434629, 324 | 250.53003533568904 325 | ], 326 | [ 327 | 141.3922261484099, 328 | 257.24381625441697 329 | ], 330 | [ 331 | 138.21201413427562, 332 | 265.7243816254417 333 | ], 334 | [ 335 | 136.79858657243815, 336 | 274.9116607773852 337 | ], 338 | [ 339 | 133.61837455830388, 340 | 285.1590106007067 341 | ], 342 | [ 343 | 133.97173144876325, 344 | 292.9328621908127 345 | ], 346 | [ 347 | 130.43816254416961, 348 | 300.35335689045934 349 | ], 350 | [ 351 | 131.14487632508835, 352 | 306.36042402826854 353 | ], 354 | [ 355 | 126.19787985865725, 356 | 309.8939929328622 357 | ], 358 | [ 359 | 121.95759717314488, 360 | 309.8939929328622 361 | ], 362 | [ 363 | 110.29681978798587, 364 | 308.12720848056534 365 | ], 366 | [ 367 | 110.29681978798587, 368 | 308.12720848056534 369 | ], 370 | [ 371 | 106.40989399293287, 372 | 307.0671378091873 373 | ], 374 | [ 375 | 103.58303886925793, 376 | 304.24028268551234 377 | ], 378 | [ 379 | 104.64310954063603, 380 | 292.57950530035333 381 | ], 382 | [ 383 | 104.64310954063603, 384 | 283.74558303886926 385 | ], 386 | [ 387 | 104.28975265017667, 388 | 274.9116607773852 389 | ], 390 | [ 391 | 103.9363957597173, 392 | 267.84452296819785 393 | ], 394 | [ 395 | 104.28975265017667, 396 | 262.54416961130744 397 | ], 398 | [ 399 | 104.64310954063603, 400 | 257.5971731448763 401 | ], 402 | [ 403 | 105.34982332155477, 404 | 250.17667844522967 405 | ], 406 | [ 407 | 106.0565371024735, 408 | 230.03533568904592 409 | ], 410 | [ 411 | 107.8233215547703, 412 | 222.61484098939928 413 | ], 414 | [ 415 | 107.8233215547703, 416 | 215.19434628975264 417 | ], 418 | [ 419 | 107.8233215547703, 420 | 209.89399293286218 421 | ], 422 | [ 423 | 107.46996466431096, 424 | 198.58657243816253 425 | ], 426 | [ 427 | 107.46996466431096, 428 | 190.45936395759716 429 | ], 430 | [ 431 | 105.70318021201413, 432 | 182.68551236749116 433 | ], 434 | [ 435 | 107.8233215547703, 436 | 173.85159010600705 437 | ], 438 | [ 439 | 113.12367491166077, 440 | 165.37102473498234 441 | ], 442 | [ 443 | 117.7173144876325, 444 | 156.8904593639576 445 | ], 446 | [ 447 | 126.90459363957598, 448 | 146.9964664310954 449 | ], 450 | [ 451 | 136.4452296819788, 452 | 137.80918727915193 453 | ], 454 | [ 455 | 143.86572438162543, 456 | 131.09540636042402 457 | ], 458 | [ 459 | 151.63957597173143, 460 | 124.02826855123675 461 | ], 462 | [ 463 | 153.40636042402826, 464 | 117.31448763250883 465 | ], 466 | [ 467 | 159.41342756183744, 468 | 108.83392226148409 469 | ], 470 | [ 471 | 166.8339222614841, 472 | 102.47349823321555 473 | ], 474 | [ 475 | 167.89399293286218, 476 | 95.75971731448763 477 | ], 478 | [ 479 | 166.12720848056537, 480 | 91.87279151943463 481 | ], 482 | [ 483 | 168.24734982332154, 484 | 85.51236749116607 485 | ], 486 | [ 487 | 170.36749116607774, 488 | 77.03180212014134 489 | ], 490 | [ 491 | 172.13427561837455, 492 | 67.84452296819788 493 | ] 494 | ], 495 | "shape_type": "polygon", 496 | "flags": {} 497 | }, 498 | { 499 | "label": "star", 500 | "line_color": null, 501 | "fill_color": null, 502 | "points": [ 503 | [ 504 | 276.37455830388694, 505 | 314.8409893992933 506 | ], 507 | [ 508 | 283.4416961130742, 509 | 308.12720848056534 510 | ], 511 | [ 512 | 288.7420494699647, 513 | 299.6466431095406 514 | ], 515 | [ 516 | 298.2826855123675, 517 | 295.05300353356887 518 | ], 519 | [ 520 | 308.8833922261484, 521 | 290.81272084805653 522 | ], 523 | [ 524 | 319.4840989399293, 525 | 289.75265017667846 526 | ], 527 | [ 528 | 332.5583038869258, 529 | 292.226148409894 530 | ], 531 | [ 532 | 339.2720848056537, 533 | 294.69964664310953 534 | ], 535 | [ 536 | 350.226148409894, 537 | 295.7597173144876 538 | ], 539 | [ 540 | 356.58657243816253, 541 | 295.05300353356887 542 | ], 543 | [ 544 | 365.773851590106, 545 | 294.3462897526502 546 | ], 547 | [ 548 | 377.434628975265, 549 | 293.9929328621908 550 | ], 551 | [ 552 | 387.3286219081272, 553 | 294.3462897526502 554 | ], 555 | [ 556 | 405.34982332155477, 557 | 297.8798586572438 558 | ], 559 | [ 560 | 403.9363957597173, 561 | 301.06007067137807 562 | ], 563 | [ 564 | 420.19081272084804, 565 | 299.29328621908127 566 | ], 567 | [ 568 | 423.3710247349823, 569 | 298.58657243816253 570 | ], 571 | [ 572 | 428.31802120141344, 573 | 304.24028268551234 574 | ], 575 | [ 576 | 434.3250883392226, 577 | 309.8939929328622 578 | ], 579 | [ 580 | 435.73851590106005, 581 | 314.8409893992933 582 | ], 583 | [ 584 | 434.3250883392226, 585 | 322.26148409893995 586 | ], 587 | [ 588 | 430.08480565371025, 589 | 326.14840989399295 590 | ], 591 | [ 592 | 427.96466431095405, 593 | 331.80212014134275 594 | ], 595 | [ 596 | 419.4840989399293, 597 | 334.982332155477 598 | ], 599 | [ 600 | 409.5901060070671, 601 | 336.0424028268551 602 | ], 603 | [ 604 | 400.0494699646643, 605 | 333.56890459363956 606 | ], 607 | [ 608 | 387.3286219081272, 609 | 335.68904593639576 610 | ], 611 | [ 612 | 374.25441696113074, 613 | 328.9752650176678 614 | ], 615 | [ 616 | 362.24028268551234, 617 | 328.9752650176678 618 | ], 619 | [ 620 | 360.1201413427562, 621 | 331.44876325088336 622 | ], 623 | [ 624 | 354.113074204947, 625 | 334.982332155477 626 | ], 627 | [ 628 | 350.9328621908127, 629 | 339.22261484098937 630 | ], 631 | [ 632 | 335.3851590106007, 633 | 338.5159010600707 634 | ], 635 | [ 636 | 327.6113074204947, 637 | 337.45583038869256 638 | ], 639 | [ 640 | 318.7773851590106, 641 | 337.1024734982332 642 | ], 643 | [ 644 | 317.0106007067138, 645 | 325.0883392226148 646 | ], 647 | [ 648 | 315.9505300353357, 649 | 320.4946996466431 650 | ], 651 | [ 652 | 306.0565371024735, 653 | 319.78798586572435 654 | ], 655 | [ 656 | 296.86925795053, 657 | 326.8551236749116 658 | ], 659 | [ 660 | 298.2826855123675, 661 | 337.1024734982332 662 | ], 663 | [ 664 | 286.9752650176678, 665 | 339.22261484098937 666 | ], 667 | [ 668 | 274.25441696113074, 669 | 338.86925795053 670 | ], 671 | [ 672 | 272.48763250883394, 673 | 332.1554770318021 674 | ], 675 | [ 676 | 267.18727915194347, 677 | 320.4946996466431 678 | ] 679 | ], 680 | "shape_type": "polygon", 681 | "flags": {} 682 | } 683 | ], 684 | "lineColor": [ 685 | 0, 686 | 255, 687 | 0, 688 | 128 689 | ], 690 | "fillColor": [ 691 | 255, 692 | 0, 693 | 0, 694 | 128 695 | ], 696 | "imagePath": "0001.jpg", 697 | "imageData": "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", 698 | "imageHeight": 354, 699 | "imageWidth": 450 700 | } -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_1.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_10.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_11.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_12.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_13.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_2.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_3.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_4.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_5.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_6.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_7.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_8.jpg -------------------------------------------------------------------------------- /Data-enhancement/Imgs/Camera_1_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cuitno1/Data-enhancement/09490f5266c688e0541ad55b4ff77bb85d031bd5/Data-enhancement/Imgs/Camera_1_9.jpg -------------------------------------------------------------------------------- /Data-enhancement/README.md: -------------------------------------------------------------------------------- 1 | 2 | # 这是一个目标检测和目标分割增强的小工具,需要您事先标记一些图片,然后变化增强图片(支持LabelIMg和LabelMe标注的文件),希望对您有所帮助!
3 | **包括3个python文件(rename_file.py、DataAugmentforLabelImg.py和DataAugmentforLabelMe.py)**
4 | 1. rename_file.py能实现文件的重命名,注意修改文件的路径 5 | 2. DataAugmentforLabelImg.py能实现LabelImg标注后的图片的增强(包括模糊,亮度,裁剪,旋转,平移,镜像等变化) 6 | 3. DataAugmentforLabelMe.py能实现LabelMe标注后的图片的增强(包括模糊、亮度、平移、镜像等变化) 7 | 8 | **注意:一些包的安装是必要的,比如Opencv_python等** 9 |
10 | ##*将您需要增强的图片放在对应的文件夹即可,具体可参考demo给出的图片和xml文件存放路径,您放入即可* 11 |
12 | **保存结果:**
13 | 1. 目标检测增强后的图片默认会保存在./data/Images2中,xml文件会保存在./data/Annotations2中(包括新的图片和xml文件)
14 | 2. 目标分割增强后的图片默认会保存在./data2中(包括新的图片和json文件) 15 |
16 | 17 | **实现这个工具参考了:**
18 | https://github.com/maozezhong/CV_ToolBox/blob/master/DataAugForObjectDetection/ 19 | -------------------------------------------------------------------------------- /Data-enhancement/rename_file.py: -------------------------------------------------------------------------------- 1 | # encoding='UTF-8' 2 | # author: pureyang 3 | # TIME: 2019/8/22 下午5:15 4 | # Description:数据图片的重命名 5 | 6 | import os 7 | 8 | 9 | def deal(path): 10 | file_names = os.listdir(path) 11 | c = 0 12 | # 随机获取一张图片的格式 13 | f_first = file_names[0] 14 | 15 | suffix = f_first.split('.')[-1] # 图片文件的后缀 16 | for file in file_names: 17 | os.rename(os.path.join(path, file), os.path.join(path, '{:0>6d}.{}'.format(c, suffix))) 18 | c += 1 19 | 20 | 21 | if __name__ == '__main__': 22 | deal('./data') # 请按需修改图片文件的路径 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-enhancement 2 | **2022/10/22 修改了github代码导致xmax 18 | ##*将您需要增强的图片放在对应的文件夹即可,具体可参考demo给出的图片和xml文件存放路径,您放入即可* 19 |
20 | **保存结果:**
21 | 22 | 1. 目标检测增强后的图片默认会保存在./data/Images2中,xml文件会保存在./data/Annotations2中(包括新的图片和xml文件)
23 | 2. 目标分割增强后的图片默认会保存在./data2中(包括新的图片和json文件) 24 |
25 | 26 | **实现这个工具参考了:**
27 | https://github.com/maozezhong/CV_ToolBox/blob/master/DataAugForObjectDetection/ 28 | --------------------------------------------------------------------------------