//初始化时,每个后验概率都得初始化为0;运行时候以下面方式更新:已知类别标签的样本(训练样本)通过n个分类器
//进行分类,如果分类结果错误,那么响应的#p和#n就会更新,这样P(y|x)也相应更新了
posteriors.push_back(vector<float>(pow(2.0,structSize), 0));
pCounter.push_back(vector<int>(pow(2.0,structSize), 0));
nCounter.push_back(vector<int>(pow(2.0,structSize), 0));
}
}
//该函数得到输入的image的用于树的节点,也就是特征组的特征(13位的二进制代码)
void FerNNClassifier::getFeatures(const cv::Mat& image, const int& scale_idx, vector<int>& fern){
int leaf; //叶子 树的最终节点
//每一个每类器维护一个后验概率的分布,这个分布有2^d个条目(entries),这里d是像素比较pixel comparisons
//的个数,这里是structSize,即13个comparison,所以会产生2^13即8,192个可能的code,每一个code对应一个后验概率
for (int t=0; t<nstructs; t++){ //nstructs 表示树的个数 10
leaf=0;
for (int f=0; f<structSize; f++){ //表示每棵树特征的个数 13
//struct Feature 特征结构体有一个运算符重载 bool operator ()(const cv::Mat& patch) const
//返回的patch图像片在(y1,x1)和(y2, x2)点的像素比较值,返回0或者1
//然后leaf就记录了这13位的二进制代码,作为特征
leaf = (leaf << 1) + features[scale_idx][t*nstructs+f](image);
}
fern[t] = leaf;
}
}
float FerNNClassifier::measure_forest(vector<int> fern) {
float votes = 0;
for (int i = 0; i < nstructs; i++) {
// 后验概率posteriors[i][idx] = ((float)(pCounter[i][idx]))/(pCounter[i][idx] + nCounter[i][idx]);
votes += posteriors[i][fern[i]]; //每棵树的每个特征值对应的后验概率累加值 作投票值??
}
return votes;
}
//更新正负样本数,同时更新后验概率