【图像增强】代码C++(有注释)

  • Post author:
  • Post category:其他




图像增强(图像、标签变换一体化)



该代码用于

实例分割

,话不多说直接上代码

定义CImgCoordTransSeg类,头文件imgCoordTransSeg.h和CPP文件imgCoordTransSeg.cpp

#pragma once
#include <opencv2/opencv.hpp>

using namespace cv;
namespace LabTrans
{ 
	enum TransType //变换类型
	{
		TRANSLATION = 0,	//平移
		ROTATE = 1,			//旋转
		FLIP_H = 2,			//水平翻转
		FLIP_V = 3,			//垂直翻转
		FLIP_HV = 4			//水平垂直翻转
	};

	class CImgCoordTransSeg
	{
	private:
		Mat _src;
		int _ang;
		float _t_h;
		float _t_w;
	public:
		/// <summary>
		/// 用于变换图片
		/// </summary>
		/// <param name="src"></param>
		/// <param name="ang"></param>
		/// <param name="t_h"></param>
		/// <param name="t_w"></param>
		CImgCoordTransSeg(Mat src, int ang, float t_h, float t_w) {
			_src = src;
			_ang = ang;
			_t_h = t_h;
			_t_w = t_w;
		}
		/// <summary>
		/// 用于变换txt
		/// </summary>
		/// <param name="ang"></param>
		/// <param name="t_h"></param>
		/// <param name="t_w"></param>
		CImgCoordTransSeg(int ang, float t_h, float t_w, int h, int w) {
			_ang = ang;
			_t_h = t_h;
			_t_w = t_w;
			_src.rows = h;
			_src.cols = w;
		}
		void translation(Mat &translated_image);
		void translation(double &x, double &y);
		void rotate(Mat& rotate_image);
		void rotate(double& x, double& y);
		void myflip(Mat& flip_image, int flipCode);
		void myflip(double& x, double& y, int flipCode);
		void Transform(double &x, double &y, int flags = TRANSLATION);
		void Transform(Mat &dst, int flags = TRANSLATION);
	};
}

#include "imgCoordTransSeg.h"
namespace LabTrans
{ 
	/// <summary>
	/// 图像平移
	/// </summary>
	/// <returns></returns>
	void  CImgCoordTransSeg::translation(Mat &translated_image)
	{
		float warp_values[] = { 1.0, 0.0, _t_w, 0.0, 1.0, _t_h };
		Mat translation_matrix = Mat(2, 3, CV_32F, warp_values);		
		warpAffine(_src, translated_image, translation_matrix, _src.size());		
	}
	/// <summary>
	/// txt坐标平移
	/// </summary>
	/// <returns></returns>
	void CImgCoordTransSeg::translation(double &x, double &y)
	{
		int cols = _src.cols;
		int rows = _src.rows;
		x *= cols;
		y *= rows;
		x = (x + _t_w) / cols;
		y= (y + _t_h) / rows;
	}
	/// <summary>
	/// 图片旋转
	/// </summary>
	/// <returns></returns>
	void CImgCoordTransSeg::rotate(Mat& rotate_image)
	{
		_ang = -_ang;//从逆时针旋转改为顺时针旋转与坐标变换一致
		Mat rotate = getRotationMatrix2D(Point2f(_src.cols / 2, _src.rows / 2), _ang, 1);
		warpAffine(_src, rotate_image, rotate, _src.size());
	}
	/// <summary>
	/// txt坐标旋转
	/// </summary>
	/// <returns></returns>
	void CImgCoordTransSeg::rotate(double&x, double& y) {
		x *= _src.cols;
		y *= _src.rows;
		Point2d a0 = Point2d(_src.cols / 2, _src.rows / 2);
		Point2d b;
		b.x = (x - a0.x) * cos(_ang * CV_PI / 180) - (y - a0.y) * sin(_ang * CV_PI / 180) + a0.x;
		b.y = (x - a0.x) * sin(_ang * CV_PI / 180) + (y - a0.y) * cos(_ang * CV_PI / 180) + a0.y;
		x = b.x / _src.cols;
		y = b.y / _src.rows;
	}
	/// <summary>
	/// 图片翻转
	/// </summary>
	/// <param name="flipCode">1表示水平翻转,0表示垂直翻转,-1表示水平垂直翻转</param>
	/// <returns></returns>
	void CImgCoordTransSeg::myflip(Mat& flip_image, int flipCode)
	{
		flip(_src, flip_image, flipCode);
	}
	/// <summary>
	/// txt坐标翻转
	/// </summary>
	/// <param name="flipCode">1表示水平翻转,0表示垂直翻转,-1表示水平垂直翻转</param>
	/// <returns></returns>
	void CImgCoordTransSeg::myflip(double& x, double& y, int flipCode)
	{
		if (flipCode == 1) {
			x = 1 - x;
		}
		else if (flipCode == 0) {
			y = 1 - y;
		}
		else if (flipCode == -1) {
			x = 1 - x;
			y = 1 - y;
		}
	}

