目录

主函数 

子程序

子函数 


主函数 

#include <opencv2/opencv.hpp>
#include <opencv2\\core\\core.hpp>
#include <opencv2\\highgui\\highgui.hpp>
#include <opencv2\\imgproc\\imgproc.hpp>
#include <iostream>

#include \"Water_Cut.h\"
#include \"Feature.h\"


using namespace cv;
using namespace std;
using namespace cv::ml;

Feature feature_class;

int main()
{	
// 训练——训练时候关闭测试
#if 0
	// 遍历图片——为了循环提取特征用
	string train_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\训练\";
	string train_img_namehead = \"test\";
	string train_img_type = \"bmp\";
	//size_t train_img_num = 4;
	string img_name = train_img_dir + \"\\\\\" + \"*.\" + train_img_type;	//cout << img_name << endl;
	int train_img_num = feature_class.read_images_in_folder(img_name);
	cout << \"训练图个数:\" << train_img_num << endl;

	// 训练用的输入和标签
	Mat trainmat;
	trainmat = cv::Mat::zeros(train_img_num, 32, CV_32FC1);
	Mat labelmat;
	labelmat = cv::Mat::zeros(train_img_num, 1, CV_32SC1);

	// 遍历图并提取特征
	vector<Mat> train_img = feature_class.data_search(train_img_dir, train_img_namehead, train_img_type, train_img_num);
	for (size_t i = 0; i < train_img_num; i++)
	{
		resize(train_img[i], train_img[i], Size(train_img[i].cols / 2, train_img[i].rows / 2));
		namedWindow(\"vetmat\", 0);
		imshow(\"vetmat\", train_img[i]);//train_img[i].clone();
		waitKey(0);

		// 图像分割
		Mat src = train_img[i].clone();
		Mat dst = Mat::zeros(train_img[i].size(), CV_8UC3);
		Mat edge = Mat::zeros(train_img[i].size(), CV_8UC3);
		Water_Cut(src, dst, edge);

		// 图像特征_HU
		Mat hu_dst = dst.clone();
		double Hu[7] = { 0 };
		feature_class.feature_hu(hu_dst, Hu);

		// 图像特征_COLOR
		Mat color_dst = dst.clone();
		float Mom[9] = { 0 };
		feature_class.feature_color(color_dst, Mom);

		// 图像特征_GLCM
		Mat glcm_dst = dst.clone();
		cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY);
		float glcm_data[16] = { 0 };
		feature_class.feature_glcm(glcm_dst, glcm_data);

		float train_data[32] = { 0 };

		for (size_t j = 0; j < 7; j++)
		{
			train_data[j] = (float)Hu[j];

		}
		for (size_t j = 0; j < 9; j++)
		{
			train_data[7 + j] = (float)Mom[j];

		}
		for (size_t j = 0; j < 16; j++)
		{
			train_data[16 + j] = (float)glcm_data[j];
		}
		


		vector<float> traindata; //	特征值——一类(一张图)的特征
		for (size_t k = 0; k < 32; k++)
		{
			traindata.push_back(train_data[k]);
		}		
		std::cout << \"traindata size:\";
		std::cout << traindata.size() << endl;

		
		for (size_t j = 0; j < traindata.size(); j++)
		{
			trainmat.at<float>(i, j) = traindata[j];
		}
		labelmat.at<int>(i, 0) = i + 1;	//每张一类
	}
		
	// 训练的初始化
	Ptr<SVM> svm = SVM::create();
	svm->setType(SVM::C_SVC);
	svm->setKernel(SVM::LINEAR);
	svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
	std::cout << \"开始训练\" << endl;
	svm->train(trainmat, ROW_SAMPLE, labelmat);

	std::cout << \"开始结束\" << endl;
	svm->save(\"svm. \");
#endif

// 测试——测试时候关闭训练
#if 1 

	// 遍历测试文件
	// 遍历图片——为了循环提取特征用
	//string test_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\测试\\\\方格1号\";
	//string test_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\测试\\\\花纹2号\";
	//string test_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\测试\\\\空纹理3号\";
	//string test_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\测试\\\\条纹4号\";
	string test_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\测试\\\\\";

	string test_img_namehead = \"test\";
	string test_img_type = \"bmp\";
	string img_name = test_img_dir + \"\\\\\" + \"*.\" + test_img_type;	//cout << img_name << endl;
	int test_img_num = feature_class.read_images_in_folder(img_name);
	std::cout << \"测试图个数:\" << test_img_num << endl;

	// 训练用的输入和标签
	Mat testmat;
	testmat = cv::Mat::zeros(test_img_num, 32, CV_32F);

	// 遍历图并提取特征
	vector<Mat> test_img = feature_class.data_search(test_img_dir, test_img_namehead, test_img_type, test_img_num);
	for (size_t i = 0; i < test_img_num; i++)
	{
		resize(test_img[i], test_img[i], Size(test_img[i].cols / 2, test_img[i].rows / 2));
		cv::namedWindow(\"vetmat\", 0);
		cv::imshow(\"vetmat\", test_img[i]);//test_img[i].clone();		

		// 图像分割
		Mat src = test_img[i].clone();
		Mat dst = Mat::zeros(test_img[i].size(), CV_8UC3);
		Mat edge = Mat::zeros(test_img[i].size(), CV_8UC3);
		Water_Cut(src, dst, edge);

		// 图像特征_HU
		Mat hu_dst = dst.clone();
		double Hu[7] = { 0 };
		feature_class.feature_hu(hu_dst, Hu);

		// 图像特征_COLOR
		Mat color_dst = dst.clone();
		float Mom[9] = { 0 };
		feature_class.feature_color(color_dst, Mom);

		// 图像特征_GLCM
		Mat glcm_dst = dst.clone();
		cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY);
		float glcm_data[16] = { 0 };
		feature_class.feature_glcm(glcm_dst, glcm_data);

		cv::waitKey();
		float test_data[32] = { 0 };

		for (size_t j = 0; j < 7; j++)
		{
			test_data[j] = (float)Hu[j];

		}
		for (size_t j = 0; j < 9; j++)
		{
			test_data[7 + j] = (float)Mom[j];

		}
		for (size_t j = 0; j < 16; j++)
		{
			test_data[16 + j] = (float)glcm_data[j];
		}

		vector<float> testdata; //	特征值——一类(一张图)的特征
		for (size_t k = 0; k < 32; k++)
		{
			testdata.push_back(test_data[k]);
		}
		std::cout << \"testdata size:\";
		std::cout << testdata.size() << endl;


		for (size_t j = 0; j < testdata.size(); j++)
		{
			testmat.at<float>(i, j) = testdata[j];
		}
		
	}
	Ptr<SVM> svmtest = Algorithm::load<SVM>(\"svm. \"); // SVM::load()是一个静态函数,不能单独用
	Mat result;
	float temp = svmtest->predict(testmat, result);
	std::cout << \"分类结果\" << endl;
	std::cout << result << endl;
	for (size_t i = 0; i < test_img_num; i++)
	{
		int a = result.at<Point2f>(i, 0).x;
		std::cout << \"最终分类为:\" << \"第\" << a << \"号瓷砖\" << endl;
	}
#endif
	
	system(\"pause\");
	return 0;
}

子程序

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include \"time.h\"

using namespace cv;
using namespace std;
using namespace cv::ml;

class Feature
{
public:

	/*
	第一步:建立类
	#include <opencv2/opencv.hpp>
	#include <iostream>
	#include <vector>
	#include \"time.h\"

	using namespace cv;
	using namespace std;
	
	第二步:包含类
	Feature feature_class;

	第三步:
	集合颜色+形状+纹理
	// 图像特征_HU
	Mat hu_dst = dst.clone();
	double Hu[7] = { 0 };
	feature_class.feature_hu(hu_dst, Hu);

	// 图像特征_COLOR
	Mat color_dst = dst.clone();
	float Mom[9] = { 0 };
	feature_class.feature_color(color_dst, Mom);

	// 图像特征_GLCM
	Mat glcm_dst = dst.clone();
	cv::cvtColor(glcm_dst, glcm_dst, CV_RGB2GRAY);
	float glcm_data[16] = { 0 };
	feature_class.feature_glcm(glcm_dst, glcm_data);

	第四步:
	// 特征集合7+9+16
	float test_data[32] = { 0 };
	for (size_t j = 0; j < 7; j++)
	{
	test_data[j] = (float)Hu[j];

	}
	for (size_t j = 0; j < 9; j++)
	{
	test_data[7 + j] = (float)Mom[j];

	}
	for (size_t j = 0; j < 16; j++)
	{
	test_data[16 + j] = (float)glcm_data[j];
	}

	*/
	/* 【颜色】 */
	// 颜色 计算三阶矩
	double calc3orderMom(Mat &channel)  //计算三阶矩
	{
		uchar *p;
		double mom = 0;
		double m = mean(channel)[0];    //计算单通道图像的均值
		int nRows = channel.rows;
		int nCols = channel.cols;
		if (channel.isContinuous())     //连续存储有助于提升图像扫描速度
		{
			nCols *= nRows;
			nRows = 1;
		}
		for (int i = 0; i < nRows; i++) //计算立方和
		{
			p = channel.ptr<uchar>(i);
			for (int j = 0; j < nCols; j++)
				mom += pow((p[j] - m), 3);
		}
		float temp;
		temp = cvCbrt((float)(mom / (nRows*nCols)));    //求均值的立方根
		mom = (double)temp;
		return mom;
	}
	// 颜色 计算9个颜色矩:3个通道的1、2、3阶矩
	double *colorMom(Mat &img)
	{
		double *Mom = new double[9];    //存放9个颜色矩
		if (img.channels() != 3)
			std::cout << \"Error,input image must be a color image\" << endl;
		Mat b(img.rows, img.cols, CV_8U);
		Mat r(img.rows, img.cols, CV_8U);
		Mat g(img.rows, img.cols, CV_8U);
		Mat channels[] = { b, g, r };
		split(img, channels);
		//cv::imshow(\"r\", channels[0]);
		//cv::imshow(\"g\", channels[1]);
		//cv::imshow(\"b\", channels[2]);
		//waitKey(0);
		Mat tmp_m, tmp_sd;
		//计算b通道的颜色矩
		meanStdDev(b, tmp_m, tmp_sd);
		Mom[0] = tmp_m.at<double>(0, 0);
		Mom[3] = tmp_sd.at<double>(0, 0);
		Mom[6] = calc3orderMom(b);
		//  cout << Mom[0] << \" \" << Mom[1] << \" \" << Mom[2] << \" \" << endl;
		//计算g通道的颜色矩
		meanStdDev(g, tmp_m, tmp_sd);
		Mom[1] = tmp_m.at<double>(0, 0);
		Mom[4] = tmp_sd.at<double>(0, 0);
		Mom[7] = calc3orderMom(g);
		//  cout << Mom[3] << \" \" << Mom[4] << \" \" << Mom[5] << \" \" << endl;
		//计算r通道的颜色矩
		meanStdDev(r, tmp_m, tmp_sd);
		Mom[2] = tmp_m.at<double>(0, 0);
		Mom[5] = tmp_sd.at<double>(0, 0);
		Mom[8] = calc3orderMom(r);
		//  cout << Mom[6] << \" \" << Mom[7] << \" \" << Mom[8] << \" \" << endl;
		return Mom;//返回颜色矩数组
	}
	// 颜色 
	bool feature_color(Mat src, float Mom[9])
	{
		if (src.channels() == 3)
		{
			// 图像特征_COLOR
			Mat color_dst = src.clone();
			cv::cvtColor(color_dst, color_dst, CV_RGB2HSV);
			double *MOM;
			MOM = colorMom(color_dst);
			for (int i = 0; i < 9; i++)
			{
				std::cout << (float)MOM[i] << endl;
				Mom[i] = (float)MOM[i];
			}
			return  true;
		}
		else
		{
			std::cout << \"channels!=3\";
			return false;
		}
	}


	/* 【形状】 */
	bool feature_hu(Mat src, double Hu[7])
	{
		if (src.channels() == 3)
		{
			// 图像特征_HU
			Mat hu_dst = src.clone();
			cv::cvtColor(hu_dst, hu_dst, CV_RGB2GRAY);
			Canny(hu_dst, hu_dst, 0, 120);
			//double Hu[7];       //存储得到的Hu矩阵
			Moments mo = moments(hu_dst);//矩变量
			HuMoments(mo, Hu);
			for (int i = 0; i < 7; i++)
			{
				std::cout << (float)Hu[i] << endl;
			}
			return true;
		}
		else if ((src.channels() == 1))
		{
			Mat hu_dst = src.clone();
			Canny(hu_dst, hu_dst, 0, 120);
			//double Hu[7];       //存储得到的Hu矩阵
			Moments mo = moments(hu_dst);//矩变量
			HuMoments(mo, Hu);
			for (int i = 0; i < 7; i++)
			{
				std::cout << (float)Hu[i] << endl;
			}
			return true;
		}
		else
		{
			return false;
		}
	}


	// 纹理
	const int gray_level = 16;//纹理区域块的大小,通常将图像划分成若干个纹理块计算
	vector<double> glamvalue;//全局变量

	//【】第一步:j计算共生矩阵
	void getglcm_0(Mat& input, Mat& dst)//0度灰度共生矩阵
	{
		Mat src = input;
		CV_Assert(1 == src.channels());
		src.convertTo(src, CV_32S);
		int height = src.rows;
		int width = src.cols;
		int max_gray_level = 0;
		for (int j = 0; j < height; j++)//寻找像素灰度最大值
		{
			int* srcdata = src.ptr<int>(j);
			for (int i = 0; i < width; i++)
			{
				if (srcdata[i] > max_gray_level)
				{
					max_gray_level = srcdata[i];
				}
			}
		}
		max_gray_level++;//像素灰度最大值加1即为该矩阵所拥有的灰度级数
		if (max_gray_level > 16)//若灰度级数大于16,则将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
		{
			for (int i = 0; i < height; i++)
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width; j++)
				{
					srcdata[j] = (int)srcdata[j] / gray_level;
				}
			}

			dst.create(gray_level, gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height; i++)
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width - 1; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata[j + 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
		else//若灰度级数小于16,则生成相应的灰度共生矩阵
		{
			dst.create(max_gray_level, max_gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height; i++)
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width - 1; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata[j + 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
	}

	void getglcm_45(Mat& input, Mat& dst)//45度灰度共生矩阵
	{
		Mat src = input;
		CV_Assert(1 == src.channels());
		src.convertTo(src, CV_32S);
		int height = src.rows;
		int width = src.cols;
		int max_gray_level = 0;
		for (int j = 0; j < height; j++)
		{
			int* srcdata = src.ptr<int>(j);
			for (int i = 0; i < width; i++)
			{
				if (srcdata[i] > max_gray_level)
				{
					max_gray_level = srcdata[i];
				}
			}
		}
		max_gray_level++;
		if (max_gray_level > 16)
		{
			for (int i = 0; i < height; i++)//将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width; j++)
				{
					srcdata[j] = (int)srcdata[j] / gray_level;
				}
			}

			dst.create(gray_level, gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 0; j < width - 1; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j + 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
		else
		{
			dst.create(max_gray_level, max_gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 0; j < width - 1; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j + 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
	}

	void getglcm_90(Mat& input, Mat& dst)//90度灰度共生矩阵
	{
		Mat src = input;
		CV_Assert(1 == src.channels());
		src.convertTo(src, CV_32S);
		int height = src.rows;
		int width = src.cols;
		int max_gray_level = 0;
		for (int j = 0; j < height; j++)
		{
			int* srcdata = src.ptr<int>(j);
			for (int i = 0; i < width; i++)
			{
				if (srcdata[i] > max_gray_level)
				{
					max_gray_level = srcdata[i];
				}
			}
		}
		max_gray_level++;
		if (max_gray_level > 16)
		{
			for (int i = 0; i < height; i++)//将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width; j++)
				{
					srcdata[j] = (int)srcdata[j] / gray_level;
				}
			}

			dst.create(gray_level, gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 0; j < width; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
		else
		{
			dst.create(max_gray_level, max_gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 0; j < width; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
	}

	void getglcm_135(Mat& input, Mat& dst)//135度灰度共生矩阵
	{
		Mat src = input;
		CV_Assert(1 == src.channels());
		src.convertTo(src, CV_32S);
		int height = src.rows;
		int width = src.cols;
		int max_gray_level = 0;
		for (int j = 0; j < height; j++)
		{
			int* srcdata = src.ptr<int>(j);
			for (int i = 0; i < width; i++)
			{
				if (srcdata[i] > max_gray_level)
				{
					max_gray_level = srcdata[i];
				}
			}
		}
		max_gray_level++;
		if (max_gray_level > 16)
		{
			for (int i = 0; i < height; i++)//将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
			{
				int*srcdata = src.ptr<int>(i);
				for (int j = 0; j < width; j++)
				{
					srcdata[j] = (int)srcdata[j] / gray_level;
				}
			}

			dst.create(gray_level, gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 1; j < width; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j - 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
		else
		{
			dst.create(max_gray_level, max_gray_level, CV_32SC1);
			dst = Scalar::all(0);
			for (int i = 0; i < height - 1; i++)
			{
				int*srcdata = src.ptr<int>(i);
				int*srcdata1 = src.ptr<int>(i + 1);
				for (int j = 1; j < width; j++)
				{
					int rows = srcdata[j];
					int cols = srcdata1[j - 1];
					dst.ptr<int>(rows)[cols]++;
				}
			}
		}
	}

	// 【】第二步:计算纹理特征	// 特征值计算—— double& Asm, double& Con, double& Ent, double& Idm
	void feature_computer(Mat&src, float& Asm, float& Con, float& Ent, float& Idm)//计算特征值
	{
		int height = src.rows;
		int width = src.cols;
		int total = 0;
		for (int i = 0; i < height; i++)
		{
			int*srcdata = src.ptr<int>(i);
			for (int j = 0; j < width; j++)
			{
				total += srcdata[j];//求图像所有像素的灰度值的和
			}
		}

		Mat copy;
		copy.create(height, width, CV_64FC1);
		for (int i = 0; i < height; i++)
		{
			int*srcdata = src.ptr<int>(i);
			float*copydata = copy.ptr<float>(i);
			for (int j = 0; j < width; j++)
			{
				copydata[j] = (float)srcdata[j] / (float)total;//图像每一个像素的的值除以像素总和
			}
		}


		for (int i = 0; i < height; i++)
		{
			float*srcdata = copy.ptr<float>(i);
			for (int j = 0; j < width; j++)
			{
				Asm += srcdata[j] * srcdata[j];								//能量
				if (srcdata[j]>0)
				{
					Ent -= srcdata[j] * log(srcdata[j]);					//熵   
				}
				Con += (float)(i - j)*(float)(i - j)*srcdata[j];			//对比度
				Idm += srcdata[j] / (1 + (float)(i - j)*(float)(i - j));	//逆差矩
			}
		}
	}

	// 【】融合第一、二步
	/*
	Mat src_gray;
	float data[16] = {0};
	*/
	void feature_glcm(Mat src_gray, float data[16])
	{
		Mat dst_0, dst_90, dst_45, dst_135;

		getglcm_0(src_gray, dst_0);
		float  asm_0 = 0, con_0 = 0, ent_0 = 0, idm_0 = 0;
		feature_computer(dst_0, asm_0, con_0, ent_0, idm_0);


		getglcm_45(src_gray, dst_45);
		float  asm_45 = 0, con_45 = 0, ent_45 = 0, idm_45 = 0;
		feature_computer(dst_45, asm_45, con_45, ent_45, idm_45);


		getglcm_90(src_gray, dst_90);
		float  asm_90 = 0, con_90 = 0, ent_90 = 0, idm_90 = 0;
		feature_computer(dst_90, asm_90, con_90, ent_90, idm_90);


		getglcm_135(src_gray, dst_135);
		float  asm_135 = 0, con_135 = 0, ent_135 = 0, idm_135 = 0;
		feature_computer(dst_135, asm_135, con_135, ent_135, idm_135);

		float AMS[4] = { asm_0, asm_45, asm_90, asm_135 };
		float COM[4] = { con_0, con_45, con_90, con_135 };
		float ENT[4] = { ent_0, ent_45, ent_90, ent_135 };
		float IDM[4] = { idm_0, idm_45, idm_90, idm_135 };

		float glcm_data[16] = {
			asm_0, asm_45, asm_90, asm_135,
			con_0, con_45, con_90, con_135,
			ent_0, ent_45, ent_90, ent_135,
			idm_0, idm_45, idm_90, idm_135
		};

		/*std::cout << \"特征数据:\" << endl;*/
		for (size_t i = 0; i < 16; i++)
		{
			data[i] = glcm_data[i];
			//std::cout << data[i] << \" \";
		}
	}




	// 读取当前文件夹图片的个数子程序
	/*
	cv::String pattern = \"./save/*.bmp\";
	int cout = read_images_in_folder(pattern);
	*/
	size_t read_images_in_folder(cv::String pattern)//读取当前指定目录的图片的个数
	{
		vector<cv::String> fn;
		glob(pattern, fn, false);//OpenCV自带一个函数glob()可以遍历文件
		size_t count = fn.size(); //number of png files in images folder	
		return count;
	}


	// 【】文件检索
	/*
	string train_img_dir = \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\样品\\\\训练\";
	string train_img_namehead = \"test\";
	string train_img_type = \"bmp\";
	size_t train_img_num = 4;
	vector<Mat> train_img = data_search(train_img_dir, train_img_namehead, train_img_type, train_img_num);
	for (size_t i = 0; i < train_img_num; i++)
	{
	namedWindow(\"vetmat\", 0);
	imshow(\"vetmat\", train_img[i]);
	waitKey(0);
	}
	*/
	vector<Mat> data_search(string &img_dir, string &img_namehead, string &img_type, size_t n)
	{
		float train_data[4][16] = { 0 };
		vector<Mat> src;
		for (int i = 0; i < n; i++)
		{
			string pos;
			stringstream ss;
			ss << i;
			ss >> pos;
			string img_name = img_dir + \"\\\\\" + img_namehead + pos + \".\" + img_type;	//cout << img_name << endl;
			Mat outsrc = imread(img_name);
			src.push_back(outsrc);
		}
		return src;
	}

private:

};


子函数 

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

using namespace cv;
using namespace std;

/*遗留问题:两点的确立*/
void Water_Cut(InputArray& src, OutputArray& dst, OutputArray& edge)
{
	Mat srcImage;
	src.copyTo(srcImage);
	//cv::resize(srcImage, srcImage, Size(srcImage.cols / 2, srcImage.rows / 2));
	cv::namedWindow(\"resImage\", 0);
	cv::imshow(\"resImage\", srcImage);
	//waitKey();
	// 【mask两点】	
	//mask的第一点 maskImage
	Mat maskImage;
	maskImage = Mat(srcImage.size(), CV_8UC1);  // 掩模,在上面做标记,然后传给findContours
	maskImage = Scalar::all(0);
	Point point1(0, 0), point2(100, 10);
	//line(maskImage, point1, point2, Scalar::all(255), 5, 8, 0);
	circle(maskImage, point1, 10, Scalar::all(255), 100);
	

	//mask的第二点 maskImage
	Point point3(srcImage.cols / 2, srcImage.rows / 2), point4(srcImage.cols / 2+200, srcImage.rows / 2);
	//line(maskImage, point3, point4, Scalar::all(255), 5, 8, 0);
	circle(maskImage, point3, 10, Scalar::all(255), 100);

	/*namedWindow(\"resImage\", 0);
	imshow(\"resImage\", maskImage);
	waitKey();*/

	// 【轮廓】
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(maskImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);

	// 【分水岭】
	// 参数二:maskWaterShed(CV_32S)
	Mat maskWaterShed;  // watershed()函数的参数
	maskWaterShed = Mat(maskImage.size(), CV_32S);//空白掩码	maskWaterShed
	maskWaterShed = Scalar::all(0);

	/* 在maskWaterShed上绘制轮廓 */
	for (int index = 0; index < contours.size(); index++)
		drawContours(maskWaterShed, contours, index, Scalar::all(index + 1), -1, 8, hierarchy, INT_MAX);

	/* 如果imshow这个maskWaterShed,我们会发现它是一片黑,原因是在上面我们只给它赋了1,2,3这样的值,通过代码80行的处理我们才能清楚的看出结果 */
	// 参数一:srcImage(CV_8UC3)
	watershed(srcImage, maskWaterShed);  //int index = maskWaterShed.at<int>(row, col);操作

	// 【随机生成几种颜色】
	vector<Vec3b> colorTab;
	for (int i = 0; i < contours.size(); i++)
	{
		int b = theRNG().uniform(0, 255);
		int g = theRNG().uniform(0, 255);
		int r = theRNG().uniform(0, 255);

		colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
	}
	Mat dst_ = Mat::zeros(maskWaterShed.size(), CV_8UC3);
	Mat dst_edge = Mat::zeros(maskWaterShed.size(), CV_8UC3);
	int index = maskWaterShed.at<int>(maskWaterShed.rows / 2, maskWaterShed.cols / 2);
	int index_temp = 0;
	for (int i = 0; i < maskWaterShed.rows; i++)
	{
		for (int j = 0; j < maskWaterShed.cols; j++)
		{
			index_temp = maskWaterShed.at<int>(i, j);
			//cout << index_temp << endl;
			if (index_temp == index)//取中心的标签区域
			{
				dst_edge.at<Vec3b>(i, j) = Vec3b((uchar)255, (uchar)255, (uchar)255); //colorTab[index - 1];
				dst_.at<Vec3b>(i, j) = srcImage.at<Vec3b>(i, j);
			}
		}
	}
	cv::namedWindow(\"分割结果\", 0);
	cv::imshow(\"分割结果\", dst_);
	imwrite(\"条纹1.bmp\", dst_);

	/*Mat dst_add;
	addWeighted(dst_edge, 0.3, srcImage, 0.7, 0, dst_add);
	namedWindow(\"加权结果\", 0);
	imshow(\"加权结果\", dst_add);*/

	cv::namedWindow(\"连通域\", 0);
	cv::imshow(\"连通域\", dst_edge);
	imwrite(\"条纹1_.bmp\", dst_edge);

	dst_.copyTo(dst);
	dst_edge.copyTo(edge);
}
收藏 打印