-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeakClassifier.cpp
More file actions
146 lines (137 loc) · 4.43 KB
/
WeakClassifier.cpp
File metadata and controls
146 lines (137 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*2016.4.13
每个弱分类器相当于一种特性的划分标准。对于每一个弱分类器来说,需要是什么类别,单个样本的在此划分标准下值是多少,以及最终分到哪一类了
对于每一个样本图像,训练的时候我们需要对正负样本进行遍历,用我们已经设定好的特征类型去计算样本其每个位置、大小、形状的特征值,
然后根据正负样本的规模,计算弱分类器(这个指标)下的分布权重、阈值、样本的特征值。这里首先根据正负样本的权值进行排序,然后依据排序后的权重计算
误差阈值,再根据e的计算公式得到一系列的正负样本的权重和分类器阈值。最后,传入样本特征值,依据阈值对样本进行正负分类。*/
#include "WeakClassifier.h"
#include <math.h>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
/*弱分类器,用权值、特征值、极性组成*/
struct h_f_p_t {
float value;
bool polarity;
float weight;
};
/*定义弱分类器参数*/
struct weakClassifier
{
int indexF;
float threshold;
};
/*定义排序方法*/
static bool compare(const h_f_p_t &a, const h_f_p_t &b) {
return a.value < b.value; //如果a分类器特征值比b的小,则返回true
}
WeakClassifier::WeakClassifier(Feature *f) {
this->f = f;
}
WeakClassifier::WeakClassifier(Feature *f, float threshold, bool polarity) {
this->f = f;
this->threshold = threshold;
this->polarity = polarity;
}
/*寻找最优阈值*/
float WeakClassifier::find_optimum_threshold(float *fvalues, int fsize, int nfsize, float *weights) {
h_f_p_t *score = new h_f_p_t[fsize + nfsize];
for (int i = 0; i<fsize; i++) { //正样本特征值、标签、权值
score[i].value = fvalues[i];
score[i].polarity = true;
score[i].weight = weights[i];
}
for (int j = 0; j<nfsize; j++) { //负样本特征值、标签、权值
score[j + fsize].value = fvalues[j + fsize];
score[j + fsize].polarity = false;
score[j + fsize].weight = weights[j + fsize];
}
std::sort(score, score + fsize + nfsize, compare); //将特征值排序,第一个参数是排序起始地址,第二个参数是结束地址,第三个参数是排序类型
/*for (int i = 0; i < fsize + nfsize; i++)
{
std::cout << score[i].value << " ";
}
system("pause");*/
wsum *ws = new wsum[fsize + nfsize];
float tp = 0;
float tn = 0;
if (score[0].polarity == false) { //划分负样本的权重
tn = score[0].weight; //保存当前权重值
ws[0].sn = score[0].weight; //赋值负样本权重和S-
ws[0].sp = 0;
}
else { //划分正样本的权重
tp = score[0].weight;
ws[0].sp = score[0].weight;
ws[0].sn = 0;
}
for (int k = 1; k<(fsize + nfsize); k++) {
if (score[k].polarity == false) {
tn += score[k].weight; //计算全部负样本权重和T-
ws[k].sn = ws[k - 1].sn + score[k].weight; //计算当前负样本权重和S-
ws[k].sp = ws[k - 1].sp;
}
else {
tp += score[k].weight; //计算全部正样本权重和T+
ws[k].sp = ws[k - 1].sp + score[k].weight; //计算当前正样本权重和S+
ws[k].sn = ws[k - 1].sn;
}
}
float minerror = 1;
float errorp;
float errorm;
for (int l = 0; l<(fsize + nfsize); l++) { // e=min{(S+)+[(T-)-(S-)],(S-)+[(T+)-(S+)]),并且定义一个最小误差
errorp = ws[l].sp + tn - ws[l].sn;
errorm = ws[l].sn + tp - ws[l].sp;
// if (errorm >= 0.1 && errorp >= 0.1){
if (errorp < errorm) {
if (errorp < minerror) {
minerror = errorp; //找到最小的分类误差阈值,并判断极性
this->threshold = score[l].value;
this->polarity = false;
}
}
else {
if (errorm < minerror) {
minerror = errorm;
this->threshold = score[l].value;
this->polarity = true;
}
}
// }
}
delete[] score;
delete[] ws;
return minerror;
}
Feature* WeakClassifier::getFeature() {
return this->f;
}
float WeakClassifier::getthreshold() {
return this->threshold;
}
int WeakClassifier::getPolarity() {
return this->polarity;
}
/*利用弱分类器对正负样本分类,返回值为1/-1*/
int WeakClassifier::classify(float *img, int imwidth, int x, int y, float mean, float stdev) {
float fval = this->f->getValue(img, imwidth, x, y);
// 若是第二种或者第三种特征
if (this->f->getType() == 2 || this->f->getType() == 3)
fval = (fval + (this->f->getWidth()*this->f->getHeight()*mean / 3)); //样本特征值= 累加求和(宽*高*平均值/3)
if (stdev != 0) fval = fval / stdev; //调整特征值,除以一个系数
//std::cout << "fval:" << fval << std::endl;
if (fval < this->threshold) { //如果特征值小于阈值,且是正样本返回1
if (this->polarity) return 1;
else return -1;
}
else { //如果特征值大于阈值,且是负样本返回1
if (this->polarity) return -1;
else return 1;
}
}
void WeakClassifier::scale(float s) {
f->scale(s);
this->threshold = (this->threshold)*pow(s, 2);
}