方法:可选用水平累积直方图、垂直累积直方图特征以及低分辨图像作为特征,用于训练的输入层
图中低分辨率图像的像素为5*5
1、水平和垂直累积直方图
a、使用countNonZero函数计算每一行或每一列的非0像素数,存放在矩阵mhist中
b、使用minMaxLoc函数求出mhist中的最大值
c、使用convertTo函数将mhist中所有的元素都除以这个最大值
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);
}
//Normalize histogram
double min, max;
minMaxLoc(mhist, &min, &max);
if(max>0)
mhist.convertTo(mhist,-1 , 1.0f/max, 0);
return mhist;
}
2、特征提取
mhist的所有元素+vhist的所有元素+低分辨率图像的所有像素
低分辨率图像可以是5*5,10*10,15*15,20*20,需要训练和测试来确定哪个最适合
Mat features(Mat in, int sizeData){
//Histogram features
Mat vhist=ProjectedHistogram(in,VERTICAL);
Mat hhist=ProjectedHistogram(in,HORIZONTAL);
//Low data feature
Mat lowData;
resize(in, lowData, Size(sizeData, sizeData) );
if(DEBUG)
drawVisualFeatures(in, hhist, vhist, lowData);
//Last 10 is the number of moments components
int numCols=vhist.cols+hhist.cols+lowData.cols*lowData.cols;
Mat out=Mat::zeros(1,numCols,CV_32F);
//Asign values to feature
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;
}
这样,通过features函数可提取出每一个训练样本的特征F_NUM,作为ANN的输入层
Mat layerSizes = (Mat_<int>(1, 3) << F_NUM, Hidden_NUM, classSum);