数据扩充(data augmentation),又名 数据增强 / 数据增广。其本质即:缺少海量数据时,为了保证模型的有效训练,一分钱掰成两半花。
为什么需要数据增强:
一般而言,比较成功的神经网络需要大量的参数,许许多多的神经网路的参数都是数以百万计,而使得这些参数可以正确工作则需要大量的数据进行训练,而实际情况中数据并没有我们想象中的那么多
数据增强的作用:
- 数据增强让有限的数据产生更多的数据,增加训练样本的数量以及多样性(噪声数据),增加噪声数据,提升模型鲁棒性
- 随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。例如,我们可以对图像进行不同方式的裁剪,让物体以不同的实例出现在图像的不同位置,这同样能够降低模型对目标位置的敏感性。例如,我们也可以调整亮度、对比度、饱和度和色调 等因素来降低模型对 色彩的敏感度。
如何获得大量的数据:
- 获得新的数据,这种方法比较麻烦,需要大量的成本,
- 对数据进行增强,即利用已有的数据比如翻转、平移或旋转,创造出更多的数据,来使得神经网络具有更好的泛化效果。数据扩充方法包括:镜像、旋转、尺度变换、随机抠取、色彩抖动
1、镜像
1、remap函数
void remap(InputArray src,OutputArray dst,InputArray map1,InputArray map2,
int interpolation,int borderMode=BORDER_CONSTANT,const Scalar&borderValue=Scalar())
第一个参数:输入图像,即原图像,需要单通道8位或者浮点类型的图像
第二个参数:输出图像,即目标图像,需和原图形一样的尺寸和类型
第三个参数:它有两种可能表示的对象:
- 表示点(x,y)的第一个映射;
- 表示CV_16SC2,CV_32FC1类型的X值
第四个参数:它有两种可能表示的对象:
- 若map1表示点(x,y)时,这个参数不代表任何值;
- 表示CV_16UC1,CV_32FC1类型的Y值
第五个参数:插值方式,有四种插值方式:(1)INTER_NEAREST——最近邻插值
(2)INTER_LINEAR——双线性插值(默认)
(3)INTER_CUBIC——双三样条插值(默认)
(4)INTER_LANCZOS4——lanczos插值(默认)
第六个参数:边界模式,默认BORDER_CONSTANT
第七个参数:边界颜色,默认Scalar()黑色
int main()
{
Mat src = imread("1.jpg");
Mat dst;
//创建和原始图像一样的效果图,x重映射图,y重映射图
dst.create(src.size(),src.type());
Mat map_x;
Mat map_y;
map_x.create(src.size(), CV_32FC1);
map_y.create(src.size(), CV_32FC1);
//双层循环,遍历每一个像素点,改变map_x和map_y的值
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
//map_x.at<float>(i, j) = (float)(src.cols - j);
//map_y.at<float>(i, j) = (float)i; //水平
map_x.at<float>(i, j) = (float)j;
map_y.at<float>(i, j) = (float)(src.rows - i); //垂直
//map_x.at<float>(i, j) = (float)(src.cols - j);
//map_y.at<float>(i, j) = (float)(src.rows - i); //同时旋转
}
}
remap(src, dst, map_x, map_y, CV_INTER_LINEAR);
}
2、flip函数
图像的反转采用flip函数实现,该函数能够实现图像在水平方向,垂直方向和水平垂直方向的旋转,函数代码如下:
void cv::flip(
InputArray src
OutputArray dst,
int flipCode)
- src 是原始图像;
- dst 是和原始图像大小,类型相同的目标图像;
- flipCode 是旋转类型,0代表x轴旋转,任意正数代表y轴旋转,任意负数代表x和y轴同时旋转。
2. 旋转
将原图按照一定角度旋转,作为新图像。常取的旋转角度为 -30°、-15°、15°、30° 角度值。先通过getRotationMatrix2D函数得到图像的旋转矩阵,然后再通过仿射变换函数warpAffine得到旋转后的图像。
函数说明:
cv2.getRotationMatrix2D(center, angle, scale)
cv2.warpAffine(src, M, dsize,dst=None,flags=None,borderMode=None,borderValue=None)
参数说明:
getRotationMatrix2D:
- center:表示旋转的中心点
- angle:表示旋转的角度degrees
- scale:图像缩放因子
warpAffine:
- src:输入的图像
- M:2 X 3 的变换矩阵.
- dsize:输出的图像的size大小
- dst:输出的图像
- flags:输出图像的插值方法
- borderMode:图像边界的处理方式
- borderValue:当图像边界处理方式为BORDER_CONSTANT时的填充值
3. 尺度变换
将图像分辨率变为原图的0.8、0.9、1.1、1.2等倍数,作为新图像。
resize(temp, dstImage, Size(128, 128), (0, 0), (0, 0), 3);
- scr:原图
- dsize:输出图像尺寸
- fx:沿水平轴的比例因子
- fy:沿垂直轴的比例因子
- interpolation:插值方法
4. 抠取
随机抠取:在原图的随机位置抠取图像块,作为新图像。
监督式抠取:只抠取含有明显语义信息的图像块。
5. 色彩抖动
对图像原有的像素值分布进行轻微扰动(即加入轻微噪声),作为新图像。
void salt(Mat img, int n)
{
for (int k = 0; k<n; k++)
{
int i = rand() % img.cols;
int j = rand() % img.rows;
if (img.channels() == 1)
img.at<uchar>(j, i) = 255;
else if (img.channels() == 3)
{
img.at<Vec3b>(j, i)[0] = 255;
img.at<Vec3b>(j, i)[1] = 255;
img.at<Vec3b>(j, i)[2] = 255;
}
}
}
from:https://blog.csdn.net/thisiszdy/article/details/87028312
from:https://blog.csdn.net/syyyy712/article/details/80042637
from:https://blog.csdn.net/jningwei/article/details/79219838