【实验原理】
读取标准化后的数字0~9,二值化,对每个数字进行等分区域分割,统计每个区域内的黑色像素点的个数,即为特征初值。采用欧式距离的模板匹配法判断数字。
【实验要求】
给定数字0-9的原始样本集合,每个数字都有10个大小为240240的样本图像。要求如下:
1、将上述图像切分成标准图像库,存储为文件。
2、对每个数字进行等分区间分割(分割区间至少大于等于1010)
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的图片选作样本集