Opencv c++从影像分帧开始,制作数据集

1.影像图片分帧并保存(按照自己设计的帧率),然后将图片裁剪为所需要的大小

//视频分帧
#include <opencv2/opencv.hpp>
#include <tchar.h>?
#include <stdio.h> ?
#include <iostream> ?
#include <math.h> ?
#include <ostream>?


using namespace std;
using namespace cv;


void main()
{
	//类VideoCapture实例化再初始化
	//VideoCapture capture;
	//capture.open("Megamind.avi");
	//类VideoCapture实例化的同时初始化

	VideoCapture capture("G:\\建筑垃圾再生料数据集\\5segment\\vedio2.mp4");
	if (!capture.isOpened())
	{
		return;
	}
	int frameRate = 5; //帧数截取间隔(每隔100帧截取一帧)
	int imgIndex = 18938;
	for (;;)
	{
		Mat frame;
		capture >> frame;
		if (frame.empty())
		{
			break;
		}
		if (imgIndex % frameRate == 0)
		{
			imshow("帧图", frame);
			char* imageSaveName = new char[200];
			//将图片的路径及名称输入到imageSaveName中
			//sprintf(imageSaveName, "F:\\2020.6.22照片\\双目相机照片\\%05d.jpg", imgIndex);
			sprintf(imageSaveName, "G:\\建筑垃圾再生料数据集\\5segment\\原图\\%06d.png", int(imgIndex/ frameRate);
			//将每一帧图像frame保存到imageSaveName指定的文件中
			imwrite(imageSaveName, frame);
			
			//裁剪图片
			Mat temp;
			temp = frame;
			string s = "G:\\建筑垃圾再生料数据集\\5segment\\240_240\\" + to_string(int(imgIndex/ frameRate)) + ".png";
			resize(temp, temp, Size(240, 240));
			imwrite(s, temp);
			delete[] imageSaveName;
		}
		imgIndex++;
	}
	cout << "total frames: " << imgIndex << endl;
}

2.批量图像数据增强

1)生成文件夹下图片的路径txt文件

点击win+R,输入cmd打开命令提示符窗口,输入cd F:\face_recognition_database\testset进入到指定目录(路径为图片的路径),再输入F:按回车即可看到当前所在路径,再输入dir /b/s/p/w *.png>inputimage.txt生成包含testset文件夹下所有图片文件名的文本文件(inputimage为该文本文件的文件名),如下图。其中png可以更改为jpg等格式

对于文件夹中有多种类型的图片,可以分别记录其路径,最后将路径合并在一个文件夹即可

dir /b/s/p/w *.jpeg>inputimage_jpeg.txt

dir /b/s/p/w *.jpg>inputimage_jpg.txt

dir /b/s/p/w *.png>inputimage_png.txt

2)批量镜像处理后,垂直和水平翻转(若没有裁剪加上裁剪)

#define _CRT_SECURE_NO_WARNINGS
#include<opencv2\opencv.hpp>
#include<iostream>
#include<vector>
#include<fstream>

using namespace std;
using namespace cv;
int GetTxtLine(const char *filename);
int main() {
	string ss;
	ifstream fin("G:\\建筑垃圾再生料数据集\\disqualification\\原图\\inputimage.txt");
	int i =0;
	while (getline(fin, ss))
	{
		if (ss.length() != 0) {
			Mat temp = imread(ss,1);		
			string s = "G:\\建筑垃圾再生料数据集\\disqualification\\240_240\\"+ to_string(i) + ".png";
			cout << s << endl;
			i=i+2;
			resize(temp, temp, Size(240, 240));
			imwrite(s, temp);			
			// 垂直和水平翻转
			cv::Mat resultImage;
			cv::flip(temp, resultImage, -1);
			string s_1 = "G:\\建筑垃圾再生料数据集\\disqualification\\240_240\\" + to_string(i-1) + ".png";
			cout << s_1 << endl;
			imwrite(s_1, resultImage);
			imshow("图", resultImage);
		}
		else
		{
			break;
		}
	}
	waitKey(0);
	getchar();
	return 0;
}

还可以加上旋转角度等函数

// 对图像进行旋转函数,默认为顺时针方向
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;
}

3.对于数据集特别少的,可以将图片先裁剪为几个部分,在对图像进行图像增强操作

 3-1)图像裁剪和缩放

