Opencv3.1的机器学习的再探:瞳孔/虹膜分类

代码和数据链接   http://pan.baidu.com/s/1eRRiYye (下载后尽量不要改文件夹关系,或者自己改一下路径,C++程序的路径还是必须改的)

一:任务与特征选取

任务:将瞳孔的像素点和其他像素区分出来

数据来源:自动化所虹膜库 


1,自己写了一个demo,将虹膜库的图像中的人眼区域保存出来,作为数据集,图片在iris文件夹里。

2,瞳孔像素的标注: 用画图工具将瞳孔所在位置标为红色,在iris压缩包下label\Labeled文件夹下。

3,生成label图像(二值图),用简单的图像处理,把光斑找出来并认为它们不是瞳孔 ,用matlab 运行\label\TheImage\label\GenerateLabelAndChange.m即可

Opencv3.1的机器学习的再探:瞳孔/虹膜分类_第1张图片

              原图                                                   瞳孔所在位置                                          label图片


4,特征的选取:像素点和周围点的关系,matlab运行random.m,会生成两个数组以及显示的一个图片(如下)

Opencv3.1的机器学习的再探:瞳孔/虹膜分类_第2张图片

这个图的大概意思假如中最中间的点事当前像素的话,在很近的周围选取24个点和当前点,这些点的像素值作为一组数据(25维)。然后在附近距离中间点25像素开外(瞳孔大小大约是50像素),75像素内的区域随机选500个点。用当前点的像素值减去这些点的像素值得,这样我们会有一个525维的特征。

这个525维的特征的需要做一些处理,因为这么高的维度而且应该会有不小的噪声,肯定会对分类有影响。前面的25维不变,后面的500维均分为20份,每份25维数据,统计每份数据中大于零的数据的个数,那么最终得到20个从0到25之间的整形数。 加上不变前面的25维数据,一共是45维。最后归一化,前面25维度除以255,后20维除以25。

运行ViewThefeatures.m,可以观察正负样本的特征规律。

Opencv3.1的机器学习的再探:瞳孔/虹膜分类_第3张图片

Opencv3.1的机器学习的再探:瞳孔/虹膜分类_第4张图片



 我们可以看出,基本上瞳孔部分的45维特征值都比较小,而其他区域的45维特征比较大。

我们在处理过程中都把眼睛resize成为270*230像素的图片,并且用用高斯滤波器模糊了一下。


二、代码

c++代码只有两个文件,GetAllfile.h是获取文件夹下文件名的代码,将Irisclassfier.cpp和GetAllfile.h添加到配置好opencv3.1.0的VS程序即可运行。在项目的地方右键-属性-配置属性,调试,在命令参数行输入-boost 或者  -rf 或者-mlp或者 -knn 或者-nbayes或者-svm或者-lr ,分别运行adaboost、随机森林、神经网络、svm、logistic 分类。

函数解析 

void readLabelNum(string path, int num, int *result)           这个函数用来计算正负样本的数目。

void ReadTrainDataAndLabel(string pathlabel, string pathSrcimg, Mat data, Mat _label, int num)   //这个函数用来提取正负样本的特征和标签,提取到的特征保存在data中,data这个矩阵的每一行代表一个样本的特征向量。_label的对应行就是该样本的标签。

static Ptr prepare_train_data(const Mat& data, const Mat& responses, int ntrain_samples) //这个函数是OpenCV给的例程的一个函数,将训练数据特征和标签整合成opencv训练的数据。

各个分类器在本项目中的的效果 

随机森林:随机森林感觉在本项目中表现的比较出色,速度快,甚至直接用525维没归一化的向量作为输入,也能得到一个不错的效果。

Adaboost:可能是本项目中本来就是线性可分的,所以Adaboost在这个问题中分类也很出色,速度也很快

神经网络:神经网络需要设置的数据太多了,网络的层数,每层的节点数,学习率,最大迭代次数等等,而且这些设置都是根据经验来的。之前也没调过神经网络,可能这个问题中,在标标签的时候不可避免的把一些正样本标成负的,把负样本标成正的,反正我试过的参数,没有一个能把这个问题做好的。

-knn  K近邻的做法比较适合用来做训练样本比较小,线性可分并且特征明显的分类。在本项目中表现一般,但是速度比较慢,应该是训练样本数太大了些。

正太贝叶斯: 效果还不错,但是速度比较慢

SVM SVM的理论成熟,而且libsvm上手很容易,一般用个RBF核什么的一般效果都很好。线性核速度最快,但是效果差一些

losgistic回归  这个方法在本实验中居然一次好的结果都没有。可能也是样本的问题,也有可能是维数太高。

结论

        特征的选取很重要,区分度高的特征可能直接用最简单的机器学习方法就能区分开来。在某个分类器效果不好的时候,可以考虑下特征需不需要降维,需不需要归一化,特征的提取时间最好不要太长,特征最好可视化最好也做一下,便于后续分析。根据实时性的要求,需要选取比较快的模型。如果一种分类器效果怎么调都不好,可以考虑选用别的分类器.一般问题可以先用svm 或者random tree先试试,不行再换一种。其实这个问题用自适应的二值化或者图像分割应该能比较好的解决了,不一定要用机器学习。

       最近才入门一点ml的知识,希望各位不吝赐教。

效果(adaboost)容易将眉毛也分成瞳孔。。(random forest好像不会这样)

Opencv3.1的机器学习的再探:瞳孔/虹膜分类_第5张图片

最后,贴出代码(压缩包里也有)

GetAllfile.h

