**图像数据增强方法概述**
图像数据准备对神经网络与卷积神经网络模型训练有重要影响,当样本空间不够或者样本数量不足的时候会严重影响训练或者导致训练出来的模型泛化程度不够,识别率与准确率不高!本文将会带你学会如何对已有的图像数据进行数据增强,获取样本的多样性与数据的多样性从而为训练模型打下良好基础。通读全文你将get到如何几个技能:
1.使用标准化对图像进行图像增强 深度学习训练-详解图像数据标准化与归一化
2.使用几何变换(平移、翻转、旋转)对图像进行数据增强
3.使用随机调整亮度对图像进行增强
4.使用随机调整对比度对图像进行增强
5.添加高斯噪声和椒盐噪声
6.对图像进行仿射变换
opencv2各模块功能
opencv_core:包含核心功能,尤其是底层数据结构和算法函数
opencv_imgproc : 包含图像处理函数
opencv_highgui : 包含读写图像及视频函数,以及操作图形用户界面函数
opencv_features2d : 包含兴趣点检测子,描述子和兴趣点匹配框架
opencv_calib3d : 包含相机标定,双目几何估算以及立体视觉函数
opencv_video : 包含运动估算,特征跟踪以及前景提取函数
opencv_objdetect : 包括物体检测函数,如面部识别
一、加椒盐噪声
图像模拟添加椒盐噪声是通过随机获取像素点并设置为高亮度点和低灰度点来实现的
图像添加椒盐噪声的程序如下:
//利用程序给原图像增加椒盐噪声
//图象模拟添加椒盐噪声是通过随机获取像素点斌那个设置为高亮度点来实现的
#include <cstdlib>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
Mat addSaltNoise(const Mat srcImage, int n);
int main()
{
Mat srcImage = imread("2345.jpg");
if (!srcImage.data)
{
cout << "读入图像有误!" << endl;
system("pause");
return -1;
}
imshow("原图像", srcImage);
Mat dstImage = addSaltNoise(srcImage, 3000);
imshow("添加椒盐噪声的图像", dstImage);
//存储图像
imwrite("salt_pepper_Image.jpg", dstImage);
waitKey();
return 0;
}
Mat addSaltNoise(const Mat srcImage, int n)
{
Mat dstImage = srcImage.clone();
for (int k = 0; k < n; k++)
{
//随机取值行列
int i = rand() % dstImage.rows;
int j = rand() % dstImage.cols;
//图像通道判定
if (dstImage.channels() == 1)
{
dstImage.at<uchar>(i, j) = 255; //盐噪声
}
else
{
dstImage.at<Vec3b>(i, j)[0] = 255;
dstImage.at<Vec3b>(i, j)[1] = 255;
dstImage.at<Vec3b>(i, j)[2] = 255;
}
}
for (int k = 0; k < n; k++)
{
//随机取值行列
int i = rand() % dstImage.rows;
int j = rand() % dstImage.cols;
//图像通道判定
if (dstImage.channels() == 1)
{
dstImage.at<uchar>(i, j) = 0; //椒噪声
}
else
{
dstImage.at<Vec3b>(i, j)[0] = 0;
dstImage.at<Vec3b>(i, j)[1] = 0;
dstImage.at<Vec3b>(i, j)[2] = 0;
}
}
return dstImage;
}
二、添加高斯噪声
高斯噪声是指图像概率密度函数服从高斯分布的一类噪声。
根据Box-Muller变换原理,建设随机变量U1、U2来自独立的处于(0,1)之间的均匀分布,则经过下面两个式子产生的随机变量Z0,Z1服从标准高斯分布。
上式中Z0,Z1满足正态分布,其中均值为0,方差为1,变量U1和U2可以修改为下式:
给图像添加高斯噪声的程序如下:
//给图像添加高斯噪声
#include <cmath>
#include <limits>
#include <cstdlib>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace cv;
using namespace std;
double generateGaussianNoise(double m, double sigma);
Mat addGaussianNoise(Mat &srcImag);
int main()
{
Mat srcImage = imread("2345.jpg");
if (!srcImage.data)
{
cout << "读入图片错误!" << endl;
system("pause");
return -1;
}
imshow("原图像", srcImage);
Mat dstImage = addGaussianNoise(srcImage);
imshow("添加高斯噪声后的图像", dstImage);
waitKey();
return 0;
}
//生成高斯噪声
double generateGaussianNoise(double mu, double sigma)
{
//定义小值
const double epsilon = numeric_limits<double>::min();
static double z0, z1;
static bool flag = false;
flag = !flag;
//flag为假构造高斯随机变量X
if (!flag)
return z1 * sigma + mu;
double u1, u2;
//构造随机变量
do
{
u1 = rand() * (1.0 / RAND_MAX);
u2 = rand() * (1.0 / RAND_MAX);
} while (u1 <= epsilon);
//flag为真构造高斯随机变量
z0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI*u2);
z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI*u2);
return z0*sigma + mu;
}
//为图像添加高斯噪声
Mat addGaussianNoise(Mat &srcImag)
{
Mat dstImage = srcImag.clone();
int channels = dstImage.channels();
int rowsNumber = dstImage.rows;
int colsNumber = dstImage.cols*channels;
//判断图像的连续性
if (dstImage.isContinuous())
{
colsNumber *= rowsNumber;
rowsNumber = 1;
}
for (int i = 0; i < rowsNumber; i++)
{
for (int j = 0; j < colsNumber; j++)
{
//添加高斯噪声
int val = dstImage.ptr<uchar>(i)[j] +
generateGaussianNoise(2, 0.8) * 32;
if (val < 0)
val = 0;
if (val>255)
val = 255;
dstImage.ptr<uchar>(i)[j] = (uchar)val;
}
}
return dstImage;
}