C++-based clipping of designated area of image

This article aims to summarize the C++-based image cutting code summarized by the blogger when he was working on the project. The code is relatively difficult and is only for the study and consolidation of basic knowledge.

For example: read the content of the file 1000.txt, the four numbers behind each line of characters represent the x center, y center, width, and height of the clipping rectangle on the picture respectively.

#define _CRT_SECURE_NO_WARNINGS

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

using namespace std;
using namespace cv;


//字符串分割
vector<string> split(const string &str, const string &pattern)
{
	//const char* convert to char*
	char * strc = new char[strlen(str.c_str()) + 1];
	strcpy(strc, str.c_str());
	vector<string> resultVec;
	char* tmpStr = strtok(strc, pattern.c_str());
	while (tmpStr != NULL)
	{
		resultVec.push_back(string(tmpStr));
		tmpStr = strtok(NULL, pattern.c_str());  //在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回被分割出片段的指针
	}

	delete[] strc;

	return resultVec;
};


//逐行读取
vector<vector<string>> readTxt(char* file)
{
	vector<vector<string>> rect_str;
	ifstream infile;
	infile.open(file);   //将文件流对象与文件连接起来 
	assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行 

	string s;
	while (getline(infile, s))
	{
		rect_str.push_back(split(s, " "));
	}

	infile.close();             //关闭文件输入流 

	return rect_str;
}


//图片裁切并保存
void ImagePicking(const char* ImageFileName, char* CutFileName, vector<vector<string>> rect) 
{
	int length = rect.size();
	Mat srcImage = imread(ImageFileName);
	Mat cutImage;
	string num;
	int centor_x, centor_y, width, height, point_x, point_y;
	for (int i = 0; i < length; i++) 
	{
		int centor_x = stof(rect[i][1]) * 3840;   //stof(),字符串转float
		int centor_y = stof(rect[i][2]) * 2160;
		int	width = stof(rect[i][3]) * 3840;
		int	height = stof(rect[i][4]) * 2160;
		int	point_x = centor_x - width/2;
		int	point_y = centor_y - height/2;

		num = CutFileName + to_string(i) + ".png";

		Rect select = Rect(point_x, point_y, width, height);
		//Rect select = Rect(100, 300, 500, 1000);

		cutImage = srcImage(select);
		imwrite(num, cutImage);
	}
}



int main()
{
	vector<vector<string>> rect;

    //标签路径
	char* LabelPath = "E:\\FaceAll\\Project\\PicCut\\tomato_large\\labels\\train\\1000.txt";
    //图片路径
	char* ImagePath = "E:\\FaceAll\\Project\\PicCut\\tomato_large\\images\\train\\1000.png";
    //裁切后的图片保存路径
	char* CutPath = "E:\\FaceAll\\Project\\PicCut\\tomato_large\\images\\train\\1000\\";

    //将标签文件中的内容读取出来
	rect = readTxt(LabelPath);
    //根据文件内容裁切图片
	ImagePicking(ImagePath, CutPath, rect);

	return 0;
}







//String split
vector<string> split(const string &str, const string &pattern){...}

Notes:

    1. The formal parameter of the function is passed in by reference. The formal parameter and the actual parameter are the same thing. Modifying the formal parameter will also change the actual parameter.

    2. char * strc = new char[strlen(str.c_str()) + 1];

        The c_str() function returns a pointer to a regular C string;

        new: The space opened up is on the heap, while the generally declared variables are stored on the stack.

        Generally speaking, when a new space is created in a local function, this space can still be used after the local function call ends, and can be used to pass parameters to the main function

    3. strcpy(strc, str.c_str());

        Copies the character pointed to by str.c_str() to strc.

    4. char* tmpStr = strtok(strc, pattern.c_str());

       In the first call, decompose the string strc  into a set of small strings, pattern.c_str( ) is the delimiter;

       In the second call, strc is set to NULL, and each successful call returns a pointer to the segment to be split.

    5. stof(), string to float, to_string(), int to string.

         

          

Guess you like

Origin blog.csdn.net/weixin_38584764/article/details/124040082