[cpp] view plain copy
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.   
  6. using namespace std;  
  7.   
  8. /************************************************************************/  
  9. /*  获取文件夹下所有文件名 
  10. 输入: 
  11. path    :   文件夹路径 
  12. exd     :   所要获取的文件名后缀,如jpg、png等;如果希望获取所有 
  13. 文件名, exd = "" 
  14. 输出: 
  15. files   :   获取的文件名列表 
  16.  
  17. shao, 20140707 
  18. */  
  19. /************************************************************************/  
  20. void getFiles(string path, string exd, vector& files)  
  21. {  
  22.   
  23.        
  24.     //文件句柄  
  25.     intptr_t   hFile = 0;  
  26.     //文件信息  
  27.     struct _finddata_t fileinfo;  
  28.     string pathName, exdName;  
  29.   
  30.     if (0 != strcmp(exd.c_str(), ""))  
  31.     {  
  32.         exdName = "\\*." + exd;  
  33.     }  
  34.     else  
  35.     {  
  36.         exdName = "\\*";  
  37.     }  
  38.        
  39.     const char* a = pathName.assign(path).append(exdName).c_str();  
  40.     if ((hFile = _findfirst(a, &fileinfo)) != -1)  
  41.     {  
  42.         do  
  43.         {  
  44.             //如果是文件夹中仍有文件夹,迭代之  
  45.             //如果不是,加入列表  
  46.             if ((fileinfo.attrib &  _A_SUBDIR))  
  47.             {  
  48.                 if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)  
  49.                     getFiles(pathName.assign(path).append("\\").append(fileinfo.name), exd, files);  
  50.             }  
  51.             else  
  52.             {  
  53.                 if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)  
  54.                     files.push_back(pathName.assign(path).append("\\").append(fileinfo.name));  
  55.             }  
  56.         } while (_findnext(hFile, &fileinfo) == 0);  
  57.         _findclose(hFile);  
  58.     }  
  59.     //int size = files.size();  for (int i = 0; i < size; i++)   {       cout << files[i].c_str() << endl;   }  
  60.    
  61. }  
  62.   
  63. void getFiles2(string path, string exd, vector& files)  
  64. {  
  65.   
  66.   
  67.     //文件句柄  
  68.     intptr_t   hFile = 0;  
  69.     //文件信息  
  70.     struct _finddata_t fileinfo;  
  71.     string pathName, exdName;  
  72.   
  73.     if (0 != strcmp(exd.c_str(), ""))  
  74.     {  
  75.         exdName = "\\*." + exd;  
  76.     }  
  77.     else  
  78.     {  
  79.         exdName = "\\*";  
  80.     }  
  81.   
  82.     const char* a = pathName.assign(path).append(exdName).c_str();  
  83.     if ((hFile = _findfirst(a, &fileinfo)) != -1)  
  84.     {  
  85.         do  
  86.         {  
  87.             //如果是文件夹中仍有文件夹,迭代之  
  88.             //如果不是,加入列表  
  89.             if ((fileinfo.attrib &  _A_SUBDIR))  
  90.             {  
  91.                   
  92.             }  
  93.             else  
  94.             {  
  95.                 if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)  
  96.                     files.push_back(pathName.assign("").append(fileinfo.name));  
  97.             }  
  98.         } while (_findnext(hFile, &fileinfo) == 0);  
  99.         _findclose(hFile);  
  100.     }  
  101.     //int size = files.size();  for (int i = 0; i < size; i++)   {       cout << files[i].c_str() << endl;   }  
  102.   
  103. }  