	/// <summary>
	/// 坐标点变换
	/// </summary>
	/// <param name="x">坐标点变换前后横坐标</param>
	/// <param name="y">坐标点变换前后纵坐标</param>
	///<param name="flags">变换类型,默认为平移</param>
	/// <returns></returns>
	void CImgCoordTransSeg::Transform(double &x, double &y, int flags)
	{
		
		if (0 == flags)//平移
		{
			translation(x, y);
		}
		else if (1 == flags) {
			rotate(x, y);
		}
		else if (2 == flags) {
			myflip(x, y, 1);
		}
		else if (3 == flags) {
			myflip(x, y, 0);
		}
		else if (4 == flags) {
			myflip(x, y, -1);
		}
	}

	/// <summary>
	/// 图片变换
	/// </summary>
	/// <param name="dst">变换结果图像</param>
	///<param name="flags">变换类型,默认为平移</param>
	/// <returns></returns>
	void CImgCoordTransSeg::Transform(Mat &dst, int flags)
	{
		if (0 == flags)//平移
		{
			translation(dst);
		}	
		else if (1 == flags) {
			rotate(dst);
		}
		else if (2 == flags) {
			myflip(dst, 1);
		}
		else if (3 == flags) {
			myflip(dst, 0);
		}
		else if (4 == flags) {
			myflip(dst, -1);
		}
	}
}

主函数如下

//labelTrans.cpp

//#include <Windows.h>
#include <fstream>
#include <iostream>
#include <regex>
using namespace std;

#include <opencv2\opencv.hpp>
using namespace cv;

#include "imgCoordTransSeg.h"
using namespace LabTrans;

int main()
{
#pragma region 参数设置 根据需要调整
	int ang = 135;					//旋转角度
	int t_h = 0;
	int t_w = -50;					//平移距离
	string strImgFormat = "png";	//图像格式
	int dstFileNo = 101;			//目标文件起始编号
	string srcPath = "./srcImages/";//源文件路径(图像和txt文件在同一个路径)
	string dstPath = "./dstImages/";//目标文件路径
#pragma endregion
	
	cv::String folderImage = srcPath+"*."+strImgFormat;
	cv::String folderTxt = srcPath + "*.txt";
	std::vector<cv::String> imagePathList;
	std::vector<cv::String> txtPathList;
	cv::glob(folderImage, imagePathList);
	cv::glob(folderTxt, txtPathList);
	int nIndex = 1;						//文件索引号
	int nImgNum = imagePathList.size();	//图像个数
	system("color 70");
	cout << "------------------图像及坐标点转换------------------" << endl;

#pragma region 图像变换
	for (auto src_path : imagePathList)
	{	
		size_t pos1=src_path.find_last_of("\\");
		size_t pos2 = src_path.find_last_of(".");
		string fileName = src_path.substr(pos1 + 1, pos2 - pos1-1);//文件名(不含扩展名)		
		string dstImgFile = dstPath + format("%06d.", dstFileNo) + strImgFormat;//目标图像文件名(含路径和扩展名)
		Mat src = imread(src_path);
		CImgCoordTransSeg imgCt(src, ang, t_h, t_w);
		Mat dst;
		imgCt.Transform(dst, FLIP_HV);	//图像变换		
		imwrite(dstImgFile, dst);
#pragma endregion

#pragma region txt坐标点转换
		ifstream fileIn(srcPath+ fileName+".txt", ios::in);//源txt文件
		ofstream fileOut(dstPath + format("%06d.txt", dstFileNo), ios::out);//目标txt文件
		string strLine;
		regex ws_re("\\s+");//空格
		bool isfirstline = true;
		while (std::getline(fileIn, strLine))
		{
			if (isfirstline) {
				isfirstline = false;
			}
			else {
				fileOut << "\n";
			}
			vector<string> strVecv(sregex_token_iterator(strLine.begin(), strLine.end(), ws_re, -1),sregex_token_iterator());//使用正则表达式匹配“ ”空格字符,-1为取空格之间的子字符串,使用分配器存入容器中
			size_t vLen = strVecv.size();
			fileOut << stoi(strVecv[0]) << " ";
			double x, y;
			for (auto i = 1; i < vLen; i += 2)
			{	
				x = stod(strVecv[i]);
				y = stod(strVecv[i + 1]);
				imgCt.Transform(x, y, FLIP_HV);	//坐标变换

				if (vLen - 2 == i)
				{
					fileOut << x << " " << y;
				}
				else
				{
					fileOut << x << " " << y << " ";
				}
			}
		}
#pragma endregion	
		
		std::cout << "   Processing " << fileName <<": "<< nIndex*1.0 / nImgNum * 100 << "%|      |"
			<< nIndex << "/" << nImgNum << "\r";//进度条
		
		nIndex++;
		dstFileNo++;
	}
	cout << endl;
	system("pause");
	return 0;
}



版权声明:本文为weixin_44359628原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。