40 m_bayes = cv::ml::NormalBayesClassifier::create();
41 m_svm = cv::ml::SVM::create();
42 m_dt = cv::ml::DTrees::create();
43 m_rt = cv::ml::RTrees::create();
44 m_boost = cv::ml::Boost::create();
45 m_ann = cv::ml::ANN_MLP::create();
46 m_knn = cv::ml::KNearest::create();
52 m_svm->setType(cv::ml::SVM::C_SVC);
53 m_svm->setKernel(cv::ml::SVM::RBF);
60 m_dt->setMaxCategories(6);
63 m_boost->setBoostType(cv::ml::Boost::DISCRETE);
64 m_boost->setWeakCount(20);
65 m_boost->setWeightTrimRate(0);
68 m_rt->setMaxCategories(6);
73 m_newHistoryData =
false;
74 m_featurePerSample = featurePerSample;
78 m_sensibility = sensibility;
83 m_detectionThread = 0;
89 if (m_trainingThread != 0)
91 m_trainingThread->join();
92 delete m_trainingThread;
98 if (m_detectionThread != 0)
100 m_detectionThread->join();
101 delete m_detectionThread;
102 m_detectionThread = 0;
106 m_categories.clear();
107 m_dataHistory.clear();
114 boost::mutex::scoped_lock lock(m_trainingCriticalSection);
115 return m_trainingState;
120 boost::mutex::scoped_lock lock(m_trainingCriticalSection);
121 m_trainingState = state;
127 for (
unsigned int i = 0; i < m_categories.size(); i++)
129 if (m_categories[i].compare(name) == 0)
137 if(pos < m_categories.size())
138 return m_categories[pos];
141 return std::string(
"none");
147 std::vector<std::string> names;
148 for(
unsigned int i = 0; i < m_categories.size(); i++)
150 names.push_back(m_categories[i]);
159 if ((
GetTrainingState() ==
TRAINING) || ((
int)input.size() < m_featurePerSample) || ((m_lastInputDate != 0) && ((cv::getTickCount() - m_lastInputDate) < 30)))
177 m_categories.push_back(label);
178 cat = m_categories.size() -1;
182 for (
unsigned int i = 0; i < input.size(); i = i + m_featurePerSample)
184 if ((i + m_featurePerSample) > (
int)input.size())
188 std::vector<MlFeature> sample;
189 for (
int k = 0; k < (int)m_featurePerSample; k++)
191 sample.push_back(
MlFeature(input[i + k], cv::getTickCount()));
195 SamplesMap::iterator catIt = m_samples.find(cat);
196 if (catIt == m_samples.end())
197 m_samples[cat].push_back(sample);
199 catIt->second.push_back(sample);
202 m_lastInputDate = cv::getTickCount();
205std::vector<std::vector<MlFeature>> NeuralNetwork::ComputeData(std::vector<std::vector<MlFeature>> ldata)
207 std::vector<std::vector<MlFeature>> sortedData;
208 std::vector<std::vector<MlFeature>> outData;
209 sortedData.resize(m_featurePerSample);
212 unsigned int lsize = ldata.size();
215 for(
unsigned int i = 0; i < ldata.size(); i++)
217 std::vector<MlFeature> samples;
219 for (
unsigned int k = 0; k < m_featurePerSample; k++)
222 if(k < ldata[i].size())
223 sortedData[k].push_back(ldata[i][k]);
232 for(
unsigned int k = 0; k < sortedData.size(); k++)
234 if ((
int)sortedData[k].size() < (m_nbAnchorPoints + 1))
237 if (sortedData[k].size() < 2)
238 sortedData[k].insert(sortedData[k].begin(),
MlFeature());
241 while ((
int)sortedData[k].size() <= (m_nbAnchorPoints + 1))
243 for (
int j = 0; j < ((int)sortedData[k].size() - 1); j++)
254 sortedData[k].insert(sortedData[k].begin() + j, (p1 + pn));
264 while ((
int)sortedData[k].size() > (m_nbAnchorPoints + 1))
267 double d_min = std::numeric_limits<double>::max();
269 std::vector<MlFeature>::iterator p_min = sortedData[k].begin();
272 std::vector<MlFeature>::iterator p = p_min;
273 std::vector<MlFeature>::iterator i = p_min;
276 std::vector<MlFeature>::iterator last = sortedData[k].end();
279 for (; i != last; ++i)
281 d = sqrt(pow((*p).x - (*i).x, 2) + pow((*p).y - (*i).y, 2) + pow((*p).z - (*i).z, 2));
294 pt.x = ((*p).x + (*i).x) / 2;
295 pt.y = ((*p).y + (*i).y) / 2;
296 pt.z = ((*p).z + (*i).z) / 2;
297 pt.
t = ((*p).t + (*i).t) / 2;
300 sortedData[k].erase(p);
311 for(
unsigned int k = 0; k < sortedData.size(); k++)
313 std::vector<MlFeature>::iterator i = sortedData[k].begin();
314 std::vector<MlFeature>::iterator p = i++;
315 std::vector<MlFeature> ndata;
317 for (; i != sortedData[k].end(); ++i)
322 np.
t = pt2.
t - pt1.
t;
331 float xangles = 0.0f;
332 float yangles = 0.0f;
333 float zangles = 0.0f;
335 xangles = (float) (atan2((pt2.y - pt1.y), (pt2.x - pt1.x)) * 180.0 / (double)
SCOL_PI);
337 xangles = 360.f + xangles;
339 yangles = (float) (atan2((pt2.y - pt1.y), (pt2.z - pt1.z)) * 180.0 / (double)
SCOL_PI);
341 yangles = 360.f + yangles;
355 outData.push_back(ndata);
397 if (m_trainingThread != 0)
399 m_trainingThread->join();
400 delete m_trainingThread;
401 m_trainingThread = 0;
404 if (m_detectionThread != 0)
406 m_detectionThread->join();
407 delete m_detectionThread;
408 m_detectionThread = 0;
412 m_trainingThread =
new boost::thread(boost::bind(&NeuralNetwork::TrainingThread,
this));
417void NeuralNetwork::TrainingThread()
420 m_nbMinSamples = std::numeric_limits<int>::max();
425 for(SamplesMap::iterator i = m_samples.begin(); i != m_samples.end(); i++)
427 m_nbMaxSamples = std::max(m_nbMaxSamples, (
int)i->second.size());
428 m_nbMinSamples = std::min(m_nbMinSamples, (
int)i->second.size());
430 for (
unsigned int j = 0; j < i->second.size(); j++)
433 m_averageTime += i->second[j][0].t - lasttime;
434 lasttime = i->second[j][0].t;
441 m_averageTime /= m_nbSamples;
443 if (m_averageTime == 0)
447 m_nbAnchorPoints = m_nbSamples;
450 cv::Mat trainIn(m_nbAnchorPoints * m_categories.size(), m_featurePerSample * 3, CV_32FC1);
452 cv::Mat trainOut(m_nbAnchorPoints * m_categories.size(), 1, CV_32FC1);
456 cv::Mat var_type(trainIn.cols + 1, 1, CV_8U);
457 var_type.setTo(cv::ml::VAR_NUMERICAL);
458 var_type.at<uchar>(trainIn.cols, 0) = cv::ml::VAR_CATEGORICAL;
463 for(SamplesMap::iterator i = m_samples.begin(); i != m_samples.end(); i++)
468 if ((i->second.size() < 2) && (m_mode ==
ML_MOTION))
471 std::vector<std::vector<MlFeature>> data = ComputeData(i->second);
474 for (
unsigned int j = 0; j < data.size(); j++)
477 for (
unsigned int k = 0; (k < m_nbAnchorPoints) && (k < data[j].size()); k++)
480 trainIn.at<
float>(k + (i->first * m_nbAnchorPoints), featureIdx) = (float)data[j][k].x;
481 trainIn.at<
float>(k + (i->first * m_nbAnchorPoints), featureIdx +1) = (float)data[j][k].y;
482 trainIn.at<
float>(k + (i->first * m_nbAnchorPoints), featureIdx +2) = (float)data[j][k].z;
487 trainOut.at<
float>(sampleIdx) = data[j][k].t == 0 ? -1 : (float)i->first;
492 featureIdx = featureIdx + 3;
496 cv::Ptr<cv::ml::TrainData> traindata = cv::ml::TrainData::create(trainIn, cv::ml::ROW_SAMPLE, trainOut);
501 m_knn->train(traindata);
506 m_bayes->train(traindata);
511 m_svm->train(traindata);
516 m_dt->train(traindata);
521 m_boost->train(traindata);
526 m_rt->train(traindata);
538 m_detectionThread =
new boost::thread(boost::bind(&NeuralNetwork::DetectionThread,
this));
543 catch(cv::Exception &e)
545 MMechostr(MSKRUNTIME,
"Machine learning - Trainning Error : %s", e.what());
552void NeuralNetwork::ValidateDetectedData()
555 boost::mutex::scoped_lock lock(m_detectionCriticalSection);
556 bool tooLong = (m_lastInputDate != 0) && (((
int)cv::getTickCount() - m_lastInputDate) > (m_averageTime * 3));
557 if (tooLong || ((
int)m_dataHistory.size() >= m_nbMaxSamples))
560 if(m_lastDetected.size() != 0)
562 unsigned int catId = (
unsigned int)m_lastDetected[m_lastDetected.size() - 1][0];
563 std::string* catname =
new std::string(
GetCategory(catId));
564 m_lastDetected.clear();
565 m_dataHistory.clear();
566 m_newHistoryData =
false;
575 m_dataHistory.clear();
576 m_newHistoryData =
false;
582 boost::this_thread::sleep_for(boost::chrono::milliseconds(m_averageTime));
585void NeuralNetwork::DetectionThread()
589 std::vector<std::vector<MlFeature>> data;
591 boost::mutex::scoped_lock lock(m_detectionCriticalSection);
594 if (m_dataHistory.empty() || ((
int)m_dataHistory.size() < m_nbMinSamples))
598 data = ComputeData(m_dataHistory);
601 if (!m_newHistoryData)
603 ValidateDetectedData();
608 m_newHistoryData =
false;
611 cv::Mat recognizeIn(m_nbAnchorPoints, m_featurePerSample * 3, CV_32FC1);
612 cv::Mat recognizeOut(m_nbAnchorPoints, 1, CV_32FC1);
613 recognizeOut.setTo(-1);
617 for (
unsigned int i = 0; i < data.size(); i++)
620 for (
unsigned int k = 0; (k < m_nbAnchorPoints) && (k < data[i].size()); k++)
622 recognizeIn.at<
float>(k, featureIdx) = (
float)data[i][k].x;
623 recognizeIn.at<
float>(k, featureIdx+1) = (
float)data[i][k].y;
624 recognizeIn.at<
float>(k, featureIdx+2) = (
float)data[i][k].z;
626 featureIdx = featureIdx + 3;
630 float accuracy = 0.0f;
633 Reconize(recognizeIn, recognizeOut);
634 cat = Evaluate(recognizeOut, accuracy);
636 catch(cv::Exception &e)
638 MMechostr(MSKRUNTIME,
"Machine learning - Recognized Error : %s", e.what());
639 ValidateDetectedData();
645 ValidateDetectedData();
649 std::vector<float> result;
650 result.push_back((
float)cat);
651 result.push_back(accuracy);
654 m_lastDetected.push_back(result);
656 ValidateDetectedData();
662 if(m_samples.empty())
669 for(SamplesMap::iterator i = m_samples.begin(); i != m_samples.end(); i++)
671 std::string catname =
GetCategory((
unsigned int)i->first);
672 std::vector<std::vector<MlFeature>> data = i->second;
678 for (
unsigned int j = 0; j < data.size(); j++)
683 for (
unsigned int k = 0; k < data[j].size(); k++)
710 m_categories.clear();
721 std::string catname = catnode->
Attribute(
"name");
726 m_categories.push_back(catname);
727 catid = m_categories.size() -1;
733 std::vector<MlFeature> sample;
745 sample.push_back(feature);
750 m_featurePerSample = std::max((
int)m_featurePerSample, numFeatures);
752 SamplesMap::iterator catIt = m_samples.find(catid);
753 if (catIt == m_samples.end())
754 m_samples[catid].push_back(sample);
756 catIt->second.push_back(sample);
775 cv::ml::DTrees::Node* n = 0;
776 for (
int r = 0; r < reconizeIn.rows; r++)
778 sample = reconizeIn.row(r);
783 v = m_knn->findNearest(sample, m_knn_p, out);
787 v = m_bayes->predict(sample);
791 v = m_svm->predict(sample);
795 v = m_dt->predict(sample);
802 v = m_boost->predict(sample);
806 v = m_rt->predict(sample);
813 reconizeOut.at<
float>(r, 0) = v;
817int NeuralNetwork::Evaluate(cv::Mat& predicted,
float &accuracy)
819 std::vector<int> countCategories;
820 countCategories.resize(m_categories.size());
821 for (
unsigned int i = 0; i < countCategories.size(); i++)
822 countCategories[i] = 0;
825 for (
int i = 0; i < predicted.rows; i++)
827 float p = predicted.at<
float>(i, 0);
831 countCategories[(int)p]++;
835 int maxCategory = -1;
836 int nbCorrelFound = 0;
839 for (
unsigned int i = 0; i < countCategories.size(); i++)
857 if (countCategories[i] > nbCorrelFound)
859 nbCorrelFound = countCategories[i];
864 accuracy = (float)nbCorrelFound / (
float)m_nbAnchorPoints;
865 if (accuracy < m_sensibility)
873 if ((
GetTrainingState() !=
TRAINED) || (input.size() == 0) || ((m_lastInputDate != 0) && ((
int)(cv::getTickCount() - m_lastInputDate) < m_averageTime)))
876 boost::mutex::scoped_lock lock(m_detectionCriticalSection);
879 for (
unsigned int i = 0; i < input.size(); i += m_featurePerSample)
881 if ((i + m_featurePerSample) > (
int)input.size())
884 std::vector<MlFeature> sample;
885 for (
unsigned int k = 0; k < m_featurePerSample; k++)
887 sample.push_back(
MlFeature(input[i+k], cv::getTickCount()));
890 m_dataHistory.push_back(sample);
892 m_newHistoryData =
true;
896 while ((
int)m_dataHistory.size() > m_nbMaxSamples)
898 m_dataHistory.erase(m_dataHistory.begin());
900 m_lastInputDate = cv::getTickCount();
int WM_ML_TRAINING_FINISHED
void Save(std::string saveFile)
NeuralNetwork(int featurePerSample, float sensibility, MlMode mode=ML_POSE, MlType type=KNN)
std::string GetCategory(unsigned int pos)
std::vector< std::string > GetCategories()
void Reconize(cv::Mat reconizeIn, cv::Mat reconizeOut)
int GetCategoryPos(std::string name)
TrainingState GetTrainingState()
void Load(std::string filename)
void AddTrainingData(std::vector< cv::Point3d > input, std::string label)
void AddDetectionData(std::vector< cv::Point3d >)
XMLError LoadFile(const char *filename)
XMLElement * NewElement(const char *name)
XMLError SaveFile(const char *filename, bool compact=false)
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
const char * Attribute(const char *name, const char *value=0) const
float FloatAttribute(const char *name) const
See IntAttribute()
int IntAttribute(const char *name) const
void DeleteChild(XMLNode *node)
const XMLElement * FirstChildElement(const char *value=0) const
XMLNode * InsertEndChild(XMLNode *addThis)