您的位置:首页 > 理论基础 > 计算机网络

用训练好的神经网络识别字符

2016-11-20 16:49 309 查看


在sample文件夹下放了一些测试字符,都是20*20的。用来识别的。同时在工程目录下放置了训练好的神经网络xml文件。如下图:



#include"opencv2/opencv.hpp"
#include<iostream>
#include<io.h>

using namespace std;
using namespace cv;

const int numCharacter=10;  //这里只有0-9共10种字符
CvANN_MLP ann;

vector<string> getFiles(const string &folder,const bool all /* = true */)
{
vector<string> files;
list<string> subfolders;
subfolders.push_back(folder);

while (!subfolders.empty()) {
string current_folder(subfolders.back());

if (*(current_folder.end() - 1) != '/') {    //确保地址是 “ ..../*” 结尾的
current_folder.append("/*");
}
else {
current_folder.append("*");
}

subfolders.pop_back();

struct _finddata_t file_info;
long file_handler = _findfirst(current_folder.c_str(), &file_info);

while (file_handler != -1)
{
if (all &&
(!strcmp(file_info.name, ".") || !strcmp(file_info.name, ".."))) {
if (_findnext(file_handler, &file_info) != 0) break;
continue;
}

if (file_info.attrib & _A_SUBDIR)
{
// it's a sub folder
if (all)
{
// will search sub folder
string folder(current_folder);
folder.pop_back();         //  就是减去最后的*     string 的pop_back Delete last character   Erases the last character of the string, effectively reducing its length by one.
folder.append(file_info.name);

subfolders.push_back(folder.c_str());
}
}
else
{
// it's a file
string file_path;
// current_folder.pop_back();
file_path.assign(current_folder.c_str()).pop_back();
file_path.append(file_info.name);

files.push_back(file_path);
}

if (_findnext(file_handler, &file_info) != 0) break;
}  // while
_findclose(file_handler);
}

return files;
}

// !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t)
{
int sz = (t) ? img.rows : img.cols;
Mat mhist = Mat::zeros(1, sz, CV_32F);

for (int j = 0; j<sz; j++) {
Mat data = (t) ? img.row(j) : img.col(j);
mhist.at<float>(j) = countNonZero(data);	//统计这一行或一列中,非零元素的个数,并保存到mhist中
}

//Normalize histogram
double min, max;
minMaxLoc(mhist, &min, &max);

if (max>0)
mhist.convertTo(mhist, -1, 1.0f / max, 0);//用mhist直方图中的最大值,归一化直方图

return mhist;
}

Mat features(Mat in, int sizeData)
{
//Histogram features

Mat vhist = ProjectedHistogram(in, 0);
Mat hhist = ProjectedHistogram(in, 1);
//Low data feature
Mat lowData;
resize(in, lowData, Size(sizeData, sizeData));

//Last 10 is the number of moments components
int numCols = vhist.cols + hhist.cols + lowData.cols*lowData.cols;
//int numCols = vhist.cols + hhist.cols;
Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j = 0;
for (int i = 0; i<vhist.cols; i++)
{
out.at<float>(j) = vhist.at<float>(i);
j++;
}
for (int i = 0; i<hhist.cols; i++)
{
out.at<float>(j) = hhist.at<float>(i);
j++;
}
for (int x = 0; x<lowData.cols; x++)
{
for (int y = 0; y<lowData.rows; y++) {
out.at<float>(j) = (float)lowData.at<unsigned char>(x, y);
j++;
}
}
//if(DEBUG)
//	cout << out << "\n===========================================\n";
return out;
}

int recog(Mat features)
{
int result = -1;
Mat Predict_result(1, numCharacter, CV_32FC1);
ann.predict(features, Predict_result);
Point maxLoc;
double maxVal;

minMaxLoc(Predict_result, 0, &maxVal, 0, &maxLoc);

return maxLoc.x;
}

void main()
{
Mat SrcImg;
ann.load("MyAnn.xml");  //加载训练好的神经网络xml文件

string path="D:/CC/test_Ann/test_Ann/Sample";

vector<string> str;
str=getFiles(path,1);//得到每个测试图片的路径名
for(int i=0;i<str.size();i++)
{  //每次按键盘显示下一个字符
SrcImg=imread(str[i],0);
imshow("1",SrcImg);
Mat ImgFeature=features(SrcImg,10);
cout<<"结果: "<< recog(ImgFeature)<<endl;

waitKey(0);
}

}



至于怎么训练得到xml文件,还有很大的学问,下一篇写吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: