C++批量对图片进行水平镜像、切片、旋转、添加椒盐噪声(小样本学习中图像扩充)

C++实现:批量对图片进行水平镜像、切片、旋转、添加椒盐噪声。 

应用场景:小样本学习中图像扩充。


#include <iostream>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

Mat addSaltNoise(const Mat srcImage, int n);
Mat rotateImage(Mat img, int degree);

void main()
{
	int i = 0;
	string name, clas;
	ifstream infile;
	infile.open("F:/小样本学习图片数据/xifang/org_img/train.txt");
	string image_dir = "F:/小样本学习图片数据/xifang/org_img/train/";
	while (infile)
	{
		infile >> name >> clas;
		cout << i++ << endl;
		string image_dir_name = image_dir + name;
		Mat image = imread(image_dir_name, -1);

		// 1、对图像进行水平镜像
		string image_jingxiang = "F:/小样本学习图片数据/xifang/生成后的train图片/水平镜像/";
		string image_out_jingxiang = image_jingxiang + name;
		Mat img_jingxiang;
		img_jingxiang.create(image.size(), image.type());
		for (int i = 0; i < image.rows; i++)
		{
			for (int j = 0; j < image.cols; j++)
			{
				img_jingxiang.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, image.cols - 1 - j)[0];
				img_jingxiang.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, image.cols - 1 - j)[1];
				img_jingxiang.at<Vec3b>(i, j)[2] = image.at<Vec3b>(i, image.cols - 1 - j)[2];
			}
		}
		imwrite(image_out_jingxiang, img_jingxiang);

		// 2、对图像进行切片,右上角切片
		string image_qiepian_youshang = "F:/小样本学习图片数据/xifang/生成后的train图片/切片/右上角切片/";
		string image_out_qiepian_youshang = image_qiepian_youshang + name;
		//Rect bbox(0, 0, 224, 224);  // 左上角切片
		Rect bbox1(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
		//Rect bbox(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
		//Rect bbox(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
		//Rect bbox(image.cols/2- 112, image.rows/2 -112,224, 224);  // 中间切片

		Mat img_qiepian_youshang = image(bbox1);
		cv::resize(img_qiepian_youshang, img_qiepian_youshang, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_qiepian_youshang, img_qiepian_youshang);

		// 3、对图像进行切片,右下角切片
		string image_qiepian_youxia = "F:/小样本学习图片数据/xifang/生成后的train图片/切片/右下角切片/";
		string image_out_qiepian_youxia = image_qiepian_youxia + name;
		//Rect bbox(0, 0, 224, 224);  // 左上角切片
		//Rect bbox(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
		//Rect bbox(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
		Rect bbox2(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
		//Rect bbox(image.cols/2- 112, image.rows/2 -112,224, 224);  // 中间切片

		Mat img_qiepian_youxia = image(bbox2);
		cv::resize(img_qiepian_youxia, img_qiepian_youxia, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_qiepian_youxia, img_qiepian_youxia);

		// 4、对图像进行切片,中间切片
		string image_qiepian_zhongjian = "F:/小样本学习图片数据/xifang/生成后的train图片/切片/中间切片/";
		string image_out_qiepian_zhongjian = image_qiepian_zhongjian + name;
		//Rect bbox(0, 0, 224, 224);  // 左上角切片
		//Rect bbox(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
		//Rect bbox(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
		//Rect bbox(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
		Rect bbox3(image.cols/2- 112, image.rows/2 -112,224, 224);  // 中间切片

		Mat img_qiepian_zhongjian = image(bbox3);
		cv::resize(img_qiepian_zhongjian, img_qiepian_zhongjian, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_qiepian_zhongjian, img_qiepian_zhongjian);

		// 5、对图像进行切片,左上角切片
		string image_qiepian_zuoshang = "F:/小样本学习图片数据/xifang/生成后的train图片/切片/左上角切片/";
		string image_out_qiepian_zuoshang = image_qiepian_zuoshang + name;
		Rect bbox4(0, 0, 224, 224);  // 左上角切片
		//Rect bbox(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
		//Rect bbox(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
		//Rect bbox(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
		//Rect bbox(image.cols / 2 - 112, image.rows / 2 - 112, 224, 224);  // 中间切片

		Mat img_qiepian_zuoshang = image(bbox4);
		cv::resize(img_qiepian_zuoshang, img_qiepian_zuoshang, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_qiepian_zuoshang, img_qiepian_zuoshang);

		// 6、对图像进行切片,左下角切片
		string image_qiepian_zuoxia = "F:/小样本学习图片数据/xifang/生成后的train图片/切片/左下角切片/";
		string image_out_qiepian_zuoxia = image_qiepian_zuoxia + name;
		//Rect bbox4(0, 0, 224, 224);  // 左上角切片
		//Rect bbox(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
		Rect bbox5(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
		//Rect bbox(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
		//Rect bbox(image.cols / 2 - 112, image.rows / 2 - 112, 224, 224);  // 中间切片

		Mat img_qiepian_zuoxia = image(bbox5);
		cv::resize(img_qiepian_zuoxia, img_qiepian_zuoxia, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_qiepian_zuoxia, img_qiepian_zuoxia);

		// 7、镜像逆时针8度
		string image_jiangxiang_ni8 = "F:/小样本学习图片数据/xifang/生成后的train图片/旋转_镜像/镜像逆时针8度/";
		string image_out_jiangxiang_ni8 = image_jiangxiang_ni8 + name;
		Mat img_jiangxiang_ni8 = rotateImage(img_jingxiang, -8);
		cv::resize(img_jiangxiang_ni8, img_jiangxiang_ni8, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_jiangxiang_ni8, img_jiangxiang_ni8);

		// 8、镜像顺时针8度
		string image_jiangxiang_shun8 = "F:/小样本学习图片数据/xifang/生成后的train图片/旋转_镜像/镜像顺时针8度/";
		string image_out_jiangxiang_shun8 = image_jiangxiang_shun8 + name;
		Mat img_jiangxiang_shun8 = rotateImage(img_jingxiang, 8);
		cv::resize(img_jiangxiang_shun8, img_jiangxiang_shun8, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_jiangxiang_shun8, img_jiangxiang_shun8);

		// 9、原图逆时针8度
		string image_yuantu_ni8 = "F:/小样本学习图片数据/xifang/生成后的train图片/旋转_镜像/原图逆时针8度/";
		string image_out_yuantu_ni8 = image_yuantu_ni8 + name;
		Mat img_yuantu_ni8 = rotateImage(image, -8);
		cv::resize(img_yuantu_ni8, img_yuantu_ni8, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_yuantu_ni8, img_yuantu_ni8);

		// 10、原图顺时针8度
		string image_yuantu_shun8 = "F:/小样本学习图片数据/xifang/生成后的train图片/旋转_镜像/原图顺时针8度/";
		string image_out_yuantu_shun8 = image_yuantu_shun8 + name;
		Mat img_yuantu_shun8 = rotateImage(image, 8);
		cv::resize(img_yuantu_shun8, img_yuantu_shun8, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_yuantu_shun8, img_yuantu_shun8);

		// 11、镜像噪声
		string image_jingxiang_zao = "F:/小样本学习图片数据/xifang/生成后的train图片/噪声_镜像/镜像噪声/";
		string image_out_jingxiang_zao = image_jingxiang_zao + name;
		Mat img_jingxiang_zao = addSaltNoise(img_jingxiang, 2000);
		cv::resize(img_jingxiang_zao, img_jingxiang_zao, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_jingxiang_zao, img_jingxiang_zao);

		// 12、原图噪声
		string image_yuantu_zao = "F:/小样本学习图片数据/xifang/生成后的train图片/噪声_镜像/原图噪声/";
		string image_out_yuantu_zao = image_yuantu_zao + name;
		Mat img_yuantu_zao = addSaltNoise(image, 2000);
		cv::resize(img_yuantu_zao, img_yuantu_zao, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_yuantu_zao, img_yuantu_zao);


	}
}





// resize
void main000(void)
{
	int i = 0;
	string name, clas;
	ifstream infile;
	infile.open("F:/小样本学习图片数据/xifang/org_img/val.txt");
	string image_dir = "F:/小样本学习图片数据/xifang/org_img/val/";
	string image_out = "F:/小样本学习图片数据/xifang/org_img/val_resize/";
	while (infile)
	{
		infile >> name >> clas;
		cout << i++ << endl;
		string image_dir_name = image_dir + name;
		string image_out_name = image_out + name;
		Mat image = imread(image_dir_name, -1);
		Mat img_trans = image;
		cv::resize(img_trans, img_trans, cv::Size(256, 256), cv::INTER_LINEAR);
		imwrite(image_out_name, img_trans);

	}

	
}


// 对图像添加椒盐噪声
void main444(void)
{
	string image_dir = "D:/visualstudio 2013/project text/c++/c++/";
	string image_out_dir = "D:/visualstudio 2013/project text/c++/";
	string image_name = "people_400.jpg";
	string image_dir_name = image_dir + image_name;
	string image_out_dir_name = image_out_dir + image_name;

	Mat image = imread(image_dir_name, -1);
	Mat img_trans = addSaltNoise(image, 2000);

	imwrite(image_out_dir_name, img_trans);
}


// 对图像进行旋转
void main222(void)
{
	string image_dir = "D:/visualstudio 2013/project text/c++/c++/";
	string image_out_dir = "D:/visualstudio 2013/project text/c++/";
	string image_name = "people_400.jpg";
	string image_dir_name = image_dir + image_name;
	string image_out_dir_name = image_out_dir + image_name;

	int degree = 8;
	Mat image = imread(image_dir_name, -1);
	Mat img_trans = rotateImage(image, degree);
	cv::resize(img_trans, img_trans, cv::Size(256, 256), cv::INTER_LINEAR);

	imwrite(image_out_dir_name, img_trans);
}


// 对四角和中间进行切片
void main333(void)
{
	string image_dir = "D:/visualstudio 2013/project text/c++/c++/";
	string image_out_dir = "D:/visualstudio 2013/project text/c++/";
	string image_name = "people_400.jpg";
	string image_dir_name = image_dir + image_name;
	string image_out_dir_name = image_out_dir + image_name;

	Mat image = imread(image_dir_name, -1);
	Rect bbox(0, 0, 224, 224);  // 左上角切片
	//Rect bbox(image.cols - 1 - 224, 0, 224, 224);  // 右上角切片
	//Rect bbox(0, image.rows - 1 - 224, 224, 224);  // 左下角切片
	//Rect bbox(image.cols - 1 - 224, image.rows - 1 - 224, 224, 224);  // 右下角切片
	//Rect bbox(image.cols/2- 112, image.rows/2 -112,224, 224);  // 中间切片

	Mat img_trans = image(bbox);
	cv::resize(img_trans, img_trans, cv::Size(256, 256), cv::INTER_LINEAR);

	imwrite(image_out_dir_name, img_trans);

}

// 对图像进行水平镜像
void main111(void)
{
	string image_dir = "D:/visualstudio 2013/project text/c++/c++/";
	string image_out_dir = "D:/visualstudio 2013/project text/c++/";
	string image_name = "people_400.jpg";
	string image_dir_name = image_dir + image_name;
	string image_out_dir_name = image_out_dir + image_name;

	Mat image = imread(image_dir_name, -1);
	Mat img_trans;
	img_trans.create(image.size(), image.type());
	for (int i = 0; i < image.rows; i++)
	{
		for (int j = 0; j < image.cols; j++)
		{
			img_trans.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, image.cols - 1 - j)[0];
			img_trans.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, image.cols - 1 - j)[1];
			img_trans.at<Vec3b>(i, j)[2] = image.at<Vec3b>(i, image.cols - 1 - j)[2];
		}
	}

	imwrite(image_out_dir_name, img_trans);

}


