博客:
人脸图像数据增强-CSDN博客
旋转:
范围在(-20°, 20°) 表示向左向右旋转
def rotate_image(image):
rows,cols,_ = image.shape
angle = random.randint(-20,20)
M = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1)
rotated_image = cv2.warpAffine(image,M,(cols,rows))
return rotated_image
翻转:
只水平翻转
def flip_image(image):
return cv2.flip(image, 1)
缩放:
范围是原来的(0.8,1.2)之间
def scale_image(image, scale_factor):
scale_factor = random.uniform(0.8, 1.2)
rows, cols, _ = image.shape
new_size = (int(cols * scale_factor), int(rows * scale_factor))
scaled_image = cv2.resize(image, new_size)
return scaled_image
改变亮度对比度
def adjust_brightness_contrast(image):
alpha = random.uniform(0.5, 1.5)
beta = random.randint(10, 50)
return cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
改变颜色
def color_distortion(image, color_matrix):
# color_matrix = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]])
return cv2.transform(image, color_matrix)
加椒盐噪声
def salt_and_pepper_noise(image, salt_prob=0.01, pepper_prob=0.01):
noisy_image = image.copy()
total_pixels = image.size
num_salt = int(total_pixels * salt_prob)
salt_coords = [np.random.randint(0, i-1, num_salt) for i in image.shape]
noisy_image[salt_coords[0], salt_coords[1]] = 255
num_pepper = int(total_pixels * pepper_prob)
pepper_coords = [np.random.randint(0, i-1, num_pepper) for i in image.shape]
noisy_image[pepper_coords[0], pepper_coords[1]] = 0
return noisy_image
直方图均衡化
def equalizeHist_image(image):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return cv2.equalizeHist(image)
自适应直方图均衡化
def clahe_image(image):
b, g, r = cv2.split(image)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(5, 5))
clahe_b = clahe.apply(b)
clahe_g = clahe.apply(g)
clahe_r = clahe.apply(r)
return cv2.merge((clahe_b, clahe_g, clahe_r))
油画与非真实感渲染
def detailEnhance_image(image):
return cv2.detailEnhance(image, None, 20, 0.8)
局部区域亮度调整
def illumination_change(image):
img_zero = np.zeros(image.shape, dtype=np.uint8)
return cv2.illuminationChange(image, mask=img_zero, alpha=0.2, beta=0.4)
人脸中心点加强或者变暗
def enhance_reduce(image, strength=100):
# strength > 0 enhance, strength < 0 reduce
x, y, _ = image.shape
radius = np.random.randint(10, int(min(x, y)), 1)
pos_x = np.random.randint(0, (min(x, y)-radius), 1)
pos_y = np.random.randint(0, (min(x, y)-radius), 1)
pos_x = int(pos_x[0])
pos_y = int(pos_y[0])
radius = int(radius[0])
for j in range(pos_y-radius, pos_y+radius):
for i in range(pos_x-radius, pos_x+radius):
distance = math.pow((pos_x-i), 2) + math.pow((pos_y-j), 2)
distance = np.sqrt(distance)
if distance < radius:
result = 1 - distance/radius
result = result*strength
if strength > 0:
image[i, j, 0] = min((image[i, j, 0]+result), 255)
image[i, j, 1] = min((image[i, j, 1]+result), 255)
image[i, j, 2] = min((image[i, j, 2]+result), 255)
else:
image[i, j, 0] = max((image[i, j, 0]+result), 0)
image[i, j, 1] = max((image[i, j, 1]+result), 0)
image[i, j, 2] = max((image[i, j, 2]+result), 0)
image = image.astype(np.uint8)
return image
遮盖
def mask(image, low=10, high=50):
x, y, _ = image.shape
mask_size = np.random.randint(low, high, 1)
pos_x = np.random.randint(low, (min(x, y)-high), 1)
pos_y = np.random.randint(low, (min(x, y)-high), 1)
pos_x = int(pos_x[0])
pos_y = int(pos_y[0])
mask_size = int(mask_size[0])
image[pos_x:pos_x+mask_size, pos_y:pos_y+mask_size] = 0
return image
合并总类:
import os
import cv2
import sys
import json
import math
import random
import numpy as np
class ImageAugment:
def rotate_image(self, image):
rows, cols, _ = image.shape
angle = random.randint(-20, 20)
M = cv2.getRotationMatrix2D((cols/2, rows/2), angle, 1)
rotated_image = cv2.warpAffine(image, M, (cols, rows))
return rotated_image
def flip_image(self, image):
return cv2.flip(image, 1)
def scale_image(self, image, scale_factor):
scale_factor = random.uniform(0.8, 1.2)
rows, cols, _ = image.shape
new_size = (int(cols * scale_factor), int(rows * scale_factor))
scaled_image = cv2.resize(image, new_size)
scaled_image = cv2.resize(scaled_image, (112, 112))
return scaled_image
def adjust_brightness_contrast(self, image):
alpha = random.uniform(0.5, 1.5)
beta = random.randint(10, 50)
return cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
def color_distortion(self, image, color_matrix):
return cv2.transform(image, color_matrix)
def salt_and_pepper_noise(self, image, salt_prob=0.01, pepper_prob=0.01):
noisy_image = image.copy()
total_pixels = image.size
num_salt = int(total_pixels * salt_prob)
salt_coords = [np.random.randint(0, i-1, num_salt) for i in image.shape]
noisy_image[salt_coords[0], salt_coords[1]] = 255
num_pepper = int(total_pixels * pepper_prob)
pepper_coords = [np.random.randint(0, i-1, num_pepper) for i in image.shape]
noisy_image[pepper_coords[0], pepper_coords[1]] = 0
return noisy_image
def equalizeHist_image(self, image):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return cv2.equalizeHist(image)
def clahe_image(self, image):
b, g, r = cv2.split(image)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(5, 5))
clahe_b = clahe.apply(b)
clahe_g = clahe.apply(g)
clahe_r = clahe.apply(r)
return cv2.merge((clahe_b, clahe_g, clahe_r))
def detailEnhance_image(self, image):
return cv2.detailEnhance(image, None, 20, 0.8)
def illumination_change(self, image):
img_zero = np.zeros(image.shape, dtype=np.uint8)
return cv2.illuminationChange(image, mask=img_zero, alpha=0.2, beta=0.4)
def enhance_reduce(self, image, strength=100):
# strength > 0 enhance, strength < 0 reduce
x, y, _ = image.shape
radius = np.random.randint(10, int(min(x, y)), 1)
pos_x = np.random.randint(0, (min(x, y)-radius), 1)
pos_y = np.random.randint(0, (min(x, y)-radius), 1)
pos_x = int(pos_x[0])
pos_y = int(pos_y[0])
radius = int(radius[0])
for j in range(pos_y-radius, pos_y+radius):
for i in range(pos_x-radius, pos_x+radius):
distance = math.pow((pos_x-i), 2) + math.pow((pos_y-j), 2)
distance = np.sqrt(distance)
if distance < radius:
result = 1 - distance/radius
result = result*strength
if strength > 0:
image[i, j, 0] = min((image[i, j, 0]+result), 255)
image[i, j, 1] = min((image[i, j, 1]+result), 255)
image[i, j, 2] = min((image[i, j, 2]+result), 255)
else:
image[i, j, 0] = max((image[i, j, 0]+result), 0)
image[i, j, 1] = max((image[i, j, 1]+result), 0)
image[i, j, 2] = max((image[i, j, 2]+result), 0)
image = image.astype(np.uint8)
return image
def mask(self, image, low=10, high=50):
x, y, _ = image.shape
mask_size = np.random.randint(low, high, 1)
pos_x = np.random.randint(low, (min(x, y)-high), 1)
pos_y = np.random.randint(low, (min(x, y)-high), 1)
pos_x = int(pos_x[0])
pos_y = int(pos_y[0])
mask_size = int(mask_size[0])
image[pos_x:pos_x+mask_size, pos_y:pos_y+mask_size] = 0
return image
if __name__ == '__main__':
ia = ImageAugment()
image_path = sys.argv[1]
image = cv2.imread(image_path)
rotated_image = ia.rotate_image(image)
flipped_image = ia.flip_image(image)
scaled_image = ia.scale_image(image, scale_factor=1.2)
adjusted_image = ia.adjust_brightness_contrast(image)
color_matrix = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]])
color_distorted_image = ia.color_distortion(image, color_matrix)
salt_image = ia.salt_and_pepper_noise(image)
equalize_image = ia.equalizeHist_image(image)
clahe_image = ia.clahe_image(image)
detailenhance_image = ia.detailEnhance_image(image)
illumination_image = ia.illumination_change(image)
enhance_image = ia.enhance_reduce(image, 100)
reduce_image = ia.enhance_reduce(image, -100)
mask_image = ia.mask(image)
# save
cv2.imwrite('rotated.jpg', rotated_image)
cv2.imwrite('flipped.jpg', flipped_image)
cv2.imwrite('scaled.jpg', scaled_image)
cv2.imwrite('adjusted.jpg', adjusted_image)
cv2.imwrite('colorDistorted.jpg', color_distorted_image)
cv2.imwrite('salt.jpg', salt_image)
cv2.imwrite('equalize.jpg', equalize_image)
cv2.imwrite('clahe.jpg', clahe_image)
cv2.imwrite('detailenhance.jpg', detailenhance_image)
cv2.imwrite('illumination.jpg', illumination_image)
cv2.imwrite('enhance.jpg', enhance_image)
cv2.imwrite('reduce.jpg', reduce_image)
cv2.imwrite('mask.jpg', mask_image)
数据增强
import cv2
import os
from PIL import Image
import random
# 去雾
def opt_img(img_path):
img = cv2.imread(img_path, 0)
clahe = cv2.createCLAHE(tileGridSize=(2, 2), clipLimit=3.0)
img2 = clahe.apply(img)
return img2
# cv2.imwrite(img_path, img2)
path = r"D:\Datasets\arthrosis"
out_path = r"D:\Datasets\arthrosis_improve2"
if not os.path.exists(out_path):
os.makedirs(out_path)
for root, _, file_names in os.walk(path):
for img in file_names:
image_path = os.path.join(root, img)
images = opt_img(image_path)
# 构建新文件路径
rel_path = os.path.relpath(image_path, path)
new_path = os.path.join(out_path, rel_path)
# 确保新路径存在
os.makedirs(os.path.dirname(new_path), exist_ok=True)
cv2.imwrite(new_path, images)
exit()
path = "img"
for i in os.listdir(path):
path2 = os.path.join(path, i)
opt_img(path2)
# 一张变5张
def img_rotate(img_path, num):
img = Image.open(img_path)
for i in range(num):
rotate = random.randint(-60, 60)
dst = img.rotate(rotate)
# return dst
# img/DIP_9116.png
# 使用os.path.splitext来获取文件名和扩展名
file_name, post = os.path.splitext(img_path)
# 在文件名后添加角度和扩展名
dst.save(f"{file_name}_{i}{post}")
# img_rotate("img/DIP_9116.png", 5)
path = r"D:\Datasets\arthrosis_improve2"
for root, _, file_names in os.walk(path):
for img in file_names:
image_path = os.path.join(root, img)
img_rotate(image_path, 10)
exit()
拆分数据集
def save_file(list, path, name):
myFile = os.path.join(path, name)
if os.path.exists(myFile):
os.remove(myFile)
with open(myFile, 'w') as f:
f.writelines(list)
pic_path_folder = r'D:\Datasets\arthrosis_improve2'
print('开始切分数据集')
for pic_folder in os.listdir(pic_path_folder):
data_path = os.path.join(pic_path_folder, pic_folder)
num_lass = len(os.listdir(data_path))
train_list = []
val_list = []
train_ratio = 0.9
for folder in os.listdir(data_path):
path = os.path.join(data_path, folder)
if os.path.isfile(path):
continue
img_lists = os.listdir(path)
train_nums = len(img_lists) * train_ratio
random.shuffle(img_lists)
for index, img in enumerate(img_lists):
if index < train_nums:
train_list.append(os.path.join(path, img) + ' ' + str(int(folder) - 1) + '\n')
else:
val_list.append(os.path.join(path, img) + ' ' + str(int(folder) - 1) + '\n')
random.shuffle(train_list)
random.shuffle(val_list)
save_file(train_list, data_path, "train.txt")
save_file(val_list, data_path, "val.txt")
print('完成切分数据集')
def img_resize(w1, src_path, out_path):
_, last_load = os.path.splitext(src_path)
if last_load.lower() not in ('.png', '.jpg', '.jpeg'):
print(f"地址为:{src_path}")
return
src = Image.open(src_path)
bg = Image.new("RGB", (w1, w1), (0, 0, 0))
value = max(src.size)
scaler = w1 / value
w = int(src.size[0] * scaler)
h = int(src.size[1] * scaler)
img = src.resize((w, h))
if img.size[1] > img.size[0]:
bg.paste(img, ((w1 - w) // 2, 0))
else:
bg.paste(img, (0, (w1 - h) // 2))
out_dir = os.path.dirname(out_path)
os.makedirs(out_dir, exist_ok=True)
bg.save(out_path, format="PNG")
w1 = 224
input_path = r"D:\Datasets\arthrosis_improve"
output_path = r"D:\Datasets\resize_arthrosis_improve"
for root, _, file_names in os.walk(input_path):
for img in file_names:
image_path = os.path.join(root, img)
out_path = os.path.join(output_path, os.path.relpath(image_path, input_path))
img_resize(w1, image_path, out_path)
if file_names[-3:] != "png":
continue