扩充方法
在进行卷积神经网络计算时,很多情况下我们无法获得足够的数据,可以通过人工数据合成的方法进行扩充.本人的扩充方法如下:
具体为将原图像分别水平,竖直和水平竖直翻转扩充至原来的4倍;然后对获得图像分别-30°,-15°,15°,30°进行旋转扩充至原来的20倍;然后随机添加高斯噪声扩充至原来的40倍.
运行环境:QT+C+++OPENCV
代码
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
void Resize(int i,cv::Mat image1);
void imageRotate(const cv::Mat &src, double degree, const double scale,int i, float height, float width );
double generateGaussianNoise(double mu, double sigma);
Mat addGaussianNoise(Mat &srcImag,int i);
int main()
{
//用void glob(String pattern, std::vector<String>& result, bool recursive = false);当recursive为false时,仅仅遍历指定文件夹内符合模式的文件,当recursive为true时,会同时遍历指定文件夹的子文件夹
//pattern要绝对路径 其它测试有问题
string pattern ="/home/li/shijuejiance/sample/train/bad/*.bmp";
//cout << pattern << endl;
vector<Mat> images;
// 必须cv的String
vector<String> fn;
glob(pattern, fn, false);
int count = fn.size();
cout << count << endl;
for (int i = 0; i < count; i++)
{
images.push_back(imread(fn[i]));
//Resize(i,images[i]);
imageRotate(images[i],-30,1,i,1375,2125);
//cout<<i<<endl;
//Mat dstImage = addGaussianNoise(images[i],i);
//imshow("添加高斯噪声后的图像", dstImage);
cout<<i<<endl;
}
}
/*
//裁剪和翻转
void Resize(int i,cv::Mat image1)
{
i=i+40;
//cv::Mat image2;
//cv::resize(image1, image2, cv::Size(), 0.2, 0.2);
//cv::imshow("原图",image2);
//矩形提取
cv::Rect rect(200,375,2125,1375); //盖板
//cv::Rect rect(260,375,2190,1375); //学校
cv::Mat image_cut = cv::Mat(image1, rect); //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
cv::Mat image = image_cut.clone(); //clone函数创建新的图片
//cv::imshow("裁剪好的图像",image);
//cv::flip(image1,image1,-1);//>0: 沿y-轴翻转, 0: 沿x-轴翻转, <0: x、y轴同时翻转
cv::imwrite("/home/li/shijuejiance/sample/train/bad/"+to_string(i)+".bmp",image1);
imshow("images", image1);
}
*/
//旋转
void imageRotate(const cv::Mat &src, double degree, const double scale,int i, float height, float width )
{
i=i+76;
cv::Mat image1;
double angle = degree;
int length = 0;//保证旋转后的图像足够大能存放结果(对角线长度)
if (scale <= 1)
length = sqrt(src.cols*src.cols + src.rows*src.rows);
else
length = sqrt(src.cols*src.cols + src.rows*src.rows) * scale;
cv::Mat tmp_img = cv::Mat(length, length, src.type(), cv::Scalar(255, 255, 255));
int ROI_X = length / 2 - src.cols / 2;
int ROI_Y = length / 2 - src.rows / 2;
cv::Rect ROI_SRC(ROI_X, ROI_Y, src.cols, src.rows);
cv::Mat tmp_ROI(tmp_img, ROI_SRC);//取出临时图像tmp_img的中心的一块ROI_SEC存放src,也就是将src图像放到了临时图像tmp_img的中心
src.copyTo(tmp_ROI);
cv::Point2f rotate_center(length / 2, length / 2);//旋转中心
cv::Mat affineMat = cv::getRotationMatrix2D(rotate_center, angle, scale);//仿射变换旋转矩阵
cv::warpAffine(tmp_img, image1, affineMat, cv::Size(length, length), cv::INTER_CUBIC, 0, cv::Scalar(255, 255, 255));//仿射变换
if(degree>=0)
degree=degree;
else
degree=-degree;
degree = degree*CV_PI / 180;
float height1, width1;
height1 = width*sin(degree) + height*cos(degree);
width1 = width*cos(degree) + height*sin(degree);
if (height1 > image1.rows)
height1 = image1.rows;
if (width1 > image1.cols)
width1 = image1.cols;
cv::Point2f point(image1.cols / 2 - width1 / 2, image1.rows / 2 - height1 / 2);
cv::Rect2f rect(point, cv::Size2f(width1, height1));
cv::Mat temp = image1(rect);
cv::Mat dst;
dst = temp;
cv::imshow("images",dst);
cv::imwrite("/home/li/shijuejiance/sample/test/"+to_string(i)+".bmp",dst);
}
/*
//生成高斯噪声
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,int i)
{
i=i+1;
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 k= 0; k < rowsNumber; k++)
{
for (int j = 0; j < colsNumber; j++)
{
//添加高斯噪声
int val = dstImage.ptr<uchar>(k)[j] + generateGaussianNoise(2, 0.8) * 32;
if (val < 0)
val = 0;
if (val>255)
val = 255;
dstImage.ptr<uchar>(k)[j] = (uchar)val;
}
}
cv::imwrite("/home/li/shijuejiance/sample/test2/"+to_string(i)+".bmp",dstImage);
return dstImage;
}
*/
版权声明:本文为weixin_41440103原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。