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度示意图:


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





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在OpenCV C++添加椒盐噪声,可以通过以下步骤来实现: 1. 加载图像 首先,使用 `imread` 函数加载需要添加噪声的图像。例如,以下代码加载名为 `test.jpg` 的图像: ```c++ Mat image = imread("test.jpg"); ``` 2. 复制图像 为了不影响原始图像,我们需要复制一份原始图像。可以使用 `clone` 函数来实现。例如,以下代码创建了一个名为 `noisyImage` 的新图像,其内容与原始图像相同: ```c++ Mat noisyImage = image.clone(); ``` 3. 添加噪声 使用随机数生成器(如 `rand` 函数)来随机选择图像的像素,并将它们设置为黑色或白色,从而添加椒盐噪声。以下代码演示了如何用10%的概率将像素设置为黑色或白色: ```c++ int noisePercent = 10; int noiseCount = (int)((float)noisePercent / 100 * image.rows * image.cols); for (int i = 0; i < noiseCount; i++) { int row = rand() % image.rows; int col = rand() % image.cols; noisyImage.at<Vec3b>(row, col)[0] = rand() % 2 == 0 ? 0 : 255; noisyImage.at<Vec3b>(row, col)[1] = rand() % 2 == 0 ? 0 : 255; noisyImage.at<Vec3b>(row, col)[2] = rand() % 2 == 0 ? 0 : 255; } ``` 这个代码用 `Vec3b` 类型的 `at` 函数来访问像素,并将其设置为随机的黑色或白色。注意,如果图像是灰度图像,可以使用 `uchar` 类型的 `at` 函数来访问像素。 4. 显示图像 最后,使用 `imshow` 函数显示原始图像添加了噪声的图像。例如,以下代码显示了原始图像添加了噪声的图像: ```c++ imshow("Original Image", image); imshow("Noisy Image", noisyImage); waitKey(0); ``` 这些是添加椒盐噪声的基本步骤。当然,还有其他的噪声类型和添加噪声的方法,您可以根据您的需求进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值