代码和数据链接 http://pan.baidu.com/s/1eRRiYye (下载后尽量不要改文件夹关系,或者自己改一下路径,C++程序的路径还是必须改的)
一:任务与特征选取
任务:将瞳孔的像素点和其他像素区分出来
数据来源:自动化所虹膜库
1,自己写了一个demo,将虹膜库的图像中的人眼区域保存出来,作为数据集,图片在iris文件夹里。
2,瞳孔像素的标注: 用画图工具将瞳孔所在位置标为红色,在iris压缩包下label\Labeled文件夹下。
3,生成label图像(二值图),用简单的图像处理,把光斑找出来并认为它们不是瞳孔 ,用matlab 运行\label\TheImage\label\GenerateLabelAndChange.m即可
原图 瞳孔所在位置 label图片
4,特征的选取:像素点和周围点的关系,matlab运行random.m,会生成两个数组以及显示的一个图片(如下)
这个图的大概意思假如中最中间的点事当前像素的话,在很近的周围选取24个点和当前点,这些点的像素值作为一组数据(25维)。然后在附近距离中间点25像素开外(瞳孔大小大约是50像素),75像素内的区域随机选500个点。用当前点的像素值减去这些点的像素值得,这样我们会有一个525维的特征。
这个525维的特征的需要做一些处理,因为这么高的维度而且应该会有不小的噪声,肯定会对分类有影响。前面的25维不变,后面的500维均分为20份,每份25维数据,统计每份数据中大于零的数据的个数,那么最终得到20个从0到25之间的整形数。 加上不变前面的25维数据,一共是45维。最后归一化,前面25维度除以255,后20维除以25。
运行ViewThefeatures.m,可以观察正负样本的特征规律。
我们可以看出,基本上瞳孔部分的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好像不会这样)
最后,贴出代码(压缩包里也有)
GetAllfile.h
- #include
- #include
- #include
- #include
-
- using namespace std;
-
-
-
-
-
-
-
-
-
-
-
-
-
- void getFiles(string path, string exd, vector& files)
- {
-
-
-
- intptr_t hFile = 0;
-
- struct _finddata_t fileinfo;
- string pathName, exdName;
-
- if (0 != strcmp(exd.c_str(), ""))
- {
- exdName = "\\*." + exd;
- }
- else
- {
- exdName = "\\*";
- }
-
- const char* a = pathName.assign(path).append(exdName).c_str();
- if ((hFile = _findfirst(a, &fileinfo)) != -1)
- {
- do
- {
-
-
- if ((fileinfo.attrib & _A_SUBDIR))
- {
- if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
- getFiles(pathName.assign(path).append("\\").append(fileinfo.name), exd, files);
- }
- else
- {
- if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
- files.push_back(pathName.assign(path).append("\\").append(fileinfo.name));
- }
- } while (_findnext(hFile, &fileinfo) == 0);
- _findclose(hFile);
- }
-
-
- }
-
- void getFiles2(string path, string exd, vector& files)
- {
-
-
-
- intptr_t hFile = 0;
-
- struct _finddata_t fileinfo;
- string pathName, exdName;
-
- if (0 != strcmp(exd.c_str(), ""))
- {
- exdName = "\\*." + exd;
- }
- else
- {
- exdName = "\\*";
- }
-
- const char* a = pathName.assign(path).append(exdName).c_str();
- if ((hFile = _findfirst(a, &fileinfo)) != -1)
- {
- do
- {
-
-
- if ((fileinfo.attrib & _A_SUBDIR))
- {
-
- }
- else
- {
- if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
- files.push_back(pathName.assign("").append(fileinfo.name));
- }
- } while (_findnext(hFile, &fileinfo) == 0);
- _findclose(hFile);
- }
-
-
- }
Irisclassifier.cpp
- #include "opencv2/core/core.hpp"
- #include
- #include
- #include "opencv2/ml/ml.hpp"
- #include
- #include
- #include
- #include "GetAllfile.h"
- using namespace cv;
- using namespace std;
- using namespace cv::ml;
- #define ATTRIBUTES_PER_SAMPLE 45
- #define NUMBER_OF_CLASSES 2 //只有正负两个类
- const int class_count = NUMBER_OF_CLASSES;
-
- #define defaultSize Size(270,230)
- int NumofPotos = 1;
-
- 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, };
- 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, };
-
- inline TermCriteria TC(int iters, double eps)
- {
- return TermCriteria(TermCriteria::MAX_ITER + (eps > 0 ? TermCriteria::EPS : 0), iters, eps);
- }
-
- void readLabelNum(string path, int num, int *result)
- {
- int ppPixels = 0, others = 0;
- Mat Src;
- vector filenames;
- getFiles2(path, "bmp", filenames);
- for (int i = 0; i < num; i++)
- { Src = imread(path + "\\" + filenames[i]);
- Mat dst;
- resize(Src, dst, defaultSize, 0, 0, CV_INTER_LINEAR);
- uchar *data = dst.data;
- int step = dst.step;
- int esize = dst.elemSize();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
- if (data[j*step + k*esize])
- {
- ppPixels++;
- }
- else
- others++;
-
- }
-
- }
-
-
- }
- result[0] = ppPixels;
- result[1] = others;
- cout << ppPixels << endl;
- cout << others << endl;
-
- }
- void ReadTrainDataAndLabel(string pathlabel, string pathSrcimg, Mat data, Mat _label, int num)
- {
-
- vector<int> label;
- vector filenames;
- getFiles2(pathlabel, "bmp", filenames);
-
- for (int i = 0; i < num; i++)
- {
- Mat Srclabel = imread(pathlabel + "\\" + filenames[i]);
- Mat dstlabel;
- resize(Srclabel, dstlabel, defaultSize, 0, 0, CV_INTER_LINEAR);
- String str = pathSrcimg + "\\" + filenames[i];
- str = str.substr(0, str.length() - 4);
-
- Mat srcimg2 = imread(str, CV_LOAD_IMAGE_GRAYSCALE);
-
-
-
-
-
-
-
-
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- blur(dstimg2, dstimg2, Size(3, 3));
- uchar *pdstlabel = dstlabel.data;
-
- int step = dstlabel.step;
- int esize = dstlabel.elemSize();
-
- int step2 = dstimg2.step[0];
- int step3 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
- if (pdstlabel[j*step + k*esize])
- {
-
- label.push_back(1);
- }
- else
- label.push_back(0);
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)(pdstimg2[(j + randx[attribute])*step2 + (k + randy[attribute])*step3]) / 255.0;
- else
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l <(attribute - 23) * 25; l++)
-
- {
- if (pdstimg2[j *step2 + k*step3] - pdstimg2[(j + randx[attribute])*step2 + (k + randy[attribute])*step3]>0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
- line++;
- }
-
- }
-
-
-
- }
- Mat(label).copyTo(_label);
- }
- static Ptr
- prepare_train_data(const Mat& data, const Mat& responses, int ntrain_samples)
- {
- cout << "perepare" << endl;
- cout << data.rows << endl;
- cout << responses.rows << endl;
- Mat sample_idx = Mat::zeros(1, data.rows, CV_8U);
- Mat train_samples = sample_idx.colRange(0, ntrain_samples);
- train_samples.setTo(Scalar::all(1));
-
- int nvars = data.cols;
- Mat var_type(nvars + 1, 1, CV_8U);
- var_type.setTo(Scalar::all(VAR_ORDERED));
- var_type.at(nvars) = VAR_CATEGORICAL;
- Ptr t = TrainData::create(data, ROW_SAMPLE, responses, noArray(), sample_idx, noArray(), var_type);
- return t;
- }
- template<typename T>
- static Ptr load_classifier(const string& filename_to_load)
- {
-
- Ptr model = StatModel::load(filename_to_load);
- if (model.empty())
- cout << "Could not read the classifier " << filename_to_load << endl;
- else
- cout << "The classifier " << filename_to_load << " is loaded.\n";
-
- return model;
- }
- int main(int argc, char** argv)
- {
- string pathlabel = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\label\\Label";
- string pathSrcimg = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\EyeImages";
- string pathtest = "E:\\Users\\Administrator\\Desktop\\matlabEyeTraking\\database\\label\\Test";
- for (int l = 0; l < argc; l++)
- cout << argv[l] << endl;
-
- cv::CommandLineParser parser(argc, argv, " {load||}{boost||}{rf randomforest||}{mlp||}{knn knearest||}{nbayes||}{svm||}{help h||}{lr logisticRegression||}");
- int method = 5;
- if (parser.has("rf"))
- {
- method = 0;
- NumofPotos = 1;
- cout << "using method randomforest" << endl;
- }
- if (parser.has("boost"))
- {
- method = 1;
- NumofPotos = 5;
- cout << "using method boost" << endl;
- }
- else if (parser.has("mlp"))
- {
- method = 2;
- NumofPotos = 2;
- cout << "using method Multi-layer perceptron neural networks" << endl;
- }
-
- else if (parser.has("knearest"))
- {
- method = 3;
- cout << "using method knn" << endl;
- }
-
- else if (parser.has("nbayes"))
- {
- method = 4;
- NumofPotos = 1;
- cout << "using method nbayes" << endl;
- }
-
- else if (parser.has("svm"))
- {
- method = 5;
- cout << "using method svm" << endl;
- }
- else if (parser.has("lr"))
- {
- method = 6;
- NumofPotos = 50;
- cout << "using method logistic regression" << endl;
- }
-
- Mat training_data;
- Mat training_label;
- int lnum[2];
- string filename_to_load = "";
- if (parser.has("load"))
- {
- filename_to_load = parser.get("load");
-
- }
-
- readLabelNum(pathlabel, NumofPotos, lnum);
- cout << lnum[0] << endl << lnum[1] << endl;
- training_data = Mat(lnum[0] + lnum[1], ATTRIBUTES_PER_SAMPLE, CV_32FC1);
- training_label = Mat(lnum[0] + lnum[1], 1, CV_32SC1);
- ReadTrainDataAndLabel(pathlabel, pathSrcimg, training_data, training_label, NumofPotos);
-
-
-
- if (method == 0)
- {
- Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);
- Ptr model;
- model = RTrees::create();
- model->setMaxDepth(6);
- model->setMinSampleCount(10);
- model->setRegressionAccuracy(0);
- model->setUseSurrogates(false);
- model->setMaxCategories(2);
- model->setPriors(Mat());
- model->setCalculateVarImportance(true);
- model->setActiveVarCount(4);
- model->setTermCriteria(TC(100, 0.01f));
- model->train(tdata);
- cout << endl;
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = model->predict(data);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
-
- }
-
-
-
- else if (method == 1)
- {
-
-
- Mat data = training_data;
- Mat responses = training_label;
- Mat weak_responses;
- int i, j, k;
- Ptr model;
- int nsamples_all = data.rows;
- int ntrain_samples = (int)(nsamples_all*0.5);
- int var_count = data.cols;
-
-
- if (!filename_to_load.empty())
- {
- model = load_classifier(filename_to_load);
- if (model.empty())
- return false;
- ntrain_samples = 0;
- cout << " the classifier loaded ...\n";
- }
- else
- {
- Mat new_data(ntrain_samples*class_count, var_count + 1, CV_32F);
- Mat new_responses(ntrain_samples*class_count, 1, CV_32S);
-
-
- printf("Unrolling the database...\n");
- for (i = 0; i < ntrain_samples; i++)
- {
- const float* data_row = data.ptr<float>(i);
- for (j = 0; j < class_count; j++)
- {
- float* new_data_row = (float*)new_data.ptr<float>(i*class_count + j);
- memcpy(new_data_row, data_row, var_count*sizeof(data_row[0]));
- new_data_row[var_count] = (float)j;
- new_responses.at<int>(i*class_count + j) = responses.at<int>(i) == j;
-
-
- }
- }
-
- Mat var_type(1, var_count + 2, CV_8U);
- var_type.setTo(Scalar::all(VAR_ORDERED));
- var_type.at(var_count) = var_type.at(var_count + 1) = VAR_CATEGORICAL;
-
- Ptr tdata = TrainData::create(new_data, ROW_SAMPLE, new_responses,
- noArray(), noArray(), noArray(), var_type);
- vector<double> priors(2);
- priors[0] = 0.8;
- priors[1] = 0.2;
-
- cout << "Training the classifier (may take a few minutes)...\n";
- model = Boost::create();
- model->setBoostType(Boost::GENTLE);
- model->setWeakCount(15);
- model->setWeightTrimRate(0.99);
- model->setMaxDepth(7);
- model->setUseSurrogates(false);
- model->setPriors(Mat(priors));
- model->train(tdata);
- cout << endl;
- }
-
- Mat temp_sample(1, var_count + 1, CV_32F);
- float* tptr = temp_sample.ptr<float>();
-
-
- double train_hr = 0, test_hr = 0;
- for (i = 0; i < nsamples_all; i++)
- {
- int best_class = 0;
- double max_sum = -DBL_MAX;
- const float* ptr = data.ptr<float>(i);
- for (k = 0; k < var_count; k++)
- tptr[k] = ptr[k];
-
- for (j = 0; j < class_count; j++)
- {
- tptr[var_count] = (float)j;
- float s = model->predict(temp_sample, noArray(), StatModel::RAW_OUTPUT);
- if (max_sum < s)
- {
- max_sum = s;
- best_class = j;
- }
- }
-
- double r = std::abs(best_class - responses.at<int>(i)) < FLT_EPSILON ? 1 : 0;
- if (i < ntrain_samples)
- train_hr += r;
- else
- test_hr += r;
- }
-
- test_hr /= nsamples_all - ntrain_samples;
- train_hr = ntrain_samples > 0 ? train_hr / ntrain_samples : 1.;
- printf("Recognition rate: train = %.1f%%, test = %.1f%%\n",
- train_hr*100., test_hr*100.);
-
- cout << "Number of trees: " << model->getRoots().size() << endl;
-
- model->save("boost.xml");
-
-
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE + 1, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
- data.at<float>(line, ATTRIBUTES_PER_SAMPLE ) = (float)1;
- result = model->predict(data, noArray(), StatModel::RAW_OUTPUT);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
- }
-
-
-
- else if (method == 2)
- {
- const int class_count = 2;
- Mat data=training_data;
- Mat responses=training_label;
-
- Ptr model;
-
-
- int ntrain_samples = (int)data.rows;
-
-
- if (!filename_to_load.empty())
- {
- model = load_classifier(filename_to_load);
- if (model.empty())
- return false;
- ntrain_samples = 0;
- }
- else
- {
-
-
- Mat train_data = data.rowRange(0, ntrain_samples);
- Mat train_responses = Mat::zeros(ntrain_samples, class_count, CV_32F);
-
-
- cout << "Unrolling the responses...\n";
- for (int i = 0; i < ntrain_samples; i++)
- {
- int cls_label = responses.at<int>(i) ;
- train_responses.at<float>(i, cls_label) = 1.f;
-
- }
-
-
- int layer_sz[] = { data.cols, 100, 9, class_count };
- int nlayers = (int)(sizeof(layer_sz) / sizeof(layer_sz[0]));
- cout << "nlayers " << nlayers << endl;
- Mat layer_sizes(1, nlayers, CV_32S, layer_sz);
-
- #if 1
- int method = ANN_MLP::BACKPROP;
- double method_param = 0.001;
- int max_iter = 30;
- #else
- int method = ANN_MLP::RPROP;
- double method_param = 0.1;
- int max_iter = 1000;
- #endif
-
- Ptr tdata = TrainData::create(train_data, ROW_SAMPLE, train_responses);
-
- cout << "Training the classifier (may take a few minutes)...\n";
- model = ANN_MLP::create();
- model->setLayerSizes(layer_sizes);
- model->setActivationFunction(ANN_MLP::GAUSSIAN, 0, 0);
- model->setTermCriteria(TC(max_iter, 0));
- model->setTrainMethod(method, method_param);
- model->train(tdata);
- cout << endl;
- model->save("mlp.xml");
- }
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = model->predict(data);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
- }
-
- else if (method == 3)
- {
- Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);
- Ptr model = KNearest::create();
- model->setDefaultK(2);
- model->setIsClassifier(true);
- model->train(tdata);
- cout << endl;
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = model->predict(data);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
-
- }
-
-
- else if (method == 4)
- {
- Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);
- Ptr model;;
- model = NormalBayesClassifier::create();
- model->train(tdata);
- cout << endl;
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = model->predict(data);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
-
- }
-
- else if (method == 5)
- {
- Ptr model;
- if (parser.has("load"))
- {
- cout << filename_to_load << endl;
- model = load_classifier(filename_to_load);
- }
- else
- {
- cout << "Training the classifier ...\n";
- Ptr tdata = prepare_train_data(training_data, training_label, lnum[0] + lnum[1]);
-
- model = SVM::create();
- model->setType(SVM::C_SVC);
-
-
- model->setKernel(SVM::LINEAR);
-
-
-
-
-
-
-
-
- model->setC(0.1);
- model->train(tdata);
- cout << endl;
- model->save("svm.xml");
- }
-
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = model->predict(data);
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
-
- }
-
-
- else if (method == 6)
- {
-
- Ptr lr1 = LogisticRegression::create();
- lr1->setLearningRate(0.01);
- lr1->setIterations(100);
- lr1->setRegularization(LogisticRegression::REG_L2);
- lr1->setTrainMethod(LogisticRegression::BATCH);
- lr1->setMiniBatchSize(1);
-
- cout << "training...";
- training_label.convertTo(training_label, CV_32F);
- lr1->train(training_data, ROW_SAMPLE, training_label);
- cout << "done!" << endl;
-
-
-
-
- string exten1 = "*.jpg";
- vector filenames;
- getFiles2(pathtest, "jpg", filenames);
- for (int i = 0; i < 1200; i++)
- {
- Mat srcimg = imread(pathtest + "\\" + filenames[i], CV_LOAD_IMAGE_GRAYSCALE);
- Mat dstimg;
- resize(srcimg, dstimg, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step0 = dstimg.step[0];
- int step1 = dstimg.step[1];
- uchar *pdstimg = dstimg.data;
- Mat srcimg2 = imread(pathtest + "\\" + filenames[i]);
- Mat dstimg2;
- resize(srcimg2, dstimg2, defaultSize, 0, 0, CV_INTER_LINEAR);
- int step02 = dstimg2.step[0];
- int step12 = dstimg2.step[1];
- uchar *pdstimg2 = dstimg2.data;
- int line = 0;
- double result;
- double t_rec;
- t_rec = (double)cvGetTickCount();
- for (int k = 76; k < 194; k++)
- {
- for (int j = 76; j < 154; j++)
- {
-
- Mat data(1, ATTRIBUTES_PER_SAMPLE, CV_32FC1);
-
- for (int attribute = 0; attribute < ATTRIBUTES_PER_SAMPLE; attribute++)
- if (attribute<25)
- data.at<float>(line, attribute) = (float)pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] / 255;
- else
-
- {
- float sum = 0;
- for (int l = (attribute - 24) * 25; l < (attribute - 23) * 25; l++)
-
- {
- if (pdstimg[j *step0 + k*step1] - pdstimg[(j + randx[attribute])*step0 + (k + randy[attribute])*step1] > 0)
- {
- sum = sum + 1;
- }
-
- }
- data.at<float>(line, attribute) = sum / 25;
- }
-
- result = lr1->predict(data);
-
- if (result>0)
- pdstimg2[j *step02 + k*step12] = 255;
-
-
- }
- }
- t_rec = (double)cvGetTickCount() - t_rec;
- cout << "timePerFrame = " << t_rec / ((double)cvGetTickFrequency() * 1000) << "ms" << endl;
- imshow("dst2", dstimg2);
- waitKey(10);
- }
-
-
- }
-
- return 0;
-
-
- }