Direct Graphical Models  v.1.7.0
TrainNodeCvKNN.cpp
1 #include "TrainNodeCvKNN.h"
2 #include "SamplesAccumulator.h"
3 
4 namespace DirectGraphicalModels
5 {
6  // Constructor
7  CTrainNodeCvKNN::CTrainNodeCvKNN(byte nStates, word nFeatures, TrainNodeCvKNNParams params) : CBaseRandomModel(nStates), CTrainNode(nStates, nFeatures)
8  {
9  init(params);
10  }
11 
12  // Constructor
13  CTrainNodeCvKNN::CTrainNodeCvKNN(byte nStates, word nFeatures, size_t maxSamples) : CBaseRandomModel(nStates), CTrainNode(nStates, nFeatures)
14  {
16  params.maxSamples = maxSamples;
17  init(params);
18  }
19 
21  {
23  m_pKNN = ml::KNearest::create();
24  // using ml::KNearest::KDTREE causes an OpenCV exception
25  // this is committed as bug #8917
26  // https://github.com/opencv/opencv/issues/8917
27  m_pKNN->setAlgorithmType(ml::KNearest::BRUTE_FORCE);
28  m_params = params;
29  }
30 
31  // Destructor
33  {
34  delete m_pSamplesAcc;
35  }
36 
38  {
40  m_pKNN->clear();
41  }
42 
43  void CTrainNodeCvKNN::save(const std::string &path, const std::string &name, short idx) const
44  {
45  std::string fileName = generateFileName(path, name.empty() ? "TrainNodeCvKNN" : name, idx);
46  m_pKNN->save(fileName.c_str());
47  }
48 
49  void CTrainNodeCvKNN::load(const std::string &path, const std::string &name, short idx)
50  {
51  std::string fileName = generateFileName(path, name.empty() ? "TrainNodeCvKNN" : name, idx);
52  m_pKNN = Algorithm::load<ml::KNearest>(fileName.c_str());
53  }
54 
55  void CTrainNodeCvKNN::addFeatureVec(const Mat &featureVector, byte gt)
56  {
57  m_pSamplesAcc->addSample(featureVector, gt);
58  }
59 
60  void CTrainNodeCvKNN::train(bool doClean)
61  {
62 #ifdef DEBUG_PRINT_INFO
63  printf("\n");
64 #endif
65 
66  // Filling the <samples> and <classes>
67  Mat samples, classes;
68  for (byte s = 0; s < m_nStates; s++) { // states
69  int nSamples = m_pSamplesAcc->getNumSamples(s);
70 #ifdef DEBUG_PRINT_INFO
71  printf("State[%d] - %d of %d samples\n", s, nSamples, m_pSamplesAcc->getNumInputSamples(s));
72 #endif
73  samples.push_back(m_pSamplesAcc->getSamplesContainer(s));
74  classes.push_back(Mat(nSamples, 1, CV_32FC1, Scalar(s)));
75  if (doClean) m_pSamplesAcc->release(s); // free memory
76  } // s
77  samples.convertTo(samples, CV_32FC1);
78 
79  // Filling <var_type>
80  Mat var_type(getNumFeatures() + 1, 1, CV_8UC1, Scalar(ml::VAR_NUMERICAL)); // all inputs are numerical
81  var_type.at<byte>(getNumFeatures(), 0) = ml::VAR_CATEGORICAL;
82 
83  // Training
84  try {
85  m_pKNN->train(ml::TrainData::create(samples, ml::ROW_SAMPLE, classes, noArray(), noArray(), noArray(), var_type));
86  }
87  catch (std::exception &e) {
88  printf("EXCEPTION: %s\n", e.what());
89  getchar();
90  exit(-1);
91  }
92  }
93 
94  void CTrainNodeCvKNN::calculateNodePotentials(const Mat &featureVector, Mat &potential, Mat &mask) const
95  {
96  Mat fv;
97  featureVector.convertTo(fv, CV_32FC1);
98  //float res = m_pKNN->predict(fv.t());
99  //byte s = static_cast<byte>(res);
100  //potential.at<float>(s, 0) = 1.0f;
101  //potential += 0.1f;
102 
103  Mat result, neighborResponses;
104  m_pKNN->findNearest(fv.t(), static_cast<int>(m_params.maxNeighbors), result, neighborResponses);
105 
106  float *pResponse = neighborResponses.ptr<float>(0);
107  int n = neighborResponses.cols;
108  for (int i = 0; i < n; i++) {
109  byte s = static_cast<byte>(pResponse[i]);
110  potential.at<float>(s, 0) += 1.0f;
111  }
112  if (n) potential /= n;
113  potential += m_params.bias;
114  }
115 }
OpenCV k-Nearest Neighbors parameters.
Ptr< ml::KNearest > m_pKNN
k-Nearest Neighbors
void reset(void)
Resets class variables.
size_t maxNeighbors
Max number of neighbors to be used for calculating potentials.
word getNumFeatures(void) const
Returns number of features.
Definition: ITrain.h:37
std::string generateFileName(const std::string &path, const std::string &name, short idx) const
Generates name of the data file for storing random model parameters.
int getNumSamples(byte state) const
Returns the number of stored samples in container for the state (class) state.
void save(const std::string &path, const std::string &name=std::string(), short idx=-1) const
Saves the training data.
void init(TrainNodeCvKNNParams params)
const TrainNodeCvKNNParams TRAIN_NODE_CV_KNN_PARAMS_DEFAULT
Base abstract class for random model training.
void release(byte state)
Releases memory of container for the state (class) state.
void addFeatureVec(const Mat &featureVector, byte gt)
Adds new feature vector.
void train(bool doClean=false)
Random model training.
float bias
Regularization CRF parameter: bias is added to all potential values.
void addSample(const Mat &featureVector, byte state)
Adds new sample to the accumulator.
void reset(void)
Resets the accumulator.
Samples accumulator abstract class.
size_t maxSamples
Maximum number of samples to be used in training. 0 means using all the samples.
void load(const std::string &path, const std::string &name=std::string(), short idx=-1)
Loads the training data.
Base abstract class for node potentials training.
Definition: TrainNode.h:47
Mat getSamplesContainer(byte state) const
Returns samples container for the state (class) state.
void calculateNodePotentials(const Mat &featureVector, Mat &potential, Mat &mask) const
Calculates the node potential, based on the feature vector.
CSamplesAccumulator * m_pSamplesAcc
Samples Accumulator.
int getNumInputSamples(byte state) const
Returns the number of input samples in container for the state (class) state.
CTrainNodeCvKNN(byte nStates, word nFeatures, TrainNodeCvKNNParams params=TRAIN_NODE_CV_KNN_PARAMS_DEFAULT)
Constructor.
byte m_nStates
The number of states (classes)