图像增强库Albumentations
1.大体的认识、有用没用的bb
github:https://github.com/albumentations-team/albumentations
例子:https://github.com/albumentations-team/albumentations_examples
特点:分类、目标检测、分割等任务都支持增强,与pytorch等框架都兼容,是Pytorch生态的一部分。
1.1 为什么图像增强能提升深度学习的性能?
DNN需要大量数据避免过拟合,数据成本很高:1.训练数据要标注,昂贵;2.有的训练数据本身就很难收集,法律限制等。
图像增强是:根据已有数据,创造新的训练数据的方法。就是对原图进行调整,如裁剪,亮度变化等。例子:
1.2 为什么需要一个单独的图像增强的库?
图像增强看似简单,基本的转换有:mirroring,cropping,改变亮度、分辨率等。很多库都能实现,Pillow与cv2等,但是有很多限制.
1.可以改变label
如,在分割、目标检测与关键点检测的任务里,label需要同image一起进行相应的转化的。torchvision应该是没有现成的实现的,Pillow与cv2应该需要你自己实现,就很复杂的!
对分类任务你只要改变image即可,label是不变的。
但是对分割,旋转了之后,对应的mask的label也要对应改变!
目标检测也一样,框的位置,大小在image调整后,都要进行相应的进行调整。
2.可设置概率与强度(torchvision也可以)
通常数据集大,增强的概率10-30%,强度不需要太大;数据集小,概率40-50%,加大强度。
3.明确的增强进行的pipeline(torchvision也可以)
就是Compose
import albumentations as A
transform = A.Compose([
A.RandomCrop(512, 512),
A.RandomBrightnessContrast(p=0.3),
A.HorizontalFlip(p=0.5),
])
4.严格测试
自己实现的pipeline容易生产垃圾数据,又不会报错。库将操作集成起来,降低风险。
1.3 为什么用Albumentations
1.单一的接口应对多种视觉问题:分类、目标检测、分割、关键点;
2.在工业、学术、竞赛中应用,效果得到了验证;
3.优化了最快的速度与最好的性能;
4.增强方式多,60多种;
2 分类任务的增强
2.1 基础
增强4步走:
1.引包读图,albumentations和OpenCV;
2.定义pipeline;
3.读图;
4.让image通过pipeline,得到增强后的图。
1.引包
import albumentations as A
import cv2
读图通常用cv2。
2.pipeline
创建Compose类,接受一个list的增强操作作为Compose的参数,得到一个转换函数transform
transform = Compose([
A.RandomCrop(width=256, height=256),
A.HorizontalFlip(p=0.5),
A.RandomBrightnessContrast(p=0.2),
])
可支持的全部操作看github。
效果在这看:https://albumentations-demo.herokuapp.com
创建一个augmentation就是把一个augmentation class实例化并传入参数。p是概率。
3.读图
pipeline需要的输入是NumPy array,channel是RGB。
image = cv2.imread("/path/to/image.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
历史原因,cv读到的图试试BGR,需要转化。
如果用Pillow
from PIL import Image
import numpy as np
pillow_image = Image.open("image.jpg") # 对象
image = np.array(pillow_image)
4.过pipeline
调研transform函数,返回的是个dict,只有一个key就是image,value就是增强后的图。
transformed = transform(image=image)
transformed_image = transformed["image"]
因为概率不同,相同的pipeline会得到不同的结果。
2.2 example1–定义1个简单的图像增强pipeline
1.引包
import albumentations as A
import random
import cv2
import matplotlib.pyplot as plt
2.定义可视化函数
def visualize(image):
plt.figure(figsize=(10, 10))
plt.axis('off')
plt.imshow(image)
3.读取,BGR转为RBG空间
原图
历史原因,cv2读进来的是BGR,而Albumentations用的是RGB,所以要转换。
反正记得转就完事了,不然色彩空间会有问题。
image = cv2.imread('./data/input/ButterflyClassification/image/12.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
但是注意,如果后面接的是pytorch的处理,那就转换完了就行了。但是如果用cv2.imwrite存储的话,还是用BGR的方式存,所以转为RGB处理后,直接用cv2.imwrite存会有问题。
所以用cv2存Albumentations的结果的话,就不用这步转换,直接进行后续即可。
4.定义单一的增强
水平翻转
transform = A.HorizontalFlip(p=1.0)
augmented_image = transform(image=image)['image']
save_path = '/data/zhaobo/tmp/test.jpg'
cv2.imwrite(save_path, augmented_image)
注意,transform函数的结果是个dict,虽然只有一个key image
{'image':array([[[...]]], dtype:uint8)}
旋转
transform = A.ShiftScaleRotate(p=1.0)
训练的时候p=0.5,都是自己定的
5.Compose定义一组pipeline
这个就是自己组合
官方例子
transform = A.Compose([
A.CLAHE(),
A.RandomRotate90(),
A.Transpose(),
A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.50, rotate_limit=45, p=.75),
A.Blur(blur_limit=3),
A.OpticalDistortion(),
A.GridDistortion(),
A.HueSaturationValue(),
])
或
transform = A.Compose([
A.RandomRotate90(),
A.Flip(),
A.Transpose(),
A.OneOf([
A.IAAAdditiveGaussianNoise(),
A.GaussNoise(),
], p=0.2),
A.OneOf([
A.MotionBlur(p=.2),
A.MedianBlur(blur_limit=3, p=0.1),
A.Blur(blur_limit=3, p=0.1),
], p=0.2),
A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.2),
A.OneOf([
A.OpticalDistortion(p=0.3),
A.GridDistortion(p=.1),
A.IAAPiecewiseAffine(p=0.3),
], p=0.2),
A.OneOf([
A.CLAHE(clip_limit=2),
A.IAASharpen(),
A.IAAEmboss(),
A.RandomBrightnessContrast(),
], p=0.3),
A.HueSaturationValue(p=0.3),
])
kaggle上cvpr 细粒度树叶的大佬的
from albumentations.pytorch import ToTensorV2
transform = A.Compose([
A.RandomResizedCrop(height=SIZE, width=SIZE, p=1.0),
A.Flip(),
A.ShiftScaleRotate(rotate_limit=1.0, p=0.8),
# Pixels
A.OneOf([
A.IAAEmboss(p=1.0),
A.IAASharpen(p=1.0),
A.Blur(p=1.0),
], p=0.5),
# Affine
A.OneOf([
A.ElasticTransform(p=1.0),
A.IAAPiecewiseAffine(p=1.0)
], p=0.5),
# 这两个训练时加上
# A.Normalize(p=1.0),
# ToTensorV2(p=1.0),
])
测试时
transforms_valid = A.Compose([
A.Resize(height=SIZE, width=SIZE, p=1.0),
A.Normalize(p=1.0),
ToTensorV2(p=1.0),
])
感觉这个增强的有点过分:
甚至直接没了
感觉还是传统的翻转,亮度啥的;或者把大变动的概率调低点。不然容易学错。少搞一点这样的或许能提高泛化能力。
2.3 增强非8bit的图像
增强16bit的tiff,用于卫星图片。下述技术用于所有非8bit的例子,如24bit与32bit等
todo
https://albumentations.ai/docs/examples/example_16_bit_tiff/
2.4 Albumentation的天气增强
增加雨雪效果。
1.随机下雨
transform = A.Compose(
[A.RandomRain(brightness_coefficient=0.9, drop_width=1, blur_value=5, p=1)],
)
2.随机下雪
transform = A.Compose(
[A.RandomSnow(brightness_coeff=2.5, snow_point_lower=0.3, snow_point_upper=0.5, p=1)]
)
3.随机逆光
transform = A.Compose(
[A.RandomSunFlare(flare_roi=(0, 0, 1, 0.5), angle_lower=0.5, p=1)],
)
4.随机阴影
transform = A.Compose(
[A.RandomShadow(num_shadows_lower=1, num_shadows_upper=1, shadow_dimension=5, shadow_roi=(0, 0.5, 1, 1), p=1)],
)
5.随机雾
transform = A.Compose(
[A.RandomFog(fog_coef_lower=0.7, fog_coef_upper=0.8, alpha_coef=0.1, p=1)],
)
2.5 比较cool的实际任务应用
todo
https://albumentations.ai/docs/examples/showcase/
本文地址:https://blog.csdn.net/rOtk1992/article/details/110443276