深度学习 之 数据增广(包含源码及注释文件更改)
生活随笔
收集整理的這篇文章主要介紹了
深度学习 之 数据增广(包含源码及注释文件更改)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據增廣:平移,水平/垂直翻轉,旋轉,縮放,剪切,對比度,色彩抖動,噪聲?
#coding=utf-8 ####################################################################### # 數據增廣,包括:平移,水平/垂直翻轉,旋轉,縮放,剪切,對比度,噪聲 # # 2021/3/8 13:40 # #######################################################################import os import cv2 import copy import json import skimage import numpy as np from random import choiceclass DataAugment:def __init__(self, debug=False):self.debug=debugprint("Data augment...")# 基礎變換矩陣def basic_matrix(self, translation): return np.array([[1,0,translation[0]],[0,1,translation[1]],[0,0,1]]) # translation = center = [width/2, height/2]# 基礎變換矩陣def adjust_transform_for_image(self, img, trans_matrix): transform_matrix=copy.deepcopy(trans_matrix) # deep copyprint("trans_matrix is \n", trans_matrix)# ################# trans_matrix ################# 平移: # [1, 0, a]# transform_matrix = [0, 1, b] # [0, 0, 1]## 垂直反轉:# [1, 0, 0]# flip_matrix = [0, -1, 0]# [0, 0, 1]## 水平反轉:# [-1, 0, 0]# flip_matrix = [ 0, 1, 0]# [ 0, 0, 1]## 旋轉a度(順):# [cos(a), -sin(a), 0]# rotate_matrix = [sin(a), cos(a), 0]# [ 0 , 0 , 1]## 圖片縮放:# [ a, 0, 0]# scale_matrix = [ 0, b, 0]# [ 0, 0, 1]## 圖片錯切:# [ 1, a, 0]# crop_matrix = [ b, 1, 0]# [ 0, 0, 1]height, width, channels = img.shapetransform_matrix[0:2, 2] *= [width, height]print("transform_matrix is \n", transform_matrix)# ################# trans_matrix ################# 平移: # [1, 0, aw]# transform_matrix = [0, 1, bh] # [0, 0, 1]## 垂直反轉:# [1, 0, 0]# flip_matrix = [0, -1, 0]# [0, 0, 1]## 水平反轉:# [-1, 0, 0]# flip_matrix = [ 0, 1, 0]# [ 0, 0, 1]## 旋轉a度(順):# [cos(a), -sin(a), 0]# rotate_matrix = [sin(a), cos(a), 0]# [ 0 , 0 , 1]## 圖片縮放:# [ a, 0, 0]# scale_matrix = [ 0, b, 0]# [ 0, 0, 1]## 圖片錯切:# [ 1, a, 0]# crop_matrix = [ b, 1, 0]# [ 0, 0, 1]center = np.array((0.5 * width, 0.5 * height))transform_matrix = np.linalg.multi_dot([self.basic_matrix(center), transform_matrix, self.basic_matrix(-center)])# ################# trans_matrix ################# 平移: 沿x軸平移aw個像素,沿y軸平移bh個像素# [1, 0, aw]# transform_matrix = [0, 1, bh] # [0, 0, 1]## 垂直反轉:# [1, 0, 0]# flip_matrix = [0, -1, h]# [0, 0, 1]## 水平反轉:# [-1, 0, w]# flip_matrix = [ 0, 1, 0]# [ 0, 0, 1]## 旋轉a度(順):以(w/2, h/2)為中心,順時針旋轉a度# [cos(a), -sin(a), w/2-(w/2)cos(a)+(h/2)sin(a)]# rotate_matrix = [sin(a), cos(a), h/2-(h/2)cos(a)-(w/2)sin(a)]# [ 0 , 0 , 1 ]## 圖片縮放:沿x軸放大a個像素,沿y軸放大b個像素# [ a, 0, w/2-(w/2)*a]# scale_matrix = [ 0, b, h/2-(h/2)*b]# [ 0, 0, 1 ]## 圖片錯切:# [ 1, a, -(h/2)*a]# crop_matrix = [ b, 1, -(w/2)*b]# [ 0, 0, 1 ]print("transform_matrix np.linalg.multi_dot is \n", transform_matrix, '\n') return transform_matrix# 仿射變換def apply_transform(self, img, transform): output = cv2.warpAffine(img, transform[:2, :], dsize=(img.shape[1], img.shape[0]),flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_TRANSPARENT, borderValue=0,)# ################################ borderMode ############################################ [1] cv2.BORDER_CONSTANT? 填充邊界時使用常數填充# [2] cv2.BORDER_REPLICATE: 使用邊界最接近的像素填充,也就是用邊緣像素填充# [3] cv2.BORDER_REFLECT, 反射法,是指對圖像的像素兩邊進行復制# [4] cv2.BORDER_REFLECT101:?反射法,把邊緣的像素作為軸,對稱的復制# [5]?cv2.BORDER_WRAP: 用另一邊的像素進行填充# [6] cv2.BORDER_TRANSPARENTreturn output# 應用變換def apply(self, img, trans_matrix): tmp_matrix=self.adjust_transform_for_image(img, trans_matrix)out_img=self.apply_transform(img, tmp_matrix) if self.debug:self.show(out_img)return tmp_matrix, out_img# 生成范圍矩陣def random_vector(self, min, max): min=np.array(min)max=np.array(max)print(min.shape,max.shape)assert min.shape==max.shapeassert len(min.shape) == 1return np.random.uniform(min, max)# 可視化def show(self, img): cv2.imshow("outimg",img)cv2.waitKey()# 平移變換def random_transform(self, img, min_translation, max_translation): factor=self.random_vector(min_translation,max_translation)trans_matrix=np.array([[1, 0, factor[0]],[0, 1, factor[1]],[0, 0, 1]])tmp_matrix, out_img=self.apply(img,trans_matrix)return tmp_matrix, trans_matrix, out_img# 水平或垂直翻轉def random_flip(self, img, factor): # 垂直: factor=[1.0, -1.0]# 水平: factor=[-1.0, 1.0]flip_matrix = np.array([[factor[0], 0, 0],[0, factor[1], 0],[0, 0, 1]])_, out_img=self.apply(img,flip_matrix)return flip_matrix, out_img# 隨機旋轉(順)def random_rotate(self, img, factor): # 除了以下方法,還可以考慮cv2.getRotationMatrix2D這個函數angle=np.random.randint(factor[0],factor[1])print("angle : {}°".format(angle))angle = np.pi / 180.0 * angle rotate_matrix=np.array([[np.cos(angle), -np.sin(angle), 0], [np.sin(angle), np.cos(angle), 0], [0, 0, 1]]) # 順時針_, out_img=self.apply(img,rotate_matrix) return angle, rotate_matrix, out_img# 隨機縮放def random_scale(self, img, min_translation, max_translation): factor=self.random_vector(min_translation, max_translation)scale_matrix = np.array([[factor[0], 0, 0],[0, factor[1], 0],[0, 0, 1]])_, out_img=self.apply(img,scale_matrix)return factor, scale_matrix, out_img# 隨機剪切,包括橫向和眾向剪切def random_shear(self, img, factor): angle = np.random.uniform(factor[0], factor[1])print("fc:{}".format(angle))crop_matrix = np.array([[1, factor[0], 0], [factor[1], 1, 0], [0, 0, 1]])_, out_img=self.apply(img,crop_matrix)return angle, crop_matrix, out_img# 設置對比度和亮度def brightness_contrast_ratio(self, im):brightness = [0.6, 0.7, 0.8, 0.9, 1.0]contrast_ratio = [1.5, 1.6, 1.7, 1.8]a = choice(contrast_ratio)b = choice(brightness)print(f"brightness is , contrast is {a}")img = np.array(im)mean = np.mean(img)temp = img - meanimg = temp * a + mean * bif self.debug:self.show(img)return img# 隨機噪聲def random_noise(self, im):noise_img = skimage.util.random_noise(im, mode='gaussian', var=0.01) # 原圖像素為float,skimage操作后控制在[0,1]內,返回時需擴大到[0,255] img = noise_img * 255 if self.debug:self.show(img)return imgclass DataAugmen_Json:def __init__(self, readPath, savePath): self.width = Noneself.height = Noneself.shapes = Noneself.json_file = Noneself.read_path = readPathself.save_path = savePathprint("Change json...")# 讀取json文件,并存放在類變量中def openjson(self, name):path = os.path.join(self.read_path, name)with open(path, 'r') as f:self.json_file = json.load(f) self.width = self.json_file['imageWidth']self.height = self.json_file['imageHeight']self.shapes = self.json_file['shapes']# 保存修改后的json文件def savejson(self, name):path = os.path.join(self.save_path, name)with open(path, 'w') as f:json.dump(self.json_file, f)# 圖片平移操作,修改相應標注點坐標def random_transform_json(self, trans_matrix):newShapes = [] x_offset, y_offset = trans_matrix[0:2, 2]for shape in self.shapes:tempdic = {"label": shape['label'], "group_id": shape['group_id'], "shape_type": "polygon", "flags": {}}newpoints = []for point in shape['points']:x = point[0] + x_offsety = point[1] + y_offset # x = width if x > width else x # y = height if y > height else ynewpoints.append([x, y])tempdic['points'] = newpointsnewShapes.append(tempdic)self.json_file['shapes'] = newShapes# 圖片翻轉操作,修改相應標注點坐標def random_flip_json(self, factor):newShapes = []for shape in self.shapes:tempdic = {"label": shape['label'], "group_id": shape['group_id'], "shape_type": "polygon", "flags": {}}newpoints = []for point in shape['points']:if factor == (-1.0, 1.0) :x = self.width - point[0]y = point[1]elif factor == (1.0, -1.0):x = point[0]y = self.height - point[1] newpoints.append([x, y])tempdic['points'] = newpointsnewShapes.append(tempdic)self.json_file['shapes'] = newShapes# 圖片旋轉操作,修改相應標注點坐標def random_rotate_json(self, angle):"""點point1繞點point2旋轉angle后的點======================================在平面坐標上,任意點P(x1,y1),繞一個坐標點Q(x2,y2)旋轉θ角度后,新的坐標設為(x, y)的計算公式:x= (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) + x2 ;y= (x1 - x2)*sin(θ) + (y1 - y2)*cos(θ) + y2 ;======================================將圖像坐標(x,y)轉換到平面坐標(x`,y`):x`=xy`=height-y:param point1::param point2: base point (基點):param angle: 旋轉角度,正:表示逆時針,負:表示順時"""newShapes = []cx, cy = self.width/2, self.height/2for shape in self.shapes:tempdic = {"label": shape['label'], "group_id": shape['group_id'], "shape_type": "polygon", "flags": {}}newpoints = []for point in shape['points']:x1 = point[0]y1 = point[1]# 將圖像坐標轉換到平面坐標y1 = self.height - y1cy = self.height - cy# # 逆時針 # x = (x1 - cx) * np.cos(angle) - (y1 - cy) * np.sin(angle) + cx # y = (x1 - cx) * np.sin(angle) + (y1 - cy) * np.cos(angle) + cy# 順時針x = (x1 - cx) * np.cos(angle) + (y1 - cy) * np.sin(angle) + cxy = -1*(x1 - cx) * np.sin(angle) + (y1 - cy) * np.cos(angle) + cy# 將平面坐標轉換到圖像坐標y = self.height - y newpoints.append([x, y])tempdic['points'] = newpointsnewShapes.append(tempdic)self.json_file['shapes'] = newShapes# 圖片縮放操作,修改相應標注點坐標def random_scale_json(self, factor):newShapes = []w, h = self.width/2, self.height/2for shape in self.shapes:tempdic = {"label": shape['label'], "group_id": shape['group_id'], "shape_type": "polygon", "flags": {}}newpoints = []for point in shape['points']: x = point[0] * factor[0] + w * (1-factor[0])y = point[1] * factor[1] + h * (1-factor[1]) newpoints.append([x, y])tempdic['points'] = newpointsnewShapes.append(tempdic)self.json_file['shapes'] = newShapes# 圖片錯切操作,修改相應標注點坐標def random_shear_json(self, factor):newShapes = []w, h = self.width/2, self.height/2for shape in self.shapes:tempdic = {"label": shape['label'], "group_id": shape['group_id'], "shape_type": "polygon", "flags": {}}newpoints = []for point in shape['points']: x = point[0] + point[1] * factor[0] - h * factor[0]y = point[1] + point[0] * factor[1] - w * factor[1] newpoints.append([x, y])tempdic['points'] = newpointsnewShapes.append(tempdic)self.json_file['shapes'] = newShapes# 設置對比度和亮度, 不需要修改標注文件def brightness_contrast_ratio_json(self):pass# 隨機噪聲, 不需要修改標注文件def random_noise_json(self):passif __name__=="__main__":daPic = DataAugment(debug=True)daJson = DataAugmen_Json(readPath='E:/Desktop/images', savePath='E:/Desktop/augment')img=cv2.imread("E:/Desktop/images/0001.jpg")# a = np.array([[1,0,0],[0,1,0],[0,0,1]]) # print(a[0:2, 2]) # min=np.array((0.1,0.1)) # print(min) # max=np.array((0.2,0.2)) # print(max) # print(np.random.uniform(min, max))# 平移測試 # trans_matrix, _, outimg=daPic.random_transform(img,(0.1,0.1),(0.2,0.2)) #(-0.3,-0.3),(0.3,0.3) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.random_transform_json(trans_matrix) # daJson.savejson('test.json')# 翻轉測試 # factor = (-1.0, 1.0) # 垂直: (1.0, -1.0) ; 水平:(-1.0, 1.0) # _, outimg = daPic.random_flip(img, factor) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.random_flip_json(factor) # daJson.savejson('test.json')# 旋轉變換測試 # angle, _, outimg = daPic.random_rotate(img, (10, 350)) # 在10°到350°之間順時針旋轉 # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.random_rotate_json(angle) # daJson.savejson('test.json')# 縮放變換測試 # factor, _, outimg = daPic.random_scale(img, (1.2, 1.2), (1.3,1.3)) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # print(f"factor is {factor}") # daJson.openjson('0001.json') # daJson.random_scale_json(factor) # daJson.savejson('test.json')# 隨機裁剪測試 # factor = (0.2,0.3) # _, _, outimg = daPic.random_shear(img, factor) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.random_shear_json(factor) # daJson.savejson('test.json')# 組合變換 # _, t1, _=daPic.random_transform(img, (-0.3,-0.3), (0.3,0.3)) # angle, t2, _=daPic.random_rotate(img, (10, 350)) # factor, t3, _=daPic.random_scale(img, (1.5,1.5), (1.7,1.7)) # tmp=np.linalg.multi_dot([t1,t2,t3]) # print("tmp:{}".format(tmp)) # out=daPic.apply(img, tmp)# 對比度和亮度測試 # outimg = daPic.brightness_contrast_ratio(img) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.brightness_contrast_ratio_json() # daJson.savejson('test.json')# 高斯噪聲測試 # outimg = daPic.random_noise(img) # cv2.imwrite('E:/Desktop/augment/0001.jpg', outimg) # daJson.openjson('0001.json') # daJson.random_noise_json() # daJson.savejson('test.json')?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的深度学习 之 数据增广(包含源码及注释文件更改)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 图片挑选程序,tkinte
- 下一篇: 将所有单个json标注文件合并成一个总的