基于模板的手写数字识别

【实验原理】
读取标准化后的数字0~9,二值化,对每个数字进行等分区域分割,统计每个区域内的黑色像素点的个数,即为特征初值。采用欧式距离的模板匹配法判断数字。
【实验要求】
给定数字0-9的原始样本集合,每个数字都有10个大小为240240的样本图像。要求如下:
1、将上述图像切分成标准图像库,存储为文件。
2、对每个数字进行等分区间分割(分割区间至少大于等于10
10)
3、给出统计结果:每个区域内的黑色像素点个数值以及占总量的百分比,显示出计算结果。
4、采用欧氏距离模板匹配法,给出识别结果。
5、从统计意义上,给出每个数字的识别率。

#include
#include
#include
#include 
#include 
#include  
#include  
#include  
using namespace cv;
using namespace std;
int main()
{
    //这里的路径根据自己的情况更改
	std::string pattern_bmp1 = "C:\\Users\\source\\手写数字数据集\\测试\\*.bmp";
	std::vector<cv::String> image_files1;
	cv::glob(pattern_bmp1, image_files1);
	if (image_files1.size() == 0) {
		std::cout << "No image files[bmp]" << std::endl;
		return 0;
	}
	//批量导出测试图像
	int dd = -1;//记录当前识别的数字
	int c[11] = {0};  //记录识别正确率
	for (unsigned int frame1 = 0; frame1 < image_files1.size(); ++frame1)
		//image_file.size()代表文件中总共的图片个数
	{
		
		dd++;
		Mat img = cv::imread(image_files1[frame1]);
		Mat  imgGray, result;
		cvtColor(img, imgGray, CV_BGR2GRAY);
		threshold(imgGray, result, 126, 255, CV_THRESH_BINARY);
		int height = result.rows;
		int width = result.cols;
		int t = 0;
		int m = result.cols / 4;    //m*n是切割后子图像的个数
		int n = result.rows / 4;
		Mat imageGray_cut;
		int a[49];
		for (int j = 0; j < n; j++)
		{
			for (int i = 0; i < m; i++)
			{
				Rect rect(i * 4, j * 4, 4, 4);
				imageGray_cut = Mat(result, rect);
				//将图像进行分割
				Scalar ss = sum(imageGray_cut) / 255;
				if (ss[0] <= 1)
					a[t] = 0;
				else
					a[t] = 1;
				t++;
				//得到01序列
			}
		}
		double mindist = 100.0;
		int min = 0;
		//这里的路径根据自己的情况更改
		std::string pattern_bmp = "C:\\Users\\source\\手写数字数据集\\样本\\*.bmp";
		std::vector<cv::String> image_files;
		cv::glob(pattern_bmp, image_files);
		if (image_files.size() == 0) {
			std::cout << "No image files[bmp]" << std::endl;
			return 0;
		}
		double dist[900];
		int qq = 0;
		for (unsigned int frame = 0; frame < image_files.size(); ++frame) {//image_file.size()代表文件中总共的图片个数
			{Mat image = cv::imread(image_files[frame]);
			Mat imgGray1, result1;
			cvtColor(image, imgGray1, CV_BGR2GRAY);
			threshold(imgGray1, result1, 126, 255, CV_THRESH_BINARY);			
			int height1 = result1.rows;
			int width1 = result1.cols;
			double qiuhe = 0.0;
			int t1 = 0;
			int m1 = result1.cols / 4;   
			int n1 = result1.rows / 4;
			Mat imageGray_cut1;
			int b[49];
			for (int j1 = 0; j1 < n1; j1++)
			{
				for (int i1 = 0; i1 < m1; i1++)
				{
					Rect rect(i1 * 4, j1 * 4, 4, 4);
					imageGray_cut1 = Mat(result1, rect);
					Scalar sss = sum(imageGray_cut1) / 255;
					if (sss[0] <=1)
						b[t1] = 0;
					else
						b[t1] = 1;
					t1++;
				}
			}
			for (int qw = 0; qw < 49; qw++)
			{
				qiuhe = qiuhe + pow((a[qw] - b[qw]), 2);
			}
			dist[qq] = pow(qiuhe, 0.5);
			if (dist[qq] < mindist)
			{
				mindist = dist[qq];
				min = qq;
			}
			//用于比较欧式距离
			}
			qq++;
		}
		min = min / 90;
		printf("当前的数字是:%d,识别的数字是:%d\n",dd/10, min);
		//数字的识别结果
		int ssss = dd / 10;
		if (ssss == min)
			c[ssss] = c[ssss] + 1;			
	}
	printf("数字0的识别正确率:%d%%\n", c[0]*  10);
	printf("数字1的识别正确率:%d%%\n", c[1] * 10);
	printf("数字2的识别正确率:%d%%\n", c[2] * 10);
	printf("数字3的识别正确率:%d%%\n", c[3] * 10);
	printf("数字4的识别正确率:%d%%\n", c[4] * 10);
	printf("数字5的识别正确率:%d%%\n", c[5] * 10);
	printf("数字6的识别正确率:%d%%\n", c[6] * 10);
	printf("数字7的识别正确率:%d%%\n", c[7] * 10);
	printf("数字8的识别正确率:%d%%\n", c[8] * 10);
	printf("数字9的识别正确率:%d%%\n", c[9] * 10);
	//数字的识别正确率
	waitKey();
	return 0;	
}

train-images文件夹中后缀0至89的图片选作训练集 train-images文件夹中缀90至99的图片选作样本集

你可能感兴趣的:(模板方法模式)