// ******************************* 功能函数 ***********************************

// 对图片添加椒盐噪声
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;
}

// 对图像进行旋转函数,默认为顺时针方向
Mat rotateImage(Mat img, int degree)
{
	degree = -degree;//warpAffine默认的旋转方向是逆时针,所以加负号表示转化为顺时针
	double angle = degree  * CV_PI / 180.; // 弧度  
	double a = sin(angle), b = cos(angle);
	int width = img.cols;
	int height = img.rows;
	int width_rotate = int(height * fabs(a) + width * fabs(b));
	int height_rotate = int(width * fabs(a) + height * fabs(b));
	//旋转数组map
	// [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]
	// [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]
	float map[6];
	Mat map_matrix = Mat(2, 3, CV_32F, map);
	// 旋转中心
	CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2);
	CvMat map_matrix2 = map_matrix;
	cv2DRotationMatrix(center, degree, 1.0, &map_matrix2);//计算二维旋转的仿射变换矩阵
	map[2] += (width_rotate - width) / 2;
	map[5] += (height_rotate - height) / 2;
	Mat img_rotate;
	//对图像做仿射变换
	//CV_WARP_FILL_OUTLIERS - 填充所有输出图像的象素。
	//如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval.
	//CV_WARP_INVERSE_MAP - 指定 map_matrix 是输出图像到输入图像的反变换,
	warpAffine(img, img_rotate, map_matrix, Size(width_rotate, height_rotate), 1, 0, 0);
	return img_rotate;
}

原图示意图:


水平镜像效果图:


原图左上角切片效果图:


原图顺时针旋转8度示意图:


原图添加椒盐噪声示意图:





猜你喜欢

转载自blog.csdn.net/xzzppp/article/details/75960273