欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV图像处理——深度学习样本制造

程序员文章站 2024-03-09 13:27:55
...

前言

在做深度学习相关的项目时,往往最麻烦的是样本的收集,或者只有很少的一些样本,训练根本达不到想要的效果,很多网络模型的配置文件里面都有样本增强的定义,是对样本做旋转,变换之类的操作,但没有给样本加一些背景来制造增强样本的数量。

一、样本准备

1.我做一个发票检测位置到识别里面文字的项目,但我手里并没有多少张发票样本,在网上也很难找到能用的样本,我的应用场景是把发票放在桌面上拍照之后,检测识别。所以我先去网上下一些木纹桌面的样本,放在一个目录,完成之后从0开始命名如下:OpenCV图像处理——深度学习样本制造
2.我自己手中有发票样本也放在一个目录,也从0开始命名如下:
OpenCV图像处理——深度学习样本制造

二、代码

1.代码用到OpenCV的基本库,读写文件就随便写了个循环读写,最好是改成boost库来读写文件。
2.代码的思想,大概是要的发票样本按任意角度旋转,再与背景图像融合。
3.代码:

bool ROI_AddImage(Mat &cv_back, Mat &cv_front, Mat &cv_dst)
{
	Mat cv_mask = cv_front.clone();
	if (!cv_back.data)
	{
		std::cout << "读入图片失败" << std::endl;
		return false;
	}
	if (!cv_front.data)
	{
		std::cout << "读入图片失败" << std::endl;
		return false;
	}

	int w = (cv_back.cols - cv_front.cols) / 2;
	int h = (cv_back.rows - cv_front.rows) / 2;
	Mat imageROI = cv_back(Rect(w, h, cv_front.cols, cv_front.rows));

	Mat mask;

	cv::cvtColor(cv_mask, mask, COLOR_BGR2GRAY);
	
	cv_front.copyTo(imageROI, mask);  
	
	cv_dst = cv_back.clone();
}

int main()
{
	string back = "C:/Users/matt/Desktop/8/";
	string front = "C:/Users/matt/Desktop/80/";
	string save = "C:/Users/matt/Desktop/data/";

	for (int i = 0; i < 20; i++)
	{
		string back_name = back + to_string(i) + ".jpg";
		string front_name = front + to_string(i) + ".jpg";

		Mat back = imread(back_name);
		Mat cv_front = imread(front_name);
		
		for (int j = 0; j < 5; j++)
		{
			Mat cv_back = back.clone();
			Mat cv_rotata;
			int a = rand() % 180;
			rotateImage2(cv_front, cv_rotata, a, 0);
			Mat cv_png;
			toPng(cv_rotata, cv_png, 0);
		
			if (cv_png.rows > cv_back.rows)
			{
				resize(cv_back, cv_back, cv_png.size(), 0.0, 0.0, INTER_NEAREST);
				resize(cv_png, cv_png, Size(cv_png.cols / 1.2, cv_png.rows / 1.2));
			}
			if (cv_png.rows < cv_back.rows)
			{
				resize(cv_png, cv_png, cv_back.size(), 0.0, 0.0, INTER_NEAREST);
				resize(cv_png, cv_png, Size(cv_png.cols / 1.2, cv_png.rows / 1.2));
			}

			Mat cv_dst;
			ROI_AddImage(cv_back, cv_png, cv_dst);
			string save_name = save + to_string(i) + to_string(j) + ".jpg";
			imwrite(save_name, cv_dst);
		}
	}
	
	waitKey(0);
	return 0;
}

void toPng(cv::Mat &src, cv::Mat &dst, int mark)
{
	cv::Mat cv_input = src.clone();
	if (cv_input.channels() != 4)
	{
		cv::cvtColor(cv_input, dst, CV_BGR2BGRA);
	}
	else
	{
		return;
	}
	for (int y = 0; y < dst.rows; ++y)
	{
		for (int x = 0; x < dst.cols; ++x)
		{
			cv::Vec4b & pixel = dst.at<cv::Vec4b>(y, x);
			if (pixel[0] == mark && pixel[1] == mark && pixel[2] == mark)
			{
				pixel[3] = 0;
			}
		}
	}
}

int rotateImage(Mat &img, Mat & imgout, int degree, int border_value)
{
	if (img.empty())
		return 1;
	degree = -degree;
	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(width * fabs(b) + height * fabs(a));
	int height_rotate = int(height * fabs(b) + width * fabs(a));
	if (width_rotate <= 20 || height_rotate <= 20)
	{
		width_rotate = 20;
		height_rotate = 20;
	}

	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;
	int chnnel = img.channels();
	if (chnnel == 3)
		warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, Scalar(0, 0, 0));
	else
		warpAffine(img, imgout, map_matrix, Size(width_rotate, height_rotate), 1, 0, 255);
	return 0;
}

4.可以自己设置融合多少次,运行之后的结果如下:
OpenCV图像处理——深度学习样本制造

注:有兴趣于图像处理学习的可以加
OpenCV图像处理——深度学习样本制造

相关标签: opencv 深度学习