Python 数据扩充(亮度、翻转、噪声)
因为训练模型的数据集很少,需要进行扩充,主要使用了一些单样本扩充方法,例如亮度变换、水平垂直翻转、增加图像噪声
下面对自己用到的一些代码进行整理,方便后续查看与使用
环境说明
- opencv:opencv_python 4.5.5.64
- numpy:1.19.2
下面的方法统一利用到的变量:
# 当前数据集图片格式
file_format = ".png"
# 左右翻转文件名附加字符
LR = "_lr"
# 上下翻转文件名附加字符
TB = "_tb"
# 变亮
BR = "_br"
# 椒盐噪声
SA = "_sa"
# 高斯噪声
GA = "_ga"
# 翻转
FZ = "fz_"
# 获取到文件的文件名
def getImageName(path):
return os.path.basename(path)
亮度
这里主要用了两种,分别是亮度变亮 亮度变暗 ,实现原理都是一样的
主要用到两个方法:
- cv2.imread:python opencv cv2.imread
- cv2.imwrite:python opencv cv2.imwrite
- np.clip:该函数的作用是数限定到范围a_min和a_max中
亮度:
import cv2
# 亮度变亮
# img_list:所有的图片地址,数组 例如:[xxx/xxx1.png , xxx/xxx2.png]
# base_path:原图片所在的文件目录
# save_base_path:变量后保存的文件目录
# percetage:亮度,变亮设置为大于1的数字,变暗设置为小于1数字
def brighter(img_list, base_path, save_base_path, percetage=1.2):
for i in range(len(img_list)):
# 原图片的地址
img_path = img_list[i]
# 保存的文件地址,以前文件名称为example.png 下面保存为 example_br.png
image_save_full_path = save_base_path + getImageName(img_path).split(file_format)[0] + BR + file_format
pri_image = cv2.imread(img_path, -1)
image_copy = pri_image.copy()
w = pri_image.shape[1]
h = pri_image.shape[0]
# get brighter 根据像素将其变量
for xi in range(0, w):
for xj in range(0, h):
image_copy[xj, xi, 0] = np.clip(int(pri_image[xj, xi, 0] * percetage), a_max=255, a_min=0)
image_copy[xj, xi, 1] = np.clip(int(pri_image[xj, xi, 1] * percetage), a_max=255, a_min=0)
image_copy[xj, xi, 2] = np.clip(int(pri_image[xj, xi, 2] * percetage), a_max=255, a_min=0)
# 保存
cv2.imwrite(image_save_full_path, image_copy)
使用后示例:(变亮)
翻转
这里主要用了五种,分别是 上下翻转 左右翻转 90度翻转 180度翻转 270度翻转 ,实现原理都是一样的
主要用到两个方法:
- PIL.Image.open:打开文件
- PIL.Image.Image.transpose:进行翻转操作
FLIP_LEFT_RIGHT = 0
FLIP_TOP_BOTTOM = 1
ROTATE_90 = 2
ROTATE_180 = 3
ROTATE_270 = 4
from PIL import Image
# 左右翻转
# img_list:所有的图片地址,数组 例如:[xxx/xxx1.png , xxx/xxx2.png]
# save_base_path:变量后保存的文件目录
def leftRightFz(img_list, save_base_path):
# 1.遍历图片
for i in range(len(img_list)):
# 图片路径
img_path = img_list[i]
# 打开图片 PIL.Image.Image对象
pri_image = Image.open(img_path)
# 保存的文件地址,以前文件名称为example.png 下面保存为 example_lr.png
image_save_full_path = save_base_path + getImageName(img_path).split(file_format)[0] + LR + file_format
# 左右镜面翻转FLIP_LEFT_RIGHT
pri_image.transpose(Image.FLIP_LEFT_RIGHT).save(image_save_full_path)
# 这里根据翻转的不同,输入不同的值
FLIP_LEFT_RIGHT = 0 # 左右翻转
FLIP_TOP_BOTTOM = 1 # **上下翻转
ROTATE_90 = 2 # 90度翻转
ROTATE_180 = 3 # 180度翻转
ROTATE_270 = 4 # 270度翻转
使用后示例:(左右翻转)
噪声
这里用到了两种噪声,分别:
- 高斯噪声,指服从正态分布的一类噪声,通常RGB图像显现比较明显
- 椒盐噪声,指黑白相间的亮暗点噪声。通常灰度图中比较明显
椒盐噪声
主要用到两个方法:
- cv2.imread:python opencv cv2.imread
- cv2.imwrite:python opencv cv2.imwrite
# 椒盐噪声
# img_list:所有的图片地址,数组 例如:[xxx/xxx1.png , xxx/xxx2.png]
# base_path:原图片所在的文件目录
# save_base_path:变量后保存的文件目录
# percetage:噪声情况
def SaltAndPepper(img_list, base_path, save_base_path, percetage=0.3):
for i in range(len(img_list)):
img_path = img_list[i]
# 保存的文件地址,以前文件名称为example.png 下面保存为 example_sa.png
image_save_full_path = save_base_path + getImageName(img_path).split(file_format)[0] + SA + file_format
pri_image = cv2.imread(img_path)
image_copy = pri_image.copy()
w = pri_image.shape[1]
h = pri_image.shape[0]
# noise_num
noise_num = int(percetage * w * h)
for i in range(noise_num):
randR = np.random.randint(0, h - 1)
randG = np.random.randint(0, w - 1)
randB = np.random.randint(0, 3)
# 随机对图片加上黑白点
if np.random.randint(0, 1) == 0:
image_copy[randR, randG, randB] = 0
else:
image_copy[randR, randG, randB] = 255
cv2.imwrite(image_save_full_path, image_copy)
示例:
高斯噪声
主要用到两个方法:
- cv2.imread:python opencv cv2.imread
- cv2.imwrite:python opencv cv2.imwrite
- np.random.randn:正态分布矩阵生成
- np.zeros:初始化一个矩阵,值为0
from PIL import Image
import numpy as np
import cv2
# 高斯噪声
# img_list:所有的图片地址,数组 例如:[xxx/xxx1.png , xxx/xxx2.png]
# base_path:原图片所在的文件目录
# save_base_path:变量后保存的文件目录
# percetage:噪声情况
def GaussianNoise(img_list, base_path, save_base_path, percetage=20):
for i in range(len(img_list)):
img_path = img_list[i]
# 保存的文件地址,以前文件名称为example.png 下面保存为 example_ga.png
image_save_full_path = save_base_path + getImageName(img_path).split(file_format)[0] + GA + file_format
pri_image = cv2.imread(img_path)
image_copy = pri_image.copy()
w = pri_image.shape[1]
h = pri_image.shape[0]
# 正太分布
noise = np.random.randn(h, w) * percetage
# 一个与图片w,h大小的0矩阵
noisy_img = np.zeros(image_copy.shape, np.float64)
if len(image_copy.shape) == 2:
noisy_img = image_copy + noise
else: # 增加噪声
noisy_img[:, :, 0] = image_copy[:, :, 0] + noise
noisy_img[:, :, 1] = image_copy[:, :, 1] + noise
noisy_img[:, :, 2] = image_copy[:, :, 2] + noise
cv2.imwrite(image_save_full_path, noisy_img)
示例: