8 #ifndef PCL_RF_FACE_UTILS_H_
9 #define PCL_RF_FACE_UTILS_H_
11 #include "pcl/recognition/face_detection/face_common.h"
12 #include <pcl/ml/feature_handler.h>
13 #include <pcl/ml/stats_estimator.h>
14 #include <pcl/ml/branch_estimator.h>
18 namespace face_detection
20 template<
class FT,
class DataSet,
class ExampleIndex>
28 float min_valid_small_patch_depth_;
36 min_valid_small_patch_depth_ = 0.5f;
97 srand (
static_cast<unsigned int>(time (NULL)));
99 float range_d = 0.05f;
100 float incr_d = 0.01f;
102 std::vector < FT > windows_and_functions;
104 for (
size_t i = 0; i < num_of_features; i++)
108 f.row1_ = rand () % (wsize_ - max_patch_size_ - 1);
109 f.col1_ = rand () % (wsize_ / 2 - max_patch_size_ - 1);
110 f.wsizex1_ = min_s + (rand () % (max_patch_size_ - min_s - 1));
111 f.wsizey1_ = min_s + (rand () % (max_patch_size_ - min_s - 1));
113 f.row2_ = rand () % (wsize_ - max_patch_size_ - 1);
114 f.col2_ = wsize_ / 2 + rand () % (wsize_ / 2 - max_patch_size_ - 1);
115 f.wsizex2_ = min_s + (rand () % (max_patch_size_ - 1 - min_s));
116 f.wsizey2_ = min_s + (rand () % (max_patch_size_ - 1 - min_s));
119 if (num_channels_ > 1)
120 f.used_ii_ = rand () % num_channels_;
122 windows_and_functions.push_back (f);
125 for (
size_t i = 0; i < windows_and_functions.size (); i++)
127 FT f = windows_and_functions[i];
128 for (
size_t j = 0; j <= 10; j++)
130 f.threshold_ = -range_d +
static_cast<float> (j) * incr_d;
131 features.push_back (f);
143 void evaluateFeature(
const FT & feature, DataSet & data_set, std::vector<ExampleIndex> & examples, std::vector<float> & results,
144 std::vector<unsigned char> & flags)
const
146 results.resize (examples.size ());
147 for (
size_t i = 0; i < examples.size (); i++)
149 evaluateFeature (feature, data_set, examples[i], results[i], flags[i]);
160 void evaluateFeature(
const FT & feature, DataSet & data_set,
const ExampleIndex & example,
float & result,
unsigned char & flag)
const
163 int el_f1 = te.
iimages_[feature.used_ii_]->getFiniteElementsCount (te.
col_ + feature.col1_, te.
row_ + feature.row1_, feature.wsizex1_,
165 int el_f2 = te.
iimages_[feature.used_ii_]->getFiniteElementsCount (te.
col_ + feature.col2_, te.
row_ + feature.row2_, feature.wsizex2_,
168 float sum_f1 =
static_cast<float>(te.
iimages_[feature.used_ii_]->getFirstOrderSum (te.
col_ + feature.col1_, te.
row_ + feature.row1_, feature.wsizex1_, feature.wsizey1_));
169 float sum_f2 =
static_cast<float>(te.
iimages_[feature.used_ii_]->getFirstOrderSum (te.
col_ + feature.col2_, te.
row_ + feature.row2_, feature.wsizex2_, feature.wsizey2_));
171 float f = min_valid_small_patch_depth_;
172 if (el_f1 == 0 || el_f2 == 0 || (el_f1 <=
static_cast<int> (f *
static_cast<float>(feature.wsizex1_ * feature.wsizey1_)))
173 || (el_f2 <=
static_cast<int> (f *
static_cast<float>(feature.wsizex2_ * feature.wsizey2_))))
175 result =
static_cast<float> (pcl_round (
static_cast<float>(rand ()) /
static_cast<float> (RAND_MAX)));
179 result =
static_cast<float> ((sum_f1 /
static_cast<float>(el_f1) - sum_f2 /
static_cast<float>(el_f2)) > feature.threshold_);
196 template<
class LabelDataType,
class NodeType,
class DataSet,
class ExampleIndex>
203 branch_estimator_ (branch_estimator)
233 Eigen::Vector3d & centroid)
const
235 Eigen::Matrix<double, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 9, Eigen::RowMajor>::Zero ();
236 unsigned int point_count =
static_cast<unsigned int> (examples.size ());
238 for (
size_t i = 0; i < point_count; ++i)
252 if (point_count != 0)
254 accu /=
static_cast<double> (point_count);
255 centroid.head<3> ().matrix () = accu.tail<3> ();
256 covariance_matrix.coeffRef (0) = accu[0] - accu[6] * accu[6];
257 covariance_matrix.coeffRef (1) = accu[1] - accu[6] * accu[7];
258 covariance_matrix.coeffRef (2) = accu[2] - accu[6] * accu[8];
259 covariance_matrix.coeffRef (4) = accu[3] - accu[7] * accu[7];
260 covariance_matrix.coeffRef (5) = accu[4] - accu[7] * accu[8];
261 covariance_matrix.coeffRef (8) = accu[5] - accu[8] * accu[8];
262 covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
263 covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
264 covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
277 Eigen::Vector3d & centroid)
const
279 Eigen::Matrix<double, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 9, Eigen::RowMajor>::Zero ();
280 unsigned int point_count =
static_cast<unsigned int> (examples.size ());
282 for (
size_t i = 0; i < point_count; ++i)
291 accu[6] += te.
rot_[0];
292 accu[7] += te.
rot_[1];
293 accu[8] += te.
rot_[2];
296 if (point_count != 0)
298 accu /=
static_cast<double> (point_count);
299 centroid.head<3> ().matrix () = accu.tail<3> ();
300 covariance_matrix.coeffRef (0) = accu[0] - accu[6] * accu[6];
301 covariance_matrix.coeffRef (1) = accu[1] - accu[6] * accu[7];
302 covariance_matrix.coeffRef (2) = accu[2] - accu[6] * accu[8];
303 covariance_matrix.coeffRef (4) = accu[3] - accu[7] * accu[7];
304 covariance_matrix.coeffRef (5) = accu[4] - accu[7] * accu[8];
305 covariance_matrix.coeffRef (8) = accu[5] - accu[8] * accu[8];
306 covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
307 covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
308 covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
322 float computeInformationGain(DataSet & data_set, std::vector<ExampleIndex> & examples, std::vector<LabelDataType> & label_data,
323 std::vector<float> & results, std::vector<unsigned char> & flags,
const float threshold)
const
325 const size_t num_of_examples = examples.size ();
329 std::vector < LabelDataType > sums (num_of_branches + 1, 0.f);
330 std::vector < LabelDataType > sqr_sums (num_of_branches + 1, 0.f);
331 std::vector < size_t > branch_element_count (num_of_branches + 1, 0.f);
333 for (
size_t branch_index = 0; branch_index < num_of_branches; ++branch_index)
335 branch_element_count[branch_index] = 1;
336 ++branch_element_count[num_of_branches];
339 for (
size_t example_index = 0; example_index < num_of_examples; ++example_index)
341 unsigned char branch_index;
342 computeBranchIndex (results[example_index], flags[example_index], threshold, branch_index);
344 LabelDataType label = label_data[example_index];
346 ++branch_element_count[branch_index];
347 ++branch_element_count[num_of_branches];
349 sums[branch_index] += label;
350 sums[num_of_branches] += label;
353 std::vector<float> hp (num_of_branches + 1, 0.f);
354 for (
size_t branch_index = 0; branch_index < (num_of_branches + 1); ++branch_index)
356 float pf = sums[branch_index] /
static_cast<float> (branch_element_count[branch_index]);
357 float pnf = (
static_cast<LabelDataType
>(branch_element_count[branch_index]) - sums[branch_index] + 1.f)
358 /
static_cast<LabelDataType
> (branch_element_count[branch_index]);
359 hp[branch_index] -=
static_cast<float>(pf * log (pf) + pnf * log (pnf));
363 float purity = sums[num_of_branches] /
static_cast<LabelDataType
>(branch_element_count[num_of_branches]);
370 std::vector < size_t > branch_element_count (num_of_branches + 1, 0);
371 std::vector < std::vector<ExampleIndex> > positive_examples;
372 positive_examples.resize (num_of_branches + 1);
375 for (
size_t example_index = 0; example_index < num_of_examples; ++example_index)
377 unsigned char branch_index;
378 computeBranchIndex (results[example_index], flags[example_index], threshold, branch_index);
380 LabelDataType label = label_data[example_index];
384 ++branch_element_count[branch_index];
385 ++branch_element_count[num_of_branches];
387 positive_examples[branch_index].push_back (examples[example_index]);
388 positive_examples[num_of_branches].push_back (examples[example_index]);
394 std::vector < Eigen::Matrix3d > offset_covariances;
395 std::vector < Eigen::Matrix3d > angle_covariances;
397 std::vector < Eigen::Vector3d > offset_centroids;
398 std::vector < Eigen::Vector3d > angle_centroids;
400 offset_covariances.resize (num_of_branches + 1);
401 angle_covariances.resize (num_of_branches + 1);
402 offset_centroids.resize (num_of_branches + 1);
403 angle_centroids.resize (num_of_branches + 1);
405 for (
size_t branch_index = 0; branch_index < (num_of_branches + 1); ++branch_index)
408 offset_centroids[branch_index]);
410 angle_centroids[branch_index]);
414 std::vector<float> hr (num_of_branches + 1, 0.f);
415 for (
size_t branch_index = 0; branch_index < (num_of_branches + 1); ++branch_index)
417 hr[branch_index] =
static_cast<float>(0.5f * log (std::pow (2 * M_PI, 3)
418 * offset_covariances[branch_index].determinant ())
419 + 0.5f * log (std::pow (2 * M_PI, 3)
420 * angle_covariances[branch_index].determinant ()));
423 for (
size_t branch_index = 0; branch_index < (num_of_branches + 1); ++branch_index)
425 hp[branch_index] += std::max (sums[branch_index] /
static_cast<float> (branch_element_count[branch_index]) - tp, 0.f) * hr[branch_index];
429 float information_gain = hp[num_of_branches + 1];
430 for (
size_t branch_index = 0; branch_index < (num_of_branches); ++branch_index)
432 information_gain -=
static_cast<float> (branch_element_count[branch_index]) /
static_cast<float> (branch_element_count[num_of_branches])
436 return information_gain;
445 void computeBranchIndices(std::vector<float> & results, std::vector<unsigned char> & flags,
const float threshold,
446 std::vector<unsigned char> & branch_indices)
const
448 const size_t num_of_results = results.size ();
450 branch_indices.resize (num_of_results);
451 for (
size_t result_index = 0; result_index < num_of_results; ++result_index)
453 unsigned char branch_index;
454 computeBranchIndex (results[result_index], flags[result_index], threshold, branch_index);
455 branch_indices[result_index] = branch_index;
465 inline void computeBranchIndex(
const float result,
const unsigned char flag,
const float threshold,
unsigned char & branch_index)
const
476 void computeAndSetNodeStats(DataSet & data_set, std::vector<ExampleIndex> & examples, std::vector<LabelDataType> & label_data, NodeType & node)
const
478 const size_t num_of_examples = examples.size ();
480 LabelDataType sum = 0.0f;
481 LabelDataType sqr_sum = 0.0f;
482 for (
size_t example_index = 0; example_index < num_of_examples; ++example_index)
484 const LabelDataType label = label_data[example_index];
487 sqr_sum += label * label;
490 sum /=
static_cast<float>(num_of_examples);
491 sqr_sum /=
static_cast<float>(num_of_examples);
493 const float variance = sqr_sum - sum * sum;
496 node.variance = variance;
499 std::vector < ExampleIndex > positive_examples;
501 for (
size_t example_index = 0; example_index < num_of_examples; ++example_index)
503 LabelDataType label = label_data[example_index];
506 positive_examples.push_back (examples[example_index]);
521 stream <<
"ERROR: RegressionVarianceStatsEstimator does not implement generateCodeForBranchIndex(...)";
530 stream <<
"ERROR: RegressionVarianceStatsEstimator does not implement generateCodeForBranchIndex(...)";