行人重识别数据集的天气数据增强——雨天
在行人重识别中数据增强方式很多:随机翻转、随机裁剪、RandomErasing等等。
关于雨天天气我也认为是一种数据增强方式,能够有效扩充数据集,特别是针对Market-1501这样的小样本数据集。
但是我在尝试数据集上的数据增强后,发现结果并不太满意,我将这一最初版本公开,希望看到我博客的机器学习或深度学习,最好是REID方向的朋友能给我一些建议。
代码中我已经加上了备注,需要用到OpenCV,可以通过参数调节雨滴的大小
class rainAug(object):
def __init__(self, value=300, length=5, angle=-30, w=1, beta=0.6):
self.value = value
self.length = length
self.angle = angle
self.w = w
self.beta = beta
def __call__(self, img):
#img = cv2.imread(str(img))
img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
noise = np.random.uniform(0, 256, img.shape[0:2])
# 控制噪声水平,取浮点数,只保留最大的一部分作为噪声
v = self.value * 0.01
noise[np.where(noise < (256 - v))] = 0
# 噪声做初次模糊
k = np.array([[0, 0.1, 0],
[0.1, 8, 0.1],
[0, 0.1, 0]])
noise = cv2.filter2D(noise, -1, k)
# 可以输出噪声看看
# noise = torch.Tensor(noise)
trans = cv2.getRotationMatrix2D((self.length / 2, self.length / 2),
self.angle - 45, 1 - self.length / 100.0)
dig = np.diag(np.ones(self.length)) # 生成对焦矩阵
k = cv2.warpAffine(dig, trans, (self.length, self.length)) # 生成模糊核
k = cv2.GaussianBlur(k, (self.w, self.w), 0) # 高斯模糊这个旋转后的对角核,使得雨有宽度
# k = k / length #是否归一化
blurred = cv2.filter2D(noise, -1, k) # 用刚刚得到的旋转后的核,进行滤波
# 转换到0-255区间
cv2.normalize(blurred, blurred, 0, 255, cv2.NORM_MINMAX)
blurred = np.array(blurred, dtype=np.uint8)
# 这里由于对角阵自带45度的倾斜,逆时针为正,所以加了-45度的误差,保证开始为正
trans = cv2.getRotationMatrix2D((self.length / 2, self.length / 2),
self.angle - 45, 1 - self.length / 100.0)
dig = np.diag(np.ones(self.length)) # 生成对焦矩阵
k = cv2.warpAffine(dig, trans, (self.length, self.length)) # 生成模糊核
k = cv2.GaussianBlur(k, (self.w, self.w), 0) # 高斯模糊这个旋转后的对角核,使得雨有宽度
# k = k / length #是否归一化
blurred = cv2.filter2D(noise, -1, k) # 用刚刚得到的旋转后的核,进行滤波
# 转换到0-255区间
cv2.normalize(blurred, blurred, 0, 255, cv2.NORM_MINMAX)
blurred = np.array(blurred, dtype=np.uint8)
# 输入雨滴噪声和图像
# beta = 0.8 #results weight
# 显示下雨效果
rain = blurred
# expand dimensin
# 将二维雨噪声扩张为三维单通道
# 并与图像合成在一起形成带有alpha通道的4通道图像
rain = np.expand_dims(rain, 2)
rain_effect = np.concatenate((img, rain), axis=2) # add alpha channel
rain_result = img.copy() # 拷贝一个掩膜
rain = np.array(rain, dtype=np.float32) # 数据类型变为浮点数,后面要叠加,防止数组越界要用32位
rain_result[:, :, 0] = rain_result[:, :, 0] * (255 - rain[:, :, 0]) / 255.0 + self.beta * rain[:, :, 0]
rain_result[:, :, 1] = rain_result[:, :, 1] * (255 - rain[:, :, 0]) / 255 + self.beta * rain[:, :, 0]
rain_result[:, :, 2] = rain_result[:, :, 2] * (255 - rain[:, :, 0]) / 255 + self.beta * rain[:, :, 0]
# 对每个通道先保留雨滴噪声图对应的黑色(透明)部分,再叠加白色的雨滴噪声部分(有比例因子)
return rain_result
实际效果(撑伞的女人)
实际效果(数据集)
Q.E.D.