diff --git a/dollar/EnginePPlus.cpp b/dollar/EnginePPlus.cpp index a460309..3a9cae1 100644 --- a/dollar/EnginePPlus.cpp +++ b/dollar/EnginePPlus.cpp @@ -18,16 +18,18 @@ dollar::EnginePPlus::EnginePPlus(): m_PPlusDistance(0.10f), m_PPlusExcludeDistance(0.2*0.2), - m_scaleKeepRatio(false) { + m_scaleKeepRatio(false), + m_penalityNotLinkRef(0.1), + m_penalityNotLinkSample(0.1) { } void dollar::EnginePPlus::setPPlusDistance(float _value) { - if (_value*_value == m_PPlusDistance) { + if (_value == m_PPlusDistance) { return; } - m_PPlusDistance = _value*_value; + m_PPlusDistance = _value; for (auto &it: m_gestures) { if (it == nullptr) { continue; @@ -37,18 +39,18 @@ void dollar::EnginePPlus::setPPlusDistance(float _value) { } float dollar::EnginePPlus::getPPlusDistance() { - return std::sqrt(m_PPlusDistance); + return m_PPlusDistance; } void dollar::EnginePPlus::setPPlusExcludeDistance(float _value) { - if (_value == m_PPlusExcludeDistance) { + if (_value*_value == m_PPlusExcludeDistance) { return; } - m_PPlusExcludeDistance = _value; + m_PPlusExcludeDistance = _value*_value; } float dollar::EnginePPlus::getPPlusExcludeDistance() { - return m_PPlusExcludeDistance; + return std::sqrt(m_PPlusExcludeDistance); } void dollar::EnginePPlus::setScaleKeepRatio(bool _value) { if (_value == m_scaleKeepRatio) { @@ -67,6 +69,78 @@ bool dollar::EnginePPlus::getScaleKeepRatio() { return m_scaleKeepRatio; } +void dollar::EnginePPlus::setPenalityNotLinkRef(float _value) { + m_penalityNotLinkRef = _value; +} + +float dollar::EnginePPlus::getPenalityNotLinkRef() { + return m_penalityNotLinkRef; +} +void dollar::EnginePPlus::setPenalityNotLinkSample(float _value) { + m_penalityNotLinkSample = _value; +} + +float dollar::EnginePPlus::getPenalityNotLinkSample() { + return m_penalityNotLinkSample; +} + + +float dollar::EnginePPlus::calculatePPlusDistanceSimple(const std::vector& _points, + const std::vector& _reference, + std::vector>& _dataDebug) { + std::vector distance; // note: use square distance (faster, we does not use std::sqrt()) + distance.resize(_points.size(), MAX_FLOAT); + // point Id that is link on the reference. + std::vector usedId; + usedId.resize(_points.size(), -1); + for (size_t iii=0; iii<_points.size(); iii++) { + float bestDistance = MAX_FLOAT; + int32_t kkkBest = -1; + for (size_t kkk=0; kkk<_reference.size(); ++kkk) { + float dist = (_points[iii]-_reference[kkk]).length2(); + if (dist < bestDistance) { + bestDistance = dist; + kkkBest = kkk; + } + } + if (kkkBest != -1) { + // reject the distance ... if too big ... + if (bestDistance <= m_PPlusExcludeDistance) { + usedId[iii] = kkkBest; + distance[iii] = bestDistance; + //DOLLAR_INFO("set new link: " << iii << " with " << kkkBest << " d=" << bestDistance); + } + } + } + double fullDistance = 0; + int32_t nbTestNotUsed = 0; + int32_t nbReferenceNotUsed = 0; + // now we count the full distance use and the number of local gesture not use + for (auto &it : distance) { + if (it < 100.0) { + fullDistance += it; + } else { + nbTestNotUsed++; + } + } + // we count the number of point in the gesture reference not used: + for (auto &it : usedId) { + if (it == -1) { + nbReferenceNotUsed++; + } + } + // now we add panality: + fullDistance += float(nbTestNotUsed)* m_penalityNotLinkSample; + fullDistance += float(nbReferenceNotUsed)* m_penalityNotLinkRef; + + for (size_t kkk=0; kkkgetPath().size(); + /* + if (nbStrokeSample != nbStrokeRef) { + continue; //==> must have the same number of stroke ... + } + */ float distance = MAX_FLOAT; std::vector> dataPair; distance = calculatePPlusDistance(points, gesture->getEnginePoints(), dataPair); + //distance = calculatePPlusDistanceSimple(points, gesture->getEnginePoints(), dataPair); + if (nbStrokeRef != nbStrokeSample) { + distance += 0.1f*float(std::abs(nbStrokeRef-nbStrokeSample)); + } //storeSVG("out_dollar/lib/recognizePPlus/" + gesture->getName() + "_" + etk::to_string(gesture->getId()) + ".svg", gesture, _strokes, points, dataPair, m_scaleKeepRatio); for (size_t kkk=0; kkk> m_gestures; //!< List of all loaded gesture in the engine public: @@ -42,6 +52,9 @@ namespace dollar { float calculatePPlusDistance(const std::vector& _points, const std::vector& _reference, std::vector>& _dataDebug); + float calculatePPlusDistanceSimple(const std::vector& _points, + const std::vector& _reference, + std::vector>& _dataDebug); }; } diff --git a/tool/bench-corpus/main.cpp b/tool/bench-corpus/main.cpp index 86ed253..6851d33 100644 --- a/tool/bench-corpus/main.cpp +++ b/tool/bench-corpus/main.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include @@ -17,7 +17,12 @@ void usage(const std::string& _progName) { TEST_PRINT("usage:"); TEST_PRINT(" " << _progName << " [option] reference_gesture corpus_path"); TEST_PRINT(" [option]"); - TEST_PRINT(" -h --help Display this help"); + TEST_PRINT(" -h --help Display this help"); + TEST_PRINT(" --keep_ratio Keep aspect ratio for the form recognition"); + TEST_PRINT(" --dist-check=flaot distance between points in the system recognition"); + TEST_PRINT(" --dist-excl=flaot distance to exclude a point in a pathern matching ..."); + TEST_PRINT(" --penal-ref=float Penality for reference when not connected"); + TEST_PRINT(" --penal-sample=float Penality for sample when not connected"); TEST_PRINT(" parameters (must be here)"); TEST_PRINT(" reference_gesture Path of the reference gestures"); TEST_PRINT(" corpus_path Path of the corpus files"); @@ -25,6 +30,12 @@ void usage(const std::string& _progName) { bool testCorpus(const std::string& _srcGesture, const std::string& _srcCorpus); +static bool keepAspectRatio = false; +static float distanceReference = 0.1f; // distance of the gesture reference [0.02, 0.3] +static float distanceExclude = 0.2f; // distance of the exclusion point [0.1, 1.0] +static float penalityRef = 0.1; +static float penalitySample = 0.1; + int main(int _argc, const char *_argv[]) { // init etk log system and file interface: etk::init(_argc, _argv); @@ -37,6 +48,34 @@ int main(int _argc, const char *_argv[]) { usage(_argv[0]); return 0; } + if (arg == "--keep_ratio") { + keepAspectRatio = true; + continue; + } + if (etk::start_with(arg,"--dist-ref=") == true) { + std::string val(&arg[11]); + distanceReference = etk::string_to_float(val); + TEST_PRINT("configure distanceReference=" << distanceReference); + continue; + } + if (etk::start_with(arg,"--dist-excl=") == true) { + std::string val(&arg[12]); + distanceExclude = etk::string_to_float(val); + TEST_PRINT("configure distanceExclude=" << distanceExclude); + continue; + } + if (etk::start_with(arg,"--penal-ref=") == true) { + std::string val(&arg[12]); + penalityRef = etk::string_to_float(val); + TEST_PRINT("configure penalityRef=" << penalityRef); + continue; + } + if (etk::start_with(arg,"--penal-sample=") == true) { + std::string val(&arg[15]); + penalityRef = etk::string_to_float(val); + TEST_PRINT("configure penalitySample=" << penalitySample); + continue; + } if( arg[0] == '-' && arg[1] == '-') { // subLibrary usage ... @@ -134,8 +173,12 @@ void annalyseResult(std::map path = etk::split(it, '/'); std::string filename = path[path.size()-1]; TEST_PRINT("Test '" << label << "' type=" << type << " " << filename); - dollar::Results res = reco.recognize(listPoints, "$P+"); + dollar::Results res = reco.recognize(listPoints); agregateResults[label+" "+type].push_back(std::make_pair(res,it)); diff --git a/tool/generate-form/main.cpp b/tool/generate-form/main.cpp index e5b56eb..fffd59a 100644 --- a/tool/generate-form/main.cpp +++ b/tool/generate-form/main.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include @@ -18,12 +18,13 @@ void usage(const std::string& _progName) { TEST_PRINT(" " << _progName << " [option] corpus_path"); TEST_PRINT(" "); TEST_PRINT(" [option]"); - TEST_PRINT(" -h --help Display this help"); - TEST_PRINT(" --keep_ratio Keep aspect ratio for the form recognition"); - TEST_PRINT(" --dist-check=flaot distance between points in the system recognition"); - TEST_PRINT(" --dist-excl=flaot distance to exclude points in the check algo"); - TEST_PRINT(" --group-size=flaot size of the distance between point to stop grouping in one form"); - TEST_PRINT(" --mode=string mode of reco"); + TEST_PRINT(" -h --help Display this help"); + TEST_PRINT(" --keep_ratio Keep aspect ratio for the form recognition"); + TEST_PRINT(" --dist-check=flaot distance between points in the system recognition"); + TEST_PRINT(" --dist-excl=flaot distance to exclude a point in a pathern matching ..."); + TEST_PRINT(" --group-size=flaot size of the distance between point to stop grouping in one form"); + TEST_PRINT(" --penal-ref=float Penality for reference when not connected"); + TEST_PRINT(" --penal-sample=float Penality for sample when not connected"); TEST_PRINT(" "); TEST_PRINT(" parameters (must be here)"); TEST_PRINT(" corpus_path Path of the corpus files"); @@ -35,16 +36,11 @@ void usage(const std::string& _progName) { bool testCorpus(const std::string& _srcCorpus); static bool keepAspectRatio = false; -static float distanceReference = 0.1; // distance of the gesture reference [0.02, 0.3] -static float distanceCheck = 0.1; // distance of the test points [0.02, 0.3] -static float distanceExclude = 0.2; // distance of the exclusion point [0.1, 1.0] -static float distanceGroupLimiting = 1.0; // square distance of the grouping genereation -static std::string modeReco = "P+"; - -setScaleKeepRatio(); -setPPlusDistance(distanceReference); // to generate reference gesture -setPPlusDistance(distanceCheck); // to generate test gesture - +static float distanceReference = 0.1f; // distance of the gesture reference [0.02, 0.3] +static float distanceExclude = 0.2f; // distance of the exclusion point [0.1, 1.0] +static float distanceGroupLimiting = 1.0f; // square distance of the grouping genereation +static float penalityRef = 0.1; +static float penalitySample = 0.1; int main(int _argc, const char *_argv[]) { // init etk log system and file interface: @@ -68,14 +64,6 @@ int main(int _argc, const char *_argv[]) { TEST_PRINT("configure distanceReference=" << distanceReference); continue; } - // TODO: Must not be different ... - if (etk::start_with(arg,"--dist-check=") == true) { - std::string val(&arg[13]); - distanceCheck = etk::string_to_float(val); - distanceReference = distanceCheck; - TEST_PRINT("configure distanceCheck=" << distanceCheck); - continue; - } if (etk::start_with(arg,"--dist-excl=") == true) { std::string val(&arg[12]); distanceExclude = etk::string_to_float(val); @@ -88,10 +76,16 @@ int main(int _argc, const char *_argv[]) { TEST_PRINT("configure distanceGroupLimiting=" << distanceGroupLimiting); continue; } - if (etk::start_with(arg,"--mode=") == true) { - std::string val(&arg[7]); - modeReco = val; - TEST_PRINT("configure modeReco=" << modeReco); + if (etk::start_with(arg,"--penal-ref=") == true) { + std::string val(&arg[12]); + penalityRef = etk::string_to_float(val); + TEST_PRINT("configure penalityRef=" << penalityRef); + continue; + } + if (etk::start_with(arg,"--penal-sample=") == true) { + std::string val(&arg[15]); + penalityRef = etk::string_to_float(val); + TEST_PRINT("configure penalitySample=" << penalitySample); continue; } if ( arg[0] == '-' @@ -176,6 +170,8 @@ bool testCorpus(const std::string& _srcCorpus) { } } } + // remove generation path ... + etk::FSNodeRemove("out_dollar/generate-form"); //listOfElementInCorpus.clear(); //listOfElementInCorpus.push_back("slash"); @@ -219,14 +215,15 @@ bool testCorpus(const std::string& _srcCorpus) { generateFile("out_dollar/generate-form/pre_generate/" + itTypeOfCorpusFileName + "_FULL.svg", listPath, ""); } for (size_t iii=0; iii gest = ememory::makeShared(); std::vector> listPoints = dollar::loadPoints(fileFiltered[iii]); - gest.set(itTypeOfCorpus, 0, listPoints); - gest.configure(10, 8, false, distanceReference, keepAspectRatio); - dollar::Engine reco; + gest->set(itTypeOfCorpus, 0, listPoints); + dollar::EnginePPlus reco; reco.setScaleKeepRatio(keepAspectRatio); - reco.setPPlusDistance(distanceCheck); + reco.setPPlusDistance(distanceReference); reco.setPPlusExcludeDistance(distanceExclude); + reco.setPenalityNotLinkRef(penalityRef); + reco.setPenalityNotLinkSample(penalitySample); reco.addGesture(gest); std::vector path = etk::split(fileFiltered[iii], '/'); std::string filename = path[path.size()-1]; @@ -237,7 +234,7 @@ bool testCorpus(const std::string& _srcCorpus) { continue; } listPoints = dollar::loadPoints(fileFiltered[jjj]); - dollar::Results res = reco.recognize(listPoints, "$" + modeReco); + dollar::Results res = reco.recognize(listPoints); results[iii][jjj] = res.getConfidence(); results[jjj][iii] = res.getConfidence(); path = etk::split(fileFiltered[jjj], '/'); @@ -312,6 +309,7 @@ bool testCorpus(const std::string& _srcCorpus) { } } // enable/disable grouping auto ... + // TODO : Check if it is possible ... if (false) { float lastValue = 0.0; linkIds.clear();