数据扩充常见方法

  数据扩充(data augmentation),又名 数据增强 / 数据增广。其本质即:缺少海量数据时,为了保证模型的有效训练,一分钱掰成两半花。

为什么需要数据增强:

     一般而言,比较成功的神经网络需要大量的参数,许许多多的神经网路的参数都是数以百万计,而使得这些参数可以正确工作则需要大量的数据进行训练,而实际情况中数据并没有我们想象中的那么多

数据增强的作用:

  1.  数据增强让有限的数据产生更多的数据,增加训练样本的数量以及多样性(噪声数据),增加噪声数据,提升模型鲁棒性
  2. 随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。例如,我们可以对图像进行不同方式的裁剪,让物体以不同的实例出现在图像的不同位置,这同样能够降低模型对目标位置的敏感性。例如,我们也可以调整亮度、对比度、饱和度和色调 等因素来降低模型对 色彩的敏感度。

如何获得大量的数据:

  1.  获得新的数据,这种方法比较麻烦,需要大量的成本,
  2. 对数据进行增强,即利用已有的数据比如翻转、平移或旋转,创造出更多的数据,来使得神经网络具有更好的泛化效果。数据扩充方法包括:镜像、旋转、尺度变换、随机抠取、色彩抖动

 

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)
  1. src 是原始图像;
  2. dst 是和原始图像大小,类型相同的目标图像;
  3. 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:

  1. center:表示旋转的中心点
  2. angle:表示旋转的角度degrees
  3. scale:图像缩放因子

warpAffine:

  1. src:输入的图像
  2. M:2 X 3 的变换矩阵.
  3. dsize:输出的图像的size大小
  4. dst:输出的图像
  5. flags:输出图像的插值方法
  6. borderMode:图像边界的处理方式
  7. 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

  • 6
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值