#include <opencv2/core/core.hpp>    
#include "opencv2/opencv.hpp"
#include <opencv2/highgui/highgui.hpp>    
#include <iostream>  
#include <opencv2/imgproc/imgproc.hpp>  
#include <vector>  
using namespace std;
using namespace cv;
//出现to_string重载时的模板!
#include <string>
#include <type_traits>
namespace std
{
	template<typename T>
	typename enable_if<is_convertible<T, _Longlong>::value, string>::type     to_string(T rhs)
	{
		return to_string(static_cast<_Longlong>(rhs));
	}
}
int main()
{       //设置分割后图像存储路径
	string outpath = "G:\\建筑垃圾再生料数据集\\7segment\\图像增强\\";
	Mat img = imread("G:\\建筑垃圾再生料数据集\\7segment\\原图\\14.jpg"); //将图像放在项目工程里,使用imread函数读取
	int t = 0;
	int m = cvFloor(img.cols / (240 * 4));    //m*n是切割后子图像的个数
	int n = cvFloor(img.rows / (240 * 4)); //cvFloor()不大于参数的最小整数值

	Vector<Mat> ceil_img;  //迭代器ceil_img存储子图像
	Vector<int> name;     //迭代器name存储子图像的名字,从0到m*n-1
	for (t; t < m*n; t++)
		name.push_back(t);
	Mat image_cut, roi_img, tim_img;
	for (int j = 0; j <n; j++)
	{
		for (int i = 0; i < m; i++)
		{
			Rect rect(i * 960, j * 960, 960, 960);
			image_cut = Mat(img, rect);
			roi_img = image_cut.clone();
			resize(roi_img, roi_img, Size(240, 240));
			ceil_img.push_back(roi_img);
		}
	}
	for (int t = 0; t < m*n; t++)
		imwrite(outpath + to_string(name[t]+13*12) + ".png", ceil_img[t]);

	return 0;
}

   3-2)图像批量增强

//图像批量增强
#define _CRT_SECURE_NO_WARNINGS
#include<opencv2\opencv.hpp>
#include<iostream>
#include<vector>
#include<fstream>

using namespace std;
using namespace cv;

Mat rotateImage(Mat img, int degree);

int main() {
	string ss;
	ifstream fin("G:\\建筑垃圾再生料数据集\\7segment\\图像增强\\inputimage.txt");
	int i = 0;
	while (getline(fin, ss))
	{
		if (ss.length() != 0) {
			//1保留原图
			Mat temp = imread(ss, 1);
			string s_1 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_1 << endl;
			imwrite(s_1, temp);

			//2水平翻转		
			i = i+1;
			Mat resultImage2;
			flip(temp, resultImage2, 1);
			string s_2 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_2 << endl;
			imwrite(s_2, resultImage2);

			
			//3垂直翻转
			i = i + 1;
			Mat resultImage3;
			flip(temp, resultImage3, 0);
			string s_3= "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_3 << endl;
			imwrite(s_3, resultImage3);


			//4垂直和水平翻转
			i = i + 1;
			Mat resultImage4;
			flip(temp, resultImage4, -1);
			string s_4 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_4 << endl;
			imwrite(s_4, resultImage4);


			//5镜像顺时针45度
			i = i + 1;
			Mat img_shun45 = rotateImage(temp, 45);
			resize(img_shun45, img_shun45, cv::Size(224, 224), cv::INTER_LINEAR);
			string s_5 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_5 << endl;
			imwrite(s_5, img_shun45);
		

			//6镜像顺时针135度
			i = i + 1;
			Mat img_shun135 = rotateImage(temp, 135);
			resize(img_shun135, img_shun135, cv::Size(224, 224), cv::INTER_LINEAR);
			string s_6 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_6 << endl;
			imwrite(s_6, img_shun135);

		
			//7镜像顺时针225度
			i = i + 1;
			Mat img_shun225 = rotateImage(temp, 225);
			resize(img_shun225, img_shun225, cv::Size(224, 224), cv::INTER_LINEAR);
			string s_7 = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\" + to_string(i) + ".png";
			cout << s_7 << endl;
			imwrite(s_7, img_shun225);
		}
		else
		{
			break;
		}
	}
	waitKey(0);
	getchar();
	return 0;
}

// 对图像进行旋转函数,默认为顺时针方向
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;
}

4.批量对文件进行加前缀操作,区分各类图像

#include<opencv2\opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

vector<Mat> RenamePic(cv::String Path);

int main()
{
	cv::String Path = "G:\\建筑垃圾再生料数据集\\7segment\\240_240\\*.png";
	vector<Mat> images = RenamePic(Path);

	return 0;
}

vector<Mat> RenamePic(cv::String Path)
{
	vector<cv::String> filenames;
	glob(Path, filenames, false);

	vector<Mat> images;
	size_t count = filenames.size();
	for (size_t i = 0; i < count; i++)
	{
		stringstream str;
		str <<"7segment-"<< i << ".png";
		string img_path = "G:\\建筑垃圾再生料数据集\\7segment\\111\\";
		imwrite(img_path + str.str(), imread(filenames[i]));

	}
	return images;
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值