Irisclassifier.cpp
[cpp] view plain copy
  1. #include "opencv2/core/core.hpp"  
  2. #include    
  3. #include     
  4. #include "opencv2/ml/ml.hpp"  
  5. #include   
  6. #include   
  7. #include   
  8. #include "GetAllfile.h"  
  9. using namespace cv;  
  10. using namespace std;  
  11. using namespace cv::ml;  
  12. #define ATTRIBUTES_PER_SAMPLE 45  
  13. #define NUMBER_OF_CLASSES 2  //只有正负两个类  
  14. const int class_count = NUMBER_OF_CLASSES;  //同一个意思,从别的地方copy过来懒得改名了  
  15.   
  16. #define defaultSize Size(270,230)  
  17. int  NumofPotos = 1;//  
  18.   
  19. int randx[525] = { -4, -4, -4, -4, -4, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 7, -64, -29, 20, -50, -16, 56, 23, -70, 61, 67, -33, -9, 66, -29, -22, 33, -16, -46, 70, -54, 17, -14, 74, 66, -5, 55, 71, -21, -7, 39, -68, 41, 67, -40, 50, -64, -9, -26, -47, 69, -30, -7, -51, 37, -33, -74, 20, 50, -29, -74, 47, 10, -69, -34, -46, -30, -28, -67, -25, -20, 35, 23, 57, 32, -73, 38, 7, 30, -38, 61, -54, 40, 32, -65, 59, -20, 22, 11, -64, 26, -17, 68, 52, -35, -57, 2, 5, 19, 5, 8, 6, -2, 36, 56, -54, -65, 8, -31, 52, -71, 14, 12, -20, -50, -62, -14, -7, -24, 62, -51, -17, 13, 26, -25, -47, -53, -37, 13, -29, 32, -10, 48, 57, 34, -63, -7, 50, -47, -28, 39, -60, 73, -48, -58, 22, 54, -12, 39, -6, -67, -35, 3, 39, -48, -31, 38, 49, -36, 54, 52, -57, -73, 44, -74, 34, 45, 37, 55, -73, 60, -28, 29, 26, -49, -63, -7, -66, 20, -51, -37, 32, -71, 47, 48, -41, -10, -65, -56, -52, 72, -39, -3, 51, 0, -15, -6, -29, 42, -21, -12, -12, 41, -70, 53, 31, 38, -51, 57, 39, 61, -47, -43, -37, 39, 54, 70, -44, 74, 55, 4, 63, 11, 5, -29, 11, 28, -10, -33, -57, 25, 29, -33, 62, -37, 12, 57, -36, 43, 30, 25, 68, -34, 53, 36, -28, -26, 7, 49, 32, -29, -34, 19, 62, 7, 41, 33, -45, 65, -4, -69, 32, 59, -22, -36, -50, -52, -53, 53, -5, 20, -51, 40, -31, 71, -65, 48, 49, 38, 44, -55, 8, -59, 47, -72, 70, 61, -30, 36, 54, -37, -74, 35, 44, -21, 62, 70, 32, 39, 67, -47, 70, -48, 48, 11, 62, 51, 9, 30, -20, 60, -73, -52, 63, 26, -45, 27, -26, -66, 56, -59, 58, 12, 2, 57, -50, -3, 37, -46, 35, -23, 63, -52, -17, 53, -62, 2, 8, 34, 42, -29, 56, -27, 28, 25, -55, -16, 8, 32, 20, 41, -62, 28, 66, -10, -27, 66, 67, -18, 59, 4, 74, 7, 67, 66, 72, 65, -27, 74, -51, -63, -71, 40, -35, 43, 4, -3, -66, 8, 32, -5, -73, -39, -50, 47, -5, 36, -7, 17, -64, -30, -2, 1, -35, -2, 63, 49, -32, 73, 2, 61, -49, 32, 16, 47, -62, -19, -53, -65, -39, -70, 50, -70, -24, 75, -17, 60, 21, -8, -60, -57, 60, -20, 59, -35, 5, 22, -26, -64, 71, 68, -32, 3, -60, -62, 53, 50, -19, -9, 61, -36, 10, 74, -24, -66, -33, -45, -41, 4, -56, -12, 26, -2, -26, 47, 58, -47, 58, 61, -64, 46, -62, 49, 22, -60, -54, -46, -56, 50, 26, 28, 49, 21, -42, 58, 56, 67, -38, 45, -43, -54, 25, 49, -48, -37, 60, 56, -40, 53, -39, -1, -28, -50, 25, 70, -46, -68, 68, 12, -71, -56, -25, -67, 14, 59, -53, 12, -18, 33, 75, };  
  20. int randy[525] = { -4, -2, 0, 2, 4, -4, -2, 0, 2, 4, -4, -2, 0, 2, 4, -4, -2, 0, 2, 4, -4, -2, 0, 2, 4, -65, 28, -46, -48, 61, -37, -66, 71, 46, 16, 51, 64, 44, -15, 39, 50, -16, 65, 46, 26, 0, -53, -62, -38, -34, 68, 33, 11, 59, 42, 56, -8, -60, 34, 71, 44, -36, -56, -8, 55, 25, -5, -30, 35, 61, -22, 66, -53, 0, 0, -7, -2, 42, -34, 14, 15, 9, 30, -27, -65, -29, -20, 28, -70, 9, 23, -2, -47, -38, -64, -59, -73, -57, 40, -13, 1, -59, -48, 72, 46, -25, -30, -66, -15, 3, 9, 36, -31, -48, -69, -28, -38, -60, -69, -73, 42, 29, 35, 35, -37, -45, 33, 61, -40, 60, -34, -45, 51, 53, 59, 47, 31, 66, 4, -10, -50, 9, 66, 42, -64, -20, 28, 58, 37, 70, 2, -30, -67, 4, 3, 57, -12, -67, -46, -57, -41, 7, -64, 61, 46, -72, -71, -49, 34, 10, 36, -20, 4, -64, 8, 6, -44, -67, 5, -42, -22, -55, 27, -40, -6, 66, 18, 28, -7, -21, -9, 43, 25, -26, -47, -27, -67, -69, 6, 71, 2, 39, 39, 25, -34, 17, -68, -51, -18, -34, 38, 67, -26, 13, -42, 56, 61, -13, -48, -68, -71, 27, 56, 26, -35, -68, -48, 58, 70, -41, 55, -3, 20, 7, -33, -43, -60, -63, -61, 32, -63, -21, -26, 40, -32, -53, 71, 56, 54, 17, 75, 40, -74, -30, -72, -8, -65, -8, -73, 45, 44, -48, -71, 25, -6, -64, -74, 57, -51, 46, -28, 1, -19, -38, 29, -35, 24, 52, 74, -6, 21, -10, 22, -43, 70, 39, -36, 43, -46, 58, -27, 36, 45, -37, 38, 30, 30, 17, -72, -71, -3, -26, -31, -34, 53, 31, 11, 19, -4, -34, 30, 52, -3, 57, 60, 48, -69, 5, -26, -42, 10, 45, -37, 36, -39, -15, 35, -43, -27, 69, -17, 62, -30, 54, 47, -68, -41, 62, 60, -48, 6, 65, -34, 44, -39, 42, 41, -66, 40, -1, 47, 62, 65, 25, -63, 36, 27, -16, 43, 74, -40, -71, -30, -26, 39, 3, -21, 74, 36, 56, -43, -72, 52, -41, 27, 26, -28, -68, 69, 68, -10, -16, 74, -22, 9, -39, 51, 63, -74, -22, -51, -36, -9, -48, 44, -74, 23, -67, -56, 54, -55, 23, -63, -43, -26, -53, 45, -42, 45, -48, 38, -57, 17, -25, -43, -26, -10, -73, -45, 4, -18, -67, 8, -22, 47, -59, 66, 33, -48, 67, -65, 49, -75, -49, -64, 18, -53, 36, 39, 57, 26, 57, -47, 37, 61, 15, 33, 56, 47, -61, 67, 32, -49, 38, 18, -26, -32, -7, 59, -38, 47, -31, -28, 67, 29, 28, 74, -30, -44, 62, 3, 72, -71, -1, 24, -21, 67, -6, 27, -13, -58, 49, 37, -3, -55, 43, 20, 41, -34, -27, 30, -8, -66, 4, 41, -38, 61, -47, 62, -30, 20, 39, 24, -21, -19, 69, -19, -6, 5, -16, 70, 48, 26, 59, 56, 45, 63, -19, 51, -44, 15, 53, 67, 4, -41, };  
  21.   
  22. inline TermCriteria TC(int iters, double eps)  
  23. {  
  24.     return TermCriteria(TermCriteria::MAX_ITER + (eps > 0 ? TermCriteria::EPS : 0), iters, eps);  
  25. }  
  26.   
  27. void readLabelNum(string path, int num, int *result)  
  28. {  
  29.     int ppPixels = 0, others = 0;  
  30.     Mat Src;  
  31.     vector filenames;  
  32.     getFiles2(path, "bmp", filenames);  
  33.     for (int i = 0; i < num; i++)  
  34.     {   Src = imread(path + "\\" + filenames[i]);  
  35.         Mat dst;  
  36.         resize(Src, dst, defaultSize, 0, 0, CV_INTER_LINEAR);  
  37.         uchar *data = dst.data;  
  38.         int step = dst.step;  
  39.         int  esize = dst.elemSize();  
  40.         for (int k = 76; k < 194; k++)  
  41.         {  
  42.             for (int j = 76; j < 154; j++)  
  43.             {  
  44.                 if (data[j*step + k*esize])  
  45.                 {  
  46.                     ppPixels++;  
  47.                 }//end if  
  48.                 else  
  49.                     others++;  
  50.   
  51.             }  
  52.   
  53.         }  
  54.         //imshow("Src", dst);  
  55.         //waitKey(1);  
  56.     }  
  57.     result[0] = ppPixels;  
  58.     result[1] = others;  
  59.     cout << ppPixels << endl;  
  60.     cout << others << endl;  
  61.   
  62. }  
  63. void ReadTrainDataAndLabel(string pathlabel, string pathSrcimg, Mat data, Mat _label, int num)  
  64. {  
  65.   
  66.     vector<int> label;  
  67.     vector filenames;  
  68.     getFiles2(pathlabel, "bmp", filenames);  
  69.   
  70.     for (int i = 0; i < num; i++)  
  71.     {  
  72.         Mat Srclabel = imread(pathlabel + "\\" + filenames[i]);  
  73.         Mat dstlabel;  
  74.         resize(Srclabel, dstlabel, defaultSize, 0, 0, CV_INTER_LINEAR);  
  75.         String str = pathSrcimg + "\\" + filenames[i];  
  76.         str = str.substr(0, str.length() - 4);  
  77.           
  78.         Mat srcimg2 = imread(str, CV_LOAD_IMAGE_GRAYSCALE);  
  79.           
  80.         //Mat srcimg = imread(str);  
  81.         //Mat dstimg;  
  82.         //resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  83.         //int step0 = dstimg.step[0];  
  84.         //int step1 = dstimg.step[1];  
  85.         //int esize1 = dstimg.elemSize1();  注释掉的部分是用来显示的,全部取消注释的话可以看到搜索的区域  
  86.   
  87.         Mat dstimg2;  
  88.         resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  89.         blur(dstimg2, dstimg2, Size(3, 3));  
  90.         uchar *pdstlabel = dstlabel.data;  
  91.         //uchar *pdstimg = dstimg.data;  
  92.         int step = dstlabel.step;  
  93.         int  esize = dstlabel.elemSize();  
  94.           
  95.         int step2 = dstimg2.step[0];  
  96.         int step3 = dstimg2.step[1];  
  97.         uchar *pdstimg2 = dstimg2.data;  
  98.         int line = 0;  
  99.         for (int k = 76; k < 194; k++)  
  100.         {  
  101.             for (int j = 76; j < 154; j++)//两个for循环遍历中间部分的像素点  
  102.             {  
  103.                 if (pdstlabel[j*step + k*esize])  
  104.                 {  
  105.                     //pdstimg[j *step0 + k*step1] = 255;  
  106.                     label.push_back(1);  
  107.                 }  
  108.                 else  
  109.                     label.push_back(0);  
  110.                 for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  111.                     if (attribute<25)//前25项用像素值  
  112.                         data.at<float>(line, attribute) = (float)(pdstimg2[(j + randx[attribute])*step2 + (k + randy[attribute])*step3]) / 255.0;  
  113.                     else  
  114.                     {  
  115.                         float sum = 0;  
  116.                         for (int l = (attribute - 24) * 25; l <(attribute - 23) * 25; l++)  
  117.   
  118.                         {  
  119.                             if (pdstimg2[j *step2 + k*step3] - pdstimg2[(j + randx[attribute])*step2 + (k + randy[attribute])*step3]>0)  
  120.                             {  
  121.                                 sum = sum + 1;//大于0的个数  
  122.                             }  
  123.   
  124.                         }  
  125.                         data.at<float>(line, attribute) = sum / 25;  
  126.                     }  
  127.                 line++;  
  128.             }  
  129.   
  130.         }  
  131.         //imshow("dst", dstimg);  
  132.         //imshow("dst2", dstimg2);  
  133.         //waitKey(1);  
  134.     }  
  135.     Mat(label).copyTo(_label);  
  136. }  
  137. static Ptr  
  138. prepare_train_data(const Mat& data, const Mat& responses, int ntrain_samples)  
  139. {  
  140.     cout << "perepare" << endl;  
  141.     cout << data.rows << endl;  
  142.     cout << responses.rows << endl;  
  143.     Mat sample_idx = Mat::zeros(1, data.rows, CV_8U);  
  144.     Mat train_samples = sample_idx.colRange(0, ntrain_samples);  
  145.     train_samples.setTo(Scalar::all(1));  
  146.   
  147.     int nvars = data.cols;  
  148.     Mat var_type(nvars + 1, 1, CV_8U);  
  149.     var_type.setTo(Scalar::all(VAR_ORDERED));  
  150.     var_type.at(nvars) = VAR_CATEGORICAL;  
  151.     Ptr t = TrainData::create(data, ROW_SAMPLE, responses, noArray(), sample_idx, noArray(), var_type);  
  152.     return t;  
  153. }  
  154. template<typename T>  
  155. static Ptr load_classifier(const string& filename_to_load)  
  156. {  
  157.     // load classifier from the specified file  
  158.     Ptr model = StatModel::load(filename_to_load);  
  159.     if (model.empty())  
  160.         cout << "Could not read the classifier " << filename_to_load << endl;  
  161.     else  
  162.         cout << "The classifier " << filename_to_load << " is loaded.\n";  
  163.   
  164.     return model;  
  165. }  
  166. int main(int argc, char** argv)  
  167. {  
  168.     string pathlabel = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\label\\Label";  
  169.     string pathSrcimg = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\EyeImages";  
  170.     string pathtest = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\label\\Test";  
  171.     for (int l = 0; l < argc; l++)  
  172.         cout << argv[l] << endl;  
  173.   
  174.     cv::CommandLineParser parser(argc, argv, " {load||}{boost||}{rf randomforest||}{mlp||}{knn knearest||}{nbayes||}{svm||}{help h||}{lr logisticRegression||}");  
  175.     int method = 5;  
  176.     if (parser.has("rf"))  
  177.     {  
  178.         method = 0;  
  179.         NumofPotos = 1;  
  180.         cout << "using method randomforest" << endl;  
  181.     }  
  182.     if (parser.has("boost"))  
  183.     {  
  184.         method = 1;  
  185.         NumofPotos = 5;  
  186.         cout << "using method boost" << endl;  
  187.     }  
  188.     else if (parser.has("mlp"))  
  189.     {   
  190.         method = 2;  
  191.         NumofPotos = 2;  
  192.         cout << "using method Multi-layer perceptron neural networks" << endl;  
  193.     }  
  194.   
  195.     else if (parser.has("knearest"))  
  196.     {  
  197.         method = 3;  
  198.         cout << "using method knn" << endl;  
  199.     }  
  200.   
  201.     else if (parser.has("nbayes"))  
  202.     {  
  203.         method = 4;  
  204.         NumofPotos = 1;  
  205.         cout << "using method nbayes" << endl;  
  206.     }  
  207.   
  208.     else if (parser.has("svm"))  
  209.     {  
  210.         method = 5;  
  211.         cout << "using method svm" << endl;  
  212.     }  
  213.     else if (parser.has("lr"))  
  214.     {  
  215.         method = 6;  
  216.         NumofPotos = 50;  
  217.         cout << "using method logistic regression" << endl;  
  218.     }  
  219.   
  220.     Mat training_data;  
  221.     Mat training_label;  
  222.     int lnum[2];  
  223.     string filename_to_load = "";  
  224.     if (parser.has("load"))  
  225.     {  
  226.         filename_to_load = parser.get("load");  
  227.   
  228.     }  
  229.        
  230.         readLabelNum(pathlabel, NumofPotos, lnum);  
  231.         cout << lnum[0] << endl << lnum[1] << endl;  
  232.         training_data = Mat(lnum[0] + lnum[1], ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  233.         training_label = Mat(lnum[0] + lnum[1], 1, CV_32SC1);  
  234.         ReadTrainDataAndLabel(pathlabel, pathSrcimg, training_data, training_label, NumofPotos);  
  235.        
  236.   
  237.     随机森林///  
  238.     if (method == 0)  
  239.     {  
  240.         Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);  
  241.         Ptr model;  
  242.         model = RTrees::create();  
  243.         model->setMaxDepth(6);  
  244.         model->setMinSampleCount(10);  
  245.         model->setRegressionAccuracy(0);  
  246.         model->setUseSurrogates(false);  
  247.         model->setMaxCategories(2);  
  248.         model->setPriors(Mat());  
  249.         model->setCalculateVarImportance(true);  
  250.         model->setActiveVarCount(4);  
  251.         model->setTermCriteria(TC(100, 0.01f));  
  252.         model->train(tdata);  
  253.         cout << endl;  
  254.         /测试及显示///  
  255.         string  exten1 = "*.jpg";  
  256.         vector filenames;  
  257.         getFiles2(pathtest, "jpg", filenames);  
  258.         for (int i = 0; i < 1200; i++)  
  259.         {  
  260.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  261.             Mat dstimg;  
  262.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  263.             int step0 = dstimg.step[0];  
  264.             int step1 = dstimg.step[1];  
  265.             uchar *pdstimg = dstimg.data;  
  266.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  267.             Mat dstimg2;  
  268.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  269.             int step02 = dstimg2.step[0];  
  270.             int step12 = dstimg2.step[1];  
  271.             uchar *pdstimg2 = dstimg2.data;  
  272.             int line = 0;  
  273.             double result;  
  274.             double t_rec;  
  275.             t_rec = (double)cvGetTickCount();  
  276.             for (int k = 76; k < 194; k++)  
  277.             {  
  278.                 for (int j = 76; j < 154; j++)  
  279.                 {  
  280.   
  281.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  282.   
  283.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  284.                         if (attribute<25)//前25项用像素值  
  285.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  286.                         else  
  287.   
  288.                         {  
  289.                             float sum = 0;  
  290.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  291.   
  292.                             {  
  293.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  294.                                 {  
  295.                                     sum = sum + 1;//大于0的个数  
  296.                                 }  
  297.   
  298.                             }  
  299.                             data.at<float>(line, attribute) = sum / 25;  
  300.                         }  
  301.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  302.                     result = model->predict(data);  
  303.                     if (result>0)  
  304.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来   
  305.                     // pdstimg[j *step0 + k*step1] = 255;  
  306.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  307.                 }           //end j=76:154  
  308.             }//end for k=76:194  
  309.             t_rec = (double)cvGetTickCount() - t_rec;  
  310.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  311.             imshow("dst2", dstimg2);  
  312.             waitKey(10);  
  313.         }          //end for i=1:1200  
  314.         /测试及显示///  
  315.   
  316.     }  
  317.     随机森林///  
  318.     方法1 boost//  
  319.   
  320.     else if (method == 1)  
  321.     {  
  322.         // Adaboost  处理的是二分类问题,但是通过增加一维做成多分类的分类器,  
  323.         //详情参考 http://blog.csdn.net/mutex86/article/details/8301070  
  324.         Mat data = training_data;  
  325.         Mat responses = training_label;  
  326.         Mat weak_responses;  
  327.         int i, j, k;  
  328.         Ptr model;  
  329.         int nsamples_all = data.rows;  
  330.         int ntrain_samples = (int)(nsamples_all*0.5);  
  331.         int var_count = data.cols;  
  332.   
  333.         // Create or load Boosted Tree classifier  
  334.         if (!filename_to_load.empty())  
  335.         {  
  336.             model = load_classifier(filename_to_load);  
  337.             if (model.empty())  
  338.                 return false;  
  339.             ntrain_samples = 0;  
  340.             cout << " the classifier loaded ...\n";  
  341.         }  
  342.         else  
  343.         {  
  344.             Mat new_data(ntrain_samples*class_count, var_count + 1, CV_32F);  
  345.             Mat new_responses(ntrain_samples*class_count, 1, CV_32S);  
  346.   
  347.             // 1. unroll the database type mask  
  348.             printf("Unrolling the database...\n");  
  349.             for (i = 0; i < ntrain_samples; i++)  
  350.             {  
  351.                 const float* data_row = data.ptr<float>(i);  
  352.                 for (j = 0; j < class_count; j++)  
  353.                 {  
  354.                     float* new_data_row = (float*)new_data.ptr<float>(i*class_count + j);  
  355.                     memcpy(new_data_row, data_row, var_count*sizeof(data_row[0]));  
  356.                     new_data_row[var_count] = (float)j; //增加一维  
  357.                     new_responses.at<int>(i*class_count + j) = responses.at<int>(i) == j;  
  358.                     //response只有两个值,0或者1responses.at(i) == j 的时候是1    
  359.                     //这个应该是boost的mh方法,http://www.360doc.com/content/12/0307/12/4910_192442968.shtml  
  360.                 }  
  361.             }  
  362.   
  363.             Mat var_type(1, var_count + 2, CV_8U);  
  364.             var_type.setTo(Scalar::all(VAR_ORDERED));  
  365.             var_type.at(var_count) = var_type.at(var_count + 1) = VAR_CATEGORICAL;  
  366.   
  367.             Ptr tdata = TrainData::create(new_data, ROW_SAMPLE, new_responses,  
  368.                 noArray(), noArray(), noArray(), var_type);  
  369.             vector<double> priors(2);  
  370.             priors[0] = 0.8;  
  371.             priors[1] = 0.2;  
  372.   
  373.             cout << "Training the classifier (may take a few minutes)...\n";  
  374.             model = Boost::create();  
  375.             model->setBoostType(Boost::GENTLE);  
  376.             model->setWeakCount(15);//弱分类器的个数  
  377.             model->setWeightTrimRate(0.99);  
  378.             model->setMaxDepth(7);  //树的深度  
  379.             model->setUseSurrogates(false);  
  380.             model->setPriors(Mat(priors));  
  381.             model->train(tdata);  
  382.             cout << endl;  
  383.         }  
  384.   
  385.         Mat temp_sample(1, var_count + 1, CV_32F);  
  386.         float* tptr = temp_sample.ptr<float>();  
  387.   
  388.         // compute prediction error on train and test data  
  389.         double train_hr = 0, test_hr = 0;  
  390.         for (i = 0; i < nsamples_all; i++)  
  391.         {  
  392.             int best_class = 0;  
  393.             double max_sum = -DBL_MAX;//负无穷  
  394.             const float* ptr = data.ptr<float>(i);  
  395.             for (k = 0; k < var_count; k++)  
  396.                 tptr[k] = ptr[k];  
  397.   
  398.             for (j = 0; j < class_count; j++)  
  399.             {  
  400.                 tptr[var_count] = (float)j;  //给测试集加1维  
  401.                 float s = model->predict(temp_sample, noArray(), StatModel::RAW_OUTPUT);//只有可能是的第j类的时候输出1   
  402.                 if (max_sum < s)  
  403.                 {  
  404.                     max_sum = s;  
  405.                     best_class = j;  
  406.                 }  
  407.             }  
  408.   
  409.             double r = std::abs(best_class - responses.at<int>(i)) < FLT_EPSILON ? 1 : 0;  
  410.             if (i < ntrain_samples)  
  411.                 train_hr += r;  
  412.             else  
  413.                 test_hr += r;  
  414.         }  
  415.   
  416.         test_hr /= nsamples_all - ntrain_samples;  
  417.         train_hr = ntrain_samples > 0 ? train_hr / ntrain_samples : 1.;  
  418.         printf("Recognition rate: train = %.1f%%, test = %.1f%%\n",  
  419.             train_hr*100., test_hr*100.);  
  420.   
  421.         cout << "Number of trees: " << model->getRoots().size() << endl;  
  422.         // Save classifier to file if needed           
  423.         model->save("boost.xml");  
  424.   
  425.   
  426.         /测试及显示///  
  427.         string  exten1 = "*.jpg";  
  428.         vector filenames;  
  429.         getFiles2(pathtest, "jpg", filenames);  
  430.         for (int i = 0; i < 1200; i++)  
  431.         {  
  432.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  433.             Mat dstimg;  
  434.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  435.             int step0 = dstimg.step[0];  
  436.             int step1 = dstimg.step[1];  
  437.             uchar *pdstimg = dstimg.data;  
  438.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  439.             Mat dstimg2;  
  440.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  441.             int step02 = dstimg2.step[0];  
  442.             int step12 = dstimg2.step[1];  
  443.             uchar *pdstimg2 = dstimg2.data;  
  444.             int line = 0;  
  445.             double result;  
  446.             double t_rec;  
  447.             t_rec = (double)cvGetTickCount();  
  448.             for (int k = 76; k < 194; k++)  
  449.             {  
  450.                 for (int j = 76; j < 154; j++)  
  451.                 {  
  452.   
  453.                     Mat data(1, ATTRIBUTES_PER_SAMPLE + 1, CV_32FC1);  
  454.   
  455.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  456.                         if (attribute<25)//前25项用像素值  
  457.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  458.                         else  
  459.   
  460.                         {  
  461.                             float sum = 0;  
  462.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  463.   
  464.                             {  
  465.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  466.                                 {  
  467.                                     sum = sum + 1;//大于0的个数  
  468.                                 }  
  469.   
  470.                             }  
  471.                             data.at<float>(line, attribute) = sum / 25;  
  472.                         }  
  473.                     data.at<float>(line, ATTRIBUTES_PER_SAMPLE ) = (float)1;  //注意,adaboost的加了一项 由于这个是二分类,就不用for循环了  
  474.                     result = model->predict(data, noArray(), StatModel::RAW_OUTPUT);   
  475.                         if (result>0)  
  476.                             pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  477.                     // pdstimg[j *step0 + k*step1] = 255;  
  478.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  479.                 }           //end j=76:154  
  480.             }//end for k=76:194  
  481.             t_rec = (double)cvGetTickCount() - t_rec;  
  482.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  483.             imshow("dst2", dstimg2);  
  484.             waitKey(10);  
  485.         }          //end for i=1:1200  
  486.         /测试及显示///  
  487.     }  
  488.     方法1 boost//  
  489.   
  490.     方法2 神经网络//  
  491.     else if (method == 2)  
  492.     {  
  493.         const int class_count = 2;  
  494.         Mat data=training_data;  
  495.         Mat responses=training_label;  
  496.   
  497.         Ptr model;  
  498.   
  499.            
  500.         int ntrain_samples = (int)data.rows;  
  501.   
  502.         // Create or load MLP classifier  
  503.         if (!filename_to_load.empty())  
  504.         {  
  505.             model = load_classifier(filename_to_load);  
  506.             if (model.empty())  
  507.                 return false;  
  508.             ntrain_samples = 0;  
  509.         }  
  510.         else  
  511.         {  
  512.               
  513.   
  514.             Mat train_data = data.rowRange(0, ntrain_samples);  
  515.             Mat train_responses = Mat::zeros(ntrain_samples, class_count, CV_32F);//全零矩阵  
  516.   
  517.             // 1. unroll the responses  
  518.             cout << "Unrolling the responses...\n";  
  519.             for (int i = 0; i < ntrain_samples; i++)  
  520.             {  
  521.                 int cls_label = responses.at<int>(i) ;  
  522.                 train_responses.at<float>(i, cls_label) = 1.f;  
  523.                 //train_responses 标签除了该样本所属列为1之外,全为零  
  524.             }  
  525.   
  526.             // 2. train classifier  
  527.             int layer_sz[] = { data.cols, 100, 9, class_count };  
  528.             int nlayers = (int)(sizeof(layer_sz) / sizeof(layer_sz[0]));  
  529.             cout << "nlayers   "  << nlayers << endl;  
  530.             Mat layer_sizes(1, nlayers, CV_32S, layer_sz);  
  531.   
  532. #if 1  
  533.             int method = ANN_MLP::BACKPROP;  
  534.             double method_param = 0.001;  
  535.             int max_iter = 30;  
  536. #else  
  537.             int method = ANN_MLP::RPROP;  
  538.             double method_param = 0.1;  
  539.             int max_iter = 1000;  
  540. #endif  
  541.   
  542.             Ptr tdata = TrainData::create(train_data, ROW_SAMPLE, train_responses);  
  543.   
  544.             cout << "Training the classifier (may take a few minutes)...\n";  
  545.             model = ANN_MLP::create();  
  546.             model->setLayerSizes(layer_sizes);  
  547.             model->setActivationFunction(ANN_MLP::GAUSSIAN, 0, 0);  
  548.             model->setTermCriteria(TC(max_iter, 0));  
  549.             model->setTrainMethod(method, method_param);  
  550.             model->train(tdata);  
  551.             cout << endl;  
  552.             model->save("mlp.xml");  
  553.         }  
  554.         /测试及显示///  
  555.         string  exten1 = "*.jpg";  
  556.         vector filenames;  
  557.         getFiles2(pathtest, "jpg", filenames);  
  558.         for (int i = 0; i < 1200; i++)  
  559.         {  
  560.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  561.             Mat dstimg;  
  562.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  563.             int step0 = dstimg.step[0];  
  564.             int step1 = dstimg.step[1];  
  565.             uchar *pdstimg = dstimg.data;  
  566.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  567.             Mat dstimg2;  
  568.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  569.             int step02 = dstimg2.step[0];  
  570.             int step12 = dstimg2.step[1];  
  571.             uchar *pdstimg2 = dstimg2.data;  
  572.             int line = 0;  
  573.             double result;  
  574.             double t_rec;  
  575.             t_rec = (double)cvGetTickCount();  
  576.             for (int k = 76; k < 194; k++)  
  577.             {  
  578.                 for (int j = 76; j < 154; j++)  
  579.                 {  
  580.   
  581.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  582.   
  583.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  584.                         if (attribute<25)//前25项用像素值  
  585.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  586.                         else  
  587.   
  588.                         {  
  589.                             float sum = 0;  
  590.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  591.   
  592.                             {  
  593.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  594.                                 {  
  595.                                     sum = sum + 1;//大于0的个数  
  596.                                 }  
  597.   
  598.                             }  
  599.                             data.at<float>(line, attribute) = sum / 25;  
  600.                         }  
  601.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  602.                     result = model->predict(data);  
  603.                     if (result>0)  
  604.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  605.                     // pdstimg[j *step0 + k*step1] = 255;  
  606.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  607.                 }           //end j=76:154  
  608.             }//end for k=76:194  
  609.             t_rec = (double)cvGetTickCount() - t_rec;  
  610.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  611.             imshow("dst2", dstimg2);  
  612.             waitKey(10);  
  613.         }          //end for i=1:1200  
  614.         /测试及显示///  
  615.     }  
  616.     //knn  
  617.     else if (method == 3)  
  618.     {  
  619.         Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);  
  620.         Ptr model = KNearest::create();  
  621.         model->setDefaultK(2);  
  622.         model->setIsClassifier(true);  
  623.         model->train(tdata);  
  624.         cout << endl;  
  625.         /测试及显示///  
  626.         string  exten1 = "*.jpg";  
  627.         vector filenames;  
  628.         getFiles2(pathtest, "jpg", filenames);  
  629.         for (int i = 0; i < 1200; i++)  
  630.         {  
  631.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  632.             Mat dstimg;  
  633.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  634.             int step0 = dstimg.step[0];  
  635.             int step1 = dstimg.step[1];  
  636.             uchar *pdstimg = dstimg.data;  
  637.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  638.             Mat dstimg2;  
  639.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  640.             int step02 = dstimg2.step[0];  
  641.             int step12 = dstimg2.step[1];  
  642.             uchar *pdstimg2 = dstimg2.data;  
  643.             int line = 0;  
  644.             double result;  
  645.             double t_rec;  
  646.             t_rec = (double)cvGetTickCount();  
  647.             for (int k = 76; k < 194; k++)  
  648.             {  
  649.                 for (int j = 76; j < 154; j++)  
  650.                 {  
  651.   
  652.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  653.   
  654.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  655.                         if (attribute<25)//前25项用像素值  
  656.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  657.                         else  
  658.   
  659.                         {  
  660.                             float sum = 0;  
  661.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  662.   
  663.                             {  
  664.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  665.                                 {  
  666.                                     sum = sum + 1;//大于0的个数  
  667.                                 }  
  668.   
  669.                             }  
  670.                             data.at<float>(line, attribute) = sum / 25;  
  671.                         }  
  672.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  673.                     result = model->predict(data);  
  674.                     if (result>0)  
  675.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  676.                     // pdstimg[j *step0 + k*step1] = 255;  
  677.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  678.                 }           //end j=76:154  
  679.             }//end for k=76:194  
  680.             t_rec = (double)cvGetTickCount() - t_rec;  
  681.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  682.             imshow("dst2", dstimg2);  
  683.             waitKey(10);  
  684.         }          //end for i=1:1200  
  685.         /测试及显示///  
  686.   
  687.     }  
  688.     knn/  
  689.     ///nbayes//  
  690.     else if (method == 4)  
  691.     {  
  692.         Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);  
  693.         Ptr model;;  
  694.         model = NormalBayesClassifier::create();  
  695.         model->train(tdata);  
  696.         cout << endl;  
  697.         /测试及显示///  
  698.         string  exten1 = "*.jpg";  
  699.         vector filenames;  
  700.         getFiles2(pathtest, "jpg", filenames);  
  701.         for (int i = 0; i < 1200; i++)  
  702.         {  
  703.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  704.             Mat dstimg;  
  705.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  706.             int step0 = dstimg.step[0];  
  707.             int step1 = dstimg.step[1];  
  708.             uchar *pdstimg = dstimg.data;  
  709.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  710.             Mat dstimg2;  
  711.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  712.             int step02 = dstimg2.step[0];  
  713.             int step12 = dstimg2.step[1];  
  714.             uchar *pdstimg2 = dstimg2.data;  
  715.             int line = 0;  
  716.             double result;  
  717.             double t_rec;  
  718.             t_rec = (double)cvGetTickCount();  
  719.             for (int k = 76; k < 194; k++)  
  720.             {  
  721.                 for (int j = 76; j < 154; j++)  
  722.                 {  
  723.   
  724.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  725.   
  726.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  727.                         if (attribute<25)//前25项用像素值  
  728.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  729.                         else  
  730.   
  731.                         {  
  732.                             float sum = 0;  
  733.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  734.   
  735.                             {  
  736.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  737.                                 {  
  738.                                     sum = sum + 1;//大于0的个数  
  739.                                 }  
  740.   
  741.                             }  
  742.                             data.at<float>(line, attribute) = sum / 25;  
  743.                         }  
  744.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  745.                     result = model->predict(data);  
  746.                     if (result>0)  
  747.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  748.                     // pdstimg[j *step0 + k*step1] = 255;  
  749.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  750.                 }           //end j=76:154  
  751.             }//end for k=76:194  
  752.             t_rec = (double)cvGetTickCount() - t_rec;  
  753.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  754.             imshow("dst2", dstimg2);  
  755.             waitKey(10);  
  756.         }          //end for i=1:1200  
  757.         /测试及显示///  
  758.   
  759.     }  
  760.     nbayes  
  761.     else if (method == 5)  
  762.     {  
  763.         Ptr model;  
  764.         if (parser.has("load"))  
  765.         {  
  766.             cout << filename_to_load << endl;  
  767.             model = load_classifier(filename_to_load);  
  768.         }  
  769.         else  
  770.         {  
  771.             cout << "Training the classifier ...\n";  
  772.             Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);  
  773.   
  774.             model = SVM::create();  
  775.             model->setType(SVM::C_SVC);  
  776.             //参数设置参考 http://blog.csdn.net/changyuanchn/article/details/7540014  
  777.   
  778.             model->setKernel(SVM::LINEAR);//速度最快,但效果不一定好。可以实时  
  779.             //model->setKernel(SVM::INTER);  
  780.             //model->setKernel(SVM::RBF);//效果不错,但是要300ms  
  781.             //model->setKernel(SVM::SIGMOID);  
  782.             //model->setKernel(SVM::CHI2);//效果最好,但是要1000ms+  
  783.             //model->setKernel(SVM::POLY);  
  784.             //model->setGamma(3);//POLY必须要这个参数  
  785.             //model->setDegree(0.5);//POLY必须要这个参数  
  786.             //model->setCoef0(0);//POLY必须要这个参数  
  787.             model->setC(0.1);  
  788.             model->train(tdata);  
  789.             cout << endl;  
  790.             model->save("svm.xml");  
  791.         }  
  792.   
  793.         /测试及显示///  
  794.         string  exten1 = "*.jpg";  
  795.         vector filenames;  
  796.         getFiles2(pathtest, "jpg", filenames);  
  797.         for (int i = 0; i < 1200; i++)  
  798.         {  
  799.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  800.             Mat dstimg;  
  801.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  802.             int step0 = dstimg.step[0];  
  803.             int step1 = dstimg.step[1];  
  804.             uchar *pdstimg = dstimg.data;  
  805.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  806.             Mat dstimg2;  
  807.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  808.             int step02 = dstimg2.step[0];  
  809.             int step12 = dstimg2.step[1];  
  810.             uchar *pdstimg2 = dstimg2.data;  
  811.             int line = 0;  
  812.             double result;  
  813.             double t_rec;  
  814.             t_rec = (double)cvGetTickCount();  
  815.             for (int k = 76; k < 194; k++)  
  816.             {  
  817.                 for (int j = 76; j < 154; j++)  
  818.                 {  
  819.   
  820.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  821.   
  822.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  823.                         if (attribute<25)//前25项用像素值  
  824.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  825.                         else  
  826.   
  827.                         {  
  828.                             float sum = 0;  
  829.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  830.   
  831.                             {  
  832.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  833.                                 {  
  834.                                     sum = sum + 1;//大于0的个数  
  835.                                 }  
  836.   
  837.                             }  
  838.                             data.at<float>(line, attribute) = sum / 25;  
  839.                         }  
  840.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  841.                     result = model->predict(data);  
  842.                     if (result>0)  
  843.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  844.                     // pdstimg[j *step0 + k*step1] = 255;  
  845.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  846.                 }           //end j=76:154  
  847.             }//end for k=76:194  
  848.             t_rec = (double)cvGetTickCount() - t_rec;  
  849.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  850.             imshow("dst2", dstimg2);  
  851.             waitKey(10);  
  852.         }          //end for i=1:1200  
  853.         /测试及显示///  
  854.   
  855.     }  
  856.     svm/  
  857.     逻辑斯底回归///  
  858.     else if (method == 6)  
  859.     {  
  860.            
  861.         Ptr lr1 = LogisticRegression::create();  
  862.         lr1->setLearningRate(0.01);  
  863.         lr1->setIterations(100);  
  864.         lr1->setRegularization(LogisticRegression::REG_L2);  
  865.         lr1->setTrainMethod(LogisticRegression::BATCH);  
  866.         lr1->setMiniBatchSize(1);  
  867.         //! [init]  
  868.         cout << "training...";  
  869.         training_label.convertTo(training_label, CV_32F);  
  870.         lr1->train(training_data, ROW_SAMPLE, training_label);  
  871.         cout << "done!" << endl;  
  872.   
  873.   
  874.   
  875.         /测试及显示///  
  876.         string  exten1 = "*.jpg";  
  877.         vector filenames;  
  878.         getFiles2(pathtest, "jpg", filenames);  
  879.         for (int i = 0; i < 1200; i++)  
  880.         {  
  881.             Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);  
  882.             Mat dstimg;  
  883.             resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);  
  884.             int step0 = dstimg.step[0];  
  885.             int step1 = dstimg.step[1];  
  886.             uchar *pdstimg = dstimg.data;  
  887.             Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);  
  888.             Mat dstimg2;  
  889.             resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);  
  890.             int step02 = dstimg2.step[0];  
  891.             int step12 = dstimg2.step[1];  
  892.             uchar *pdstimg2 = dstimg2.data;  
  893.             int line = 0;  
  894.             double result;  
  895.             double t_rec;  
  896.             t_rec = (double)cvGetTickCount();  
  897.             for (int k = 76; k < 194; k++)  
  898.             {  
  899.                 for (int j = 76; j < 154; j++)  
  900.                 {  
  901.   
  902.                     Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);  
  903.   
  904.                     for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)  
  905.                         if (attribute<25)//前25项用像素值  
  906.                             data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;  
  907.                         else  
  908.   
  909.                         {  
  910.                             float sum = 0;  
  911.                             for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)  
  912.   
  913.                             {  
  914.                                 if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)  
  915.                                 {  
  916.                                     sum = sum + 1;//大于0的个数  
  917.                                 }  
  918.   
  919.                             }  
  920.                             data.at<float>(line, attribute) = sum / 25;  
  921.                         }  
  922.                     //data.at(line, attribute) = pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1];  
  923.                     result = lr1->predict(data);  
  924.                     //cout << result << endl;  
  925.                     if (result>0)  
  926.                         pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  927.                     // pdstimg[j *step0 + k*step1] = 255;  
  928.                     //   pdstimg2[j *step02 + k*step12] = 255;//将正样本的地方标出来  
  929.                 }           //end j=76:154  
  930.             }//end for k=76:194  
  931.             t_rec = (double)cvGetTickCount() - t_rec;  
  932.             cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;  
  933.             imshow("dst2", dstimg2);  
  934.             waitKey(10);  
  935.         }          //end for i=1:1200  
  936.         /测试及显示///  
  937.   
  938.     }  
  939.     逻辑斯底回归///  
  940.     return 0;  
  941.   
  942.   

你可能感兴趣的:(虹膜识别)