运行环境:Linux Ubuntu12.04
opencv 2.3.1
包含头文件、命名空间:
</pre><pre name="code" class="cpp">#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>
#include <opencv2/opencv.hpp>
#include "qdebug.h"
using namespace std;
using namespace cv;
代码
const string fileform = ".png";
const string perfileReadPath = "../sourse";
const string perfileSavePath = "../resize";
const int sample_mun_perclass = 20;
const int class_mun = 10;
const int image_cols = 8;
const int image_rows = 16;
string fileReadName,
fileReadPath,
fileSaveName,
fileSavePath;
char t[256];
char temp[256];
float trainingData[class_mun*sample_mun_perclass][image_rows*image_cols] = {{0}};
float labels[class_mun*sample_mun_perclass][class_mun]={{0,0,0,0}};
//Mat trainingDataMat;
for(int i=0;i<=class_mun-1;++i)
{
sprintf(temp, "%d", i);
fileReadPath = temp;
fileSavePath = perfileSavePath+"/"+fileReadPath;
fileReadPath = perfileReadPath+"/"+fileReadPath;
for(int j=1;j<=sample_mun_perclass;++j)
{
sprintf(t, "%d", j);
fileReadName = t;
fileReadName = fileReadName+fileform;//bug?
//cout << fileReadPath+"/"+fileReadName<<endl;
//cout << fileSavePath+"/"+fileReadName<<endl;
Mat srcImage = imread(fileReadPath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);
Mat resizeImage;
if(srcImage.empty())
{
qDebug()<<"路径出错,找不到指定图像";
return;
}
Mat result;
//cvtColor( srcImage, srcImage, CV_BGR2GRAY );
//cv::equalizeHist(srcImage,result);
cv::resize(srcImage,resizeImage,Size(image_cols,image_rows),(0,0),(0,0),3);
cv::threshold(resizeImage,resizeImage,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);
imwrite(fileSavePath+"/"+fileReadName,resizeImage);
// Set up training data
Mat train_image = imread(fileSavePath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);
for(int k = 0; k<image_rows*image_cols; ++k)
{
trainingData[i*sample_mun_perclass+(j-1)][k] = (float)train_image.at<unsigned char>((int)k/8,(int)k%8);//(float)train_image.data[k];
//cout<<trainingData[i*sample_mun_perclass+(j-1)][k] <<" "<< (float)train_image.at<unsigned char>(k/8,k%8)<<endl;
}
//cout<<endl;
}
}
Mat trainingDataMat(class_mun*sample_mun_perclass, image_rows*image_cols, CV_32FC1);
for(int i =0;i < class_mun*sample_mun_perclass; ++i)
for(int j =0;j < image_rows*image_cols; ++j)
{
trainingDataMat.at<float>(i,j) = (float)trainingData[i][j];
// cout<<i<<" "<<j<<endl;
}
// memcpy(temp.data,trainingData,sizeof(float)*class_mun*sample_mun_perclass*image_rows*image_cols);
// trainingDataMat = temp;
/**/
/**/ Mat mm(image_rows,image_cols,CV_8UC1);
for(int n=0;n < sample_mun_perclass*class_mun;n++)
{
for(int m=0;m < image_rows*image_cols;m++)
mm.at<uchar>(m/8,m%8) = trainingDataMat.at<float>(n,m);//(uchar)(int)trainingData[0][m];
//imshow("check",mm);
//waitKey(100);
}
// Set up lable data
for(int i=0;i<=class_mun-1;++i)
{
for(int j=0;j<=sample_mun_perclass-1;++j)
{
for(int k = 0;k<class_mun;++k)
{
if(k==i)
labels[i*sample_mun_perclass + j][k] = 1;
else labels[i*sample_mun_perclass + j][k] = 0;
}
}
}
Mat labelsMat(class_mun*sample_mun_perclass, class_mun, CV_32FC1,labels);
for(int i=0;i<=class_mun-1;++i)
{
for(int j=0;j<=sample_mun_perclass-1;++j)
{
for(int k = 0;k<class_mun;++k)
{
labelsMat.data[i*sample_mun_perclass + j+k] = labels[i*sample_mun_perclass + j][k];
//cout<<(float)labelsMat.data[i*sample_mun_perclass + j+k];
//cout<<labels[i*sample_mun_perclass + j][k];
}
//cout<<endl;
}
}
/*
*训练代码
*/
CvANN_MLP bp;
//if(0)
{
cout<<"training start...."<<endl;
// Set up BPNetwork's parameters
CvANN_MLP_TrainParams params;
params.train_method=CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale=0.001;
params.bp_moment_scale=0.1;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10000,0.0001); //设置结束条件
//params.train_method=CvANN_MLP_TrainParams::RPROP;
//params.rp_dw0 = 0.1;
//params.rp_dw_plus = 1.2;
//params.rp_dw_minus = 0.5;
//params.rp_dw_min = FLT_EPSILON;
//params.rp_dw_max = 50.;
//Setup the BPNetwork
Mat layerSizes=(Mat_<int>(1,5) << 128,128,128,128,class_mun);
bp.create(layerSizes,CvANN_MLP::SIGMOID_SYM,1.0,1.0);//CvANN_MLP::SIGMOID_SYM
//CvANN_MLP::GAUSSIAN
//CvANN_MLP::IDENTITY
cout<<"training...."<<endl;
bp.train(trainingDataMat, labelsMat, Mat(),Mat(), params);
bp.save("../bpcharModel.xml"); //save classifier
cout<<"bpModel1.xml saved training finish..."<<endl;
}
/*
*测试代码
*/
//if(0)
int err = 0;
for(int i=0;i<=class_mun-1;++i)
{
sprintf(temp, "%d", i);
fileReadPath = temp;
fileSavePath = perfileSavePath+"/"+fileReadPath;
for(int j=sample_mun_perclass+1;j<=10+2*sample_mun_perclass;++j)
{
sprintf(t, "%d", j);
fileReadName = t;
fileReadName = fileReadName+fileform;//bug?
cout << fileSavePath+"/"+fileReadName<<endl;
{
Mat test_image = imread(fileSavePath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);
if(test_image.empty())
{
qDebug()<<"路径出错,找不到指定图像";
return;
}
Mat_<float>sampleMat(1,image_rows*image_cols);
for(int i = 0; i<image_rows*image_cols; ++i)
{
sampleMat.at<float>(0,i) = (float)test_image.at<uchar>(i/8,i%8);
//cout<<((sampleMat.at<float>(0,i))>0?1:0)<<" ";
//if(i%8==7)
// cout<<endl;
}
imshow("1",test_image);
//Mat sampleMat = ( << 10,501);
Mat responseMat;
bp.predict(sampleMat,responseMat);
float* p=responseMat.ptr<float>(0);
//cout<<(float)(*p)<<" "<<(float)(*(p+1))<<" "<<(float)(*(p+2))<<" "<<(float)(*(p+3))<<endl;
float max= -1,min =0;
int index = 0;
for(int k=0;k<class_mun;++k)
{
cout<<(float)(*(p+k))<<" ";
if(k==class_mun-1)
cout<<endl;
//max = (*p)
if((float)(*(p+k))>max)
{
min = max;
max = (float)(*(p+k));
index = k;
}
else
{
if(min < (float)(*(p+k)))
min = (float)(*(p+k));
}
}
cout<<"识别结果:"<<index<<endl<<"识别置信度:"<<(((max-min)*100) > 100 ? 100:((max-min)*100))<<endl;
if(index!=i)
{
//if(max-min)<
err++;
cout<<"识别出错: "<<err<<endl;
}
cout<<"识别出错: "<<err<<endl;
// if((max-min)<0.2)
{
}
}
}
}
特征采用8*16的二值化图像构成的128维向量作为输入层,3层128维的隐藏层,10维的输出层。输出用{1,0,0,0,0,...0}{0,1,0,0,0,...0}{0,0,1,0,0,...0}......{0,0,0,0,0,...1}表示
识别率95%左右
测试图像来源:http://www.cnblogs.com/ronny/p/opencv_road_more_01.html ,