# 深度学习：图像扩增方法

## 图像大小变化

import cv2
import numpy as np
def preprocess(img, imgsize, jitter, random_placing=False):
"""
Image preprocess for yolo input
Pad the shorter side of the image and resize to (imgsize, imgsize)
Args:
img (numpy.ndarray): input image whose shape is :math:(H, W, C).
Values range from 0 to 255.
imgsize (int): target image size after pre-processing
jitter (float): amplitude of jitter for resizing
random_placing (bool): if True, place the image at random position

Returns:
img (numpy.ndarray): input image whose shape is :math:(C, imgsize, imgsize).
Values range from 0 to 1.
info_img : tuple of h, w, nh, nw, dx, dy.
h, w (int): original shape of the image
nh, nw (int): shape of the resized image without padding
"""
h, w, _ = img.shape
img = img[:, :, ::-1]
assert img is not None
#尺寸大小的随机抖动，jitter越大，长宽的的变化越大
if jitter > 0:
dw = jitter * w
dh = jitter * h
new_ar = (w + np.random.uniform(low=-dw, high=dw))\
/ (h + np.random.uniform(low=-dh, high=dh))
else:
new_ar = w / h

if new_ar < 1:
nh = imgsize
nw = nh * new_ar
else:
nw = imgsize
nh = nw / new_ar
nw, nh = int(nw), int(nh)
#图像填充位置的随机性
if random_placing:
dx = int(np.random.uniform(imgsize - nw))
dy = int(np.random.uniform(imgsize - nh))
else:
dx = (imgsize - nw) // 2
dy = (imgsize - nh) // 2

img = cv2.resize(img, (nw, nh))
sized = np.ones((imgsize, imgsize, 3), dtype=np.uint8) * 127
sized[dy:dy+nh, dx:dx+nw, :] = img

info_img = (h, w, nh, nw, dx, dy)
return sized, info_img

jitter=0
andom_placing=False
img_size=416
print(img.shape)
sized, info_img=preprocess(img, img_size, jitter=jitter,random_placing=andom_placing)
print(sized.shape)
sized=sized[:,:,::-1]
cv2.imshow('imgs',img)
cv2.imshow('img',sized)
cv2.waitKey()



#jitter为尺寸大小的随机抖动，jitter参数越大，长宽的的变化越大。

andom_placing为图像位置，上面图像为andom_placing=False，因此在两侧均匀填充空白。

## 图像翻转

def random_flip(img, y_random=False, x_random=False,
return_param=False, copy=False):

y_flip, x_flip = False, False
if y_random:
y_flip = random.choice([True, False])
if x_random:
x_flip = random.choice([True, False])

if y_flip:
img = img[:, ::-1, :]
if x_flip:
img = img[:, :, ::-1]

if copy:
img = img.copy()

if return_param:
return img, {'y_flip': y_flip, 'x_flip': x_flip}
else:
return img


def flip_bbox(bbox, size, y_flip=False, x_flip=False):

H, W = size
bbox = bbox.copy()
if y_flip:
y_max = H - bbox[:, 0]
y_min = H - bbox[:, 2]
bbox[:, 0] = y_min
bbox[:, 2] = y_max
if x_flip:
x_max = W - bbox[:, 1]
x_min = W - bbox[:, 3]
bbox[:, 1] = x_min
bbox[:, 3] = x_max
return bbox


## Random Distortion

def random_distort(img, hue, saturation, exposure):
"""
perform random distortion in the HSV color space.
Args:
img (numpy.ndarray): input image whose shape is :math:(H, W, C).
Values range from 0 to 255.
hue (float): random distortion parameter.
saturation (float): random distortion parameter.
exposure (float): random distortion parameter.
Returns:
img (numpy.ndarray)
"""
#hue 调整色彩度，越大色彩度变化的程度越大；sat 调整对比度，越大对比度变化越大； exp调整亮度
dhue = np.random.uniform(low=-hue, high=hue)
dsat = rand_scale(saturation)
dexp = rand_scale(exposure)

img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
img = np.asarray(img, dtype=np.float32) / 255.
img[:, :, 1] *= dsat
img[:, :, 2] *= dexp
H = img[:, :, 0] + dhue

if dhue > 0:
H[H > 1.0] -= 1.0
else:
H[H < 0.0] += 1.0

img[:, :, 0] = H
img = (img * 255).clip(0, 255).astype(np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
img = np.asarray(img, dtype=np.float32)

return img

def rand_scale(s):
#乘或者除一定倍数
"""
calculate
random scaling factor
Args:
s (float): range of the random scale.
Returns:
random scaling factor (float) whose range is
from 1 / s to s .
"""
scale = np.random.uniform(low=1, high=s)
if np.random.rand() > 0.5:
return scale
return 1 / scale
hue=0.8
saturation=1.5
exposure=1.0
img2 = random_distort(sized, hue, saturation, exposure)
sized=sized[:,:,::-1]
img2=img2[:,:,::-1]
cv2.imwrite('img_or.jpg',sized)
cv2.imwrite('img_dis.jpg',img2)