[DEV] better recognition

This commit is contained in:
Edouard DUPIN 2016-08-26 21:46:41 +02:00
parent 1b1992a301
commit aaceff37cb
8 changed files with 135 additions and 54 deletions

View File

@ -54,7 +54,8 @@ static float pathDistance(const std::vector<vec2>& _path1, const std::vector<vec
} }
dollar::Engine::Engine(): dollar::Engine::Engine():
m_PPlusDistance(0.10f) { m_PPlusDistance(0.10f),
m_scaleKeepRatio(false) {
m_numPointsInGesture = 128; m_numPointsInGesture = 128;
DOLLAR_ASSERT(m_numPointsInGesture>16, "NB element in a path must be > 16 ..."); DOLLAR_ASSERT(m_numPointsInGesture>16, "NB element in a path must be > 16 ...");
setRotationInvariance(false); setRotationInvariance(false);
@ -68,7 +69,7 @@ void dollar::Engine::setNumberPointInGesture(size_t _value) {
m_numPointsInGesture = _value; m_numPointsInGesture = _value;
DOLLAR_ASSERT(m_numPointsInGesture>16, "NB element in a path must be > 16 ..."); DOLLAR_ASSERT(m_numPointsInGesture>16, "NB element in a path must be > 16 ...");
for (auto &it: m_gestures) { for (auto &it: m_gestures) {
it.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance); it.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance, m_scaleKeepRatio);
} }
} }
@ -76,6 +77,34 @@ size_t dollar::Engine::getNumberPointInGesture() {
return m_numPointsInGesture; return m_numPointsInGesture;
} }
void dollar::Engine::setPPlusDistance(float _value) {
if (_value == m_PPlusDistance) {
return;
}
m_PPlusDistance = _value;
for (auto &it: m_gestures) {
it.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance, m_scaleKeepRatio);
}
}
float dollar::Engine::getPPlusDistance() {
return m_PPlusDistance;
}
void dollar::Engine::setScaleKeepRatio(bool _value) {
if (_value == m_scaleKeepRatio) {
return;
}
m_scaleKeepRatio = _value;
for (auto &it: m_gestures) {
it.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance, m_scaleKeepRatio);
}
}
bool dollar::Engine::getScaleKeepRatio() {
return m_scaleKeepRatio;
}
float dollar::Engine::distanceAtBestAngle(const std::vector<vec2>& _points, const std::vector<vec2>& _reference) { float dollar::Engine::distanceAtBestAngle(const std::vector<vec2>& _points, const std::vector<vec2>& _reference) {
float startRange = -m_angleRange; float startRange = -m_angleRange;
float endRange = m_angleRange; float endRange = m_angleRange;
@ -177,17 +206,17 @@ static float calculatePPlusDistance(const std::vector<vec2>& _points,
} }
} }
if (kkkBest != -1) { if (kkkBest != -1) {
if (bestDistance > 0.2*0.2) { // reject the distance ... if too big ...
// reject the distance ... if (bestDistance <= 0.2*0.2) {
} int32_t previous = usedId[kkkBest];
int32_t previous = usedId[kkkBest]; usedId[kkkBest] = iii;
usedId[kkkBest] = iii; distance[iii] = bestDistance;
distance[iii] = bestDistance; //DOLLAR_INFO("set new link: " << iii << " with " << kkkBest << " d=" << bestDistance);
//DOLLAR_INFO("set new link: " << iii << " with " << kkkBest << " d=" << bestDistance); if (previous != -1) {
if (previous != -1) { //DOLLAR_INFO(" Reject : " << previous);
//DOLLAR_INFO(" Reject : " << previous); distance[previous] = MAX_FLOAT;
distance[previous] = MAX_FLOAT; iii = previous-1;
iii = previous-1; }
} }
} }
} }
@ -276,7 +305,7 @@ bool dollar::Engine::loadGesture(const std::string& _filename) {
} }
void dollar::Engine::addGesture(Gesture _gesture) { void dollar::Engine::addGesture(Gesture _gesture) {
_gesture.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance); _gesture.configure(m_numPointsInGesture/RATIO_START_VECTOR, m_numPointsInGesture, m_paramterIgnoreRotation, m_PPlusDistance, m_scaleKeepRatio);
m_gestures.push_back(std::move(_gesture)); m_gestures.push_back(std::move(_gesture));
} }
@ -309,7 +338,7 @@ dollar::Results dollar::Engine::recognize(const std::vector<std::vector<vec2>>&
dollar::Results dollar::Engine::recognizeN(const std::vector<std::vector<vec2>>& _strokes, const std::string& _method) { dollar::Results dollar::Engine::recognizeN(const std::vector<std::vector<vec2>>& _strokes, const std::string& _method) {
std::vector<vec2> points = dollar::combineStrokes(_strokes); std::vector<vec2> points = dollar::combineStrokes(_strokes);
points = dollar::normalizePath(points, m_numPointsInGesture, m_paramterIgnoreRotation); points = dollar::normalizePath(points, m_numPointsInGesture, m_paramterIgnoreRotation, m_scaleKeepRatio);
vec2 startv = dollar::getStartVector(points, m_numPointsInGesture/RATIO_START_VECTOR); vec2 startv = dollar::getStartVector(points, m_numPointsInGesture/RATIO_START_VECTOR);
std::vector<vec2> vector = normalyse(points); std::vector<vec2> vector = normalyse(points);
// Keep maximum 5 results ... // Keep maximum 5 results ...
@ -393,7 +422,7 @@ dollar::Results dollar::Engine::recognizeN(const std::vector<std::vector<vec2>>&
dollar::Results dollar::Engine::recognizeP(const std::vector<std::vector<vec2>>& _strokes) { dollar::Results dollar::Engine::recognizeP(const std::vector<std::vector<vec2>>& _strokes) {
std::vector<vec2> points = dollar::combineStrokes(_strokes); std::vector<vec2> points = dollar::combineStrokes(_strokes);
points = dollar::normalizePath(points, m_numPointsInGesture, m_paramterIgnoreRotation); points = dollar::normalizePath(points, m_numPointsInGesture, m_paramterIgnoreRotation, m_scaleKeepRatio);
// Keep maximum 5 results ... // Keep maximum 5 results ...
float bestDistance[MAX_RESULT_NUMBER]; float bestDistance[MAX_RESULT_NUMBER];
int32_t indexOfBestMatch[MAX_RESULT_NUMBER]; int32_t indexOfBestMatch[MAX_RESULT_NUMBER];
@ -456,10 +485,11 @@ dollar::Results dollar::Engine::recognizeP(const std::vector<std::vector<vec2>>&
static void storeSVG(const std::string& _fileName, static void storeSVG(const std::string& _fileName,
const dollar::Gesture& gesture, const dollar::Gesture& gesture,
const std::vector<std::vector<vec2>>& _strokes, const std::vector<std::vector<vec2>>& _strokes,
const std::vector<vec2>& _points, const std::vector<vec2>& _points,
std::vector<std::pair<int32_t, int32_t>> _links) { std::vector<std::pair<int32_t, int32_t>> _links,
bool _keepAspectRatio) {
std::string data("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); std::string data("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
data += "<svg height=\"100\" width=\"100\">\n"; data += "<svg height=\"100\" width=\"100\">\n";
for (auto &itLines : gesture.getPath()) { for (auto &itLines : gesture.getPath()) {
@ -476,7 +506,7 @@ static void storeSVG(const std::string& _fileName,
data += "\"\n"; data += "\"\n";
data += " />\n"; data += " />\n";
} }
for (auto &itLines : dollar::scaleToOne(_strokes)) { for (auto &itLines : dollar::scaleToOne(_strokes, _keepAspectRatio)) {
data += " <polyline fill=\"none\" stroke=\"purple\" stroke-opacity=\"0.8\" stroke-width=\"2\"\n"; data += " <polyline fill=\"none\" stroke=\"purple\" stroke-opacity=\"0.8\" stroke-width=\"2\"\n";
data += " points=\""; data += " points=\"";
bool first = true; bool first = true;
@ -513,7 +543,7 @@ static void storeSVG(const std::string& _fileName,
dollar::Results dollar::Engine::recognizePPlus(const std::vector<std::vector<vec2>>& _strokes) { dollar::Results dollar::Engine::recognizePPlus(const std::vector<std::vector<vec2>>& _strokes) {
std::vector<vec2> points = dollar::normalizePathToPoints(_strokes, m_PPlusDistance); std::vector<vec2> points = dollar::normalizePathToPoints(_strokes, m_PPlusDistance, m_scaleKeepRatio);
// Keep maximum 5 results ... // Keep maximum 5 results ...
float bestDistance[MAX_RESULT_NUMBER]; float bestDistance[MAX_RESULT_NUMBER];
int32_t indexOfBestMatch[MAX_RESULT_NUMBER]; int32_t indexOfBestMatch[MAX_RESULT_NUMBER];
@ -536,7 +566,7 @@ dollar::Results dollar::Engine::recognizePPlus(const std::vector<std::vector<vec
float distance = MAX_FLOAT; float distance = MAX_FLOAT;
std::vector<std::pair<int32_t, int32_t>> dataPair; std::vector<std::pair<int32_t, int32_t>> dataPair;
distance = calculatePPlusDistance(points, gesture.getEnginePoints(), dataPair); distance = calculatePPlusDistance(points, gesture.getEnginePoints(), dataPair);
storeSVG("out_dollar/lib/recognizePPlus/" + gesture.getName() + "_" + etk::to_string(gesture.getId()) + ".svg", gesture, _strokes, points, dataPair); //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<MAX_RESULT_NUMBER; ++kkk) { for (size_t kkk=0; kkk<MAX_RESULT_NUMBER; ++kkk) {
if (distance < bestDistance[kkk]) { if (distance < bestDistance[kkk]) {
if (kkk == 0) { if (kkk == 0) {

View File

@ -17,6 +17,15 @@ namespace dollar {
class Engine { class Engine {
protected: protected:
float m_PPlusDistance; float m_PPlusDistance;
public:
void setPPlusDistance(float _value);
float getPPlusDistance();
protected:
bool m_scaleKeepRatio; // when rescale the path, keep the aspect ration for processing
public:
void setScaleKeepRatio(bool _value);
bool getScaleKeepRatio();
protected:
float m_angleRange; float m_angleRange;
bool m_paramterIgnoreRotation; //!< Ignore the start rotation of the gesture bool m_paramterIgnoreRotation; //!< Ignore the start rotation of the gesture
public: public:

View File

@ -90,7 +90,6 @@ bool dollar::Gesture::loadJSON(const std::string& _fileName) {
m_name = doc["value"].toString().get(); m_name = doc["value"].toString().get();
m_subId = doc["sub-id"].toNumber().getU64(), m_subId = doc["sub-id"].toNumber().getU64(),
m_path = loadPointsJson(doc); m_path = loadPointsJson(doc);
m_path = dollar::scaleToOne(m_path);
DOLLAR_DEBUG("Load gesture : " << m_name << " id=" << m_subId << " nb_elem=" << m_path.size()); DOLLAR_DEBUG("Load gesture : " << m_name << " id=" << m_subId << " nb_elem=" << m_path.size());
return true; return true;
} }
@ -110,7 +109,6 @@ bool dollar::Gesture::loadSVG(const std::string& _fileName) {
it2.setY(it2.y()*-1); it2.setY(it2.y()*-1);
} }
} }
m_path = dollar::scaleToOne(m_path);
DOLLAR_DEBUG("Load gesture : " << m_name << " id=" << m_subId << " nb_elem=" << m_path.size()); DOLLAR_DEBUG("Load gesture : " << m_name << " id=" << m_subId << " nb_elem=" << m_path.size());
return true; return true;
} }
@ -151,7 +149,7 @@ void dollar::Gesture::storeJSON(const std::string& _fileName) {
} }
void dollar::Gesture::storeSVG(const std::string& _fileName, bool _storeDot) { void dollar::Gesture::storeSVG(const std::string& _fileName, bool _storeDot) {
std::vector<std::vector<vec2>> strokes = dollar::scaleToOne(m_path); std::vector<std::vector<vec2>> strokes = dollar::scaleToOne(m_path, true);
std::string data("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); std::string data("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
data += "<svg height=\"100\" width=\"100\">\n"; data += "<svg height=\"100\" width=\"100\">\n";
for (auto &itLines : strokes) { for (auto &itLines : strokes) {
@ -185,23 +183,25 @@ void dollar::Gesture::set(const std::string& _name, uint32_t _subId, std::vector
m_engineVector.clear(); m_engineVector.clear();
m_engineStartV.clear(); m_engineStartV.clear();
m_enginePoints.clear(); m_enginePoints.clear();
m_path2.clear();
} }
void dollar::Gesture::configure(float _startAngleIndex, size_t _nbSample, bool _ignoreRotation, float _distance) { void dollar::Gesture::configure(float _startAngleIndex, size_t _nbSample, bool _ignoreRotation, float _distance, bool _keepAspectRatio) {
m_enginePath.clear(); m_enginePath.clear();
m_engineVector.clear(); m_engineVector.clear();
m_engineStartV.clear(); m_engineStartV.clear();
m_enginePoints.clear(); m_enginePoints.clear();
m_path2 = dollar::scaleToOne(m_path, _keepAspectRatio);
// Generates dots: // Generates dots:
m_enginePoints = dollar::normalizePathToPoints(m_path, _distance); m_enginePoints = dollar::normalizePathToPoints(m_path, _distance, _keepAspectRatio);
DOLLAR_VERBOSE("create " << m_enginePoints.size() << " points"); DOLLAR_VERBOSE("create " << m_enginePoints.size() << " points");
// for debug only // for debug only
storeSVG("out_dollar/lib/gestures/" + m_name + "_" + etk::to_string(m_subId) + ".svg", true); //storeSVG("out_dollar/lib/gestures/" + m_name + "_" + etk::to_string(m_subId) + ".svg", true);
// Simplyfy paths // Simplyfy paths
std::vector<std::vector<vec2>> uniPath = dollar::makeReferenceStrokes(m_path); std::vector<std::vector<vec2>> uniPath = dollar::makeReferenceStrokes(m_path);
// normalize paths // normalize paths
for (auto &it : uniPath) { for (auto &it : uniPath) {
std::vector<vec2> val = dollar::normalizePath(it, _nbSample, _ignoreRotation); std::vector<vec2> val = dollar::normalizePath(it, _nbSample, _ignoreRotation, _keepAspectRatio);
m_enginePath.push_back(val); m_enginePath.push_back(val);
// calculate start vector: // calculate start vector:
vec2 startv = dollar::getStartVector(val, _startAngleIndex); vec2 startv = dollar::getStartVector(val, _startAngleIndex);

View File

@ -14,6 +14,7 @@ namespace dollar {
std::string m_name; std::string m_name;
uint32_t m_subId; uint32_t m_subId;
std::vector<std::vector<vec2>> m_path; std::vector<std::vector<vec2>> m_path;
std::vector<std::vector<vec2>> m_path2;
public: public:
Gesture(); Gesture();
bool load(const std::string& _filename); bool load(const std::string& _filename);
@ -32,10 +33,10 @@ namespace dollar {
return m_subId; return m_subId;
} }
const std::vector<std::vector<vec2>>& getPath() const { const std::vector<std::vector<vec2>>& getPath() const {
return m_path; return m_path2;
} }
std::vector<std::vector<vec2>>& getPath() { std::vector<std::vector<vec2>>& getPath() {
return m_path; return m_path2;
} }
protected: protected:
std::vector<std::vector<vec2>> m_enginePath; // Singulized path with every conbinaison std::vector<std::vector<vec2>> m_enginePath; // Singulized path with every conbinaison
@ -44,7 +45,7 @@ namespace dollar {
std::vector<vec2> m_enginePoints; std::vector<vec2> m_enginePoints;
public: public:
// Configure the reference gesture for recognition... // Configure the reference gesture for recognition...
void configure(float _startAngleIndex, size_t _nbSample, bool _ignoreRotation, float _distance); void configure(float _startAngleIndex, size_t _nbSample, bool _ignoreRotation, float _distance, bool _keepAspectRatio);
size_t getEngineSize() const { size_t getEngineSize() const {
return m_enginePath.size(); return m_enginePath.size();
} }

View File

@ -52,18 +52,23 @@ std::vector<vec2> dollar::scaleToOne(const std::vector<vec2>& _points, bool _kee
dollar::Rectangle box(_points); dollar::Rectangle box(_points);
std::vector<vec2> out; std::vector<vec2> out;
vec2 scale(1.0f/box.getSize().x(), 1.0f/box.getSize().y()); vec2 scale(1.0f/box.getSize().x(), 1.0f/box.getSize().y());
vec2 offset(0,0);
if (_keepAspectRation == true) { if (_keepAspectRation == true) {
float val = 1; float val = 1;
if (box.getSize().x() > 0) { offset = box.getSize() * val;
if (box.getSize().x() > box.getSize().y()) {
val = 1.0f/box.getSize().x(); val = 1.0f/box.getSize().x();
offset = vec2(0.0f, (1.0f-offset.y())*0.5f);
} else { } else {
val = 1.0f/box.getSize().y(); val = 1.0f/box.getSize().y();
offset = vec2((1.0f-offset.x())*0.5f, 0.0f);
} }
scale = vec2(val,val); scale = vec2(val,val);
} }
for (auto &it : _points) { for (auto &it : _points) {
vec2 tmp = it - box.getPos(); vec2 tmp = it - box.getPos();
tmp *= scale; tmp *= scale;
//tmp += offset;
out.push_back(tmp); out.push_back(tmp);
} }
return out; return out;
@ -73,12 +78,16 @@ std::vector<std::vector<vec2>> dollar::scaleToOne(const std::vector<std::vector<
dollar::Rectangle box(_points); dollar::Rectangle box(_points);
std::vector<std::vector<vec2>> out; std::vector<std::vector<vec2>> out;
vec2 scale(1.0f/box.getSize().x(), 1.0f/box.getSize().y()); vec2 scale(1.0f/box.getSize().x(), 1.0f/box.getSize().y());
vec2 offset(0,0);
if (_keepAspectRation == true) { if (_keepAspectRation == true) {
float val = 1; float val = 1;
if (box.getSize().x() > 0) { offset = box.getSize() * val;
if (box.getSize().x() > box.getSize().y()) {
val = 1.0f/box.getSize().x(); val = 1.0f/box.getSize().x();
offset = vec2(0.0f, (1.0f-offset.y())*0.5f);
} else { } else {
val = 1.0f/box.getSize().y(); val = 1.0f/box.getSize().y();
offset = vec2((1.0f-offset.x())*0.5f, 0.0f);
} }
scale = vec2(val,val); scale = vec2(val,val);
} }
@ -87,6 +96,7 @@ std::vector<std::vector<vec2>> dollar::scaleToOne(const std::vector<std::vector<
for (auto &itPoint : it) { for (auto &itPoint : it) {
vec2 tmp = itPoint - box.getPos(); vec2 tmp = itPoint - box.getPos();
tmp *= scale; tmp *= scale;
//tmp += offset;
stroke.push_back(tmp); stroke.push_back(tmp);
} }
out.push_back(stroke); out.push_back(stroke);
@ -204,19 +214,19 @@ std::vector<vec2> dollar::normalyse(const std::vector<vec2>& _points) {
} }
std::vector<vec2> dollar::normalizePath(std::vector<vec2> _points, size_t _nbSample, bool _ignoreRotation) { std::vector<vec2> dollar::normalizePath(std::vector<vec2> _points, size_t _nbSample, bool _ignoreRotation, bool _keepAspectRatio) {
_points = dollar::resample(_points, _nbSample); _points = dollar::resample(_points, _nbSample);
if (_ignoreRotation == true) { if (_ignoreRotation == true) {
_points = rotateToZero(_points); _points = rotateToZero(_points);
} }
_points = scaleToOne(_points); _points = scaleToOne(_points, _keepAspectRatio);
return translateBariCenterToZero(_points); return translateBariCenterToZero(_points);
} }
std::vector<vec2> dollar::normalizePathToPoints(std::vector<std::vector<vec2>> _points, float _distance) { std::vector<vec2> dollar::normalizePathToPoints(std::vector<std::vector<vec2>> _points, float _distance, bool _keepAspectRatio) {
// Scale point to (0.0,0.0) position and (1.0,1.0) size // Scale point to (0.0,0.0) position and (1.0,1.0) size
_points = dollar::scaleToOne(_points); _points = dollar::scaleToOne(_points, _keepAspectRatio);
std::vector<vec2> out; std::vector<vec2> out;
for (auto &it : _points) { for (auto &it : _points) {
if (it.size() == 0) { if (it.size() == 0) {

View File

@ -47,7 +47,7 @@ namespace dollar {
* @param[in] _keepAspectRation Keep the aspect ratio of the scaling * @param[in] _keepAspectRation Keep the aspect ratio of the scaling
* @return modify points * @return modify points
*/ */
std::vector<vec2> scaleToOne(const std::vector<vec2>& _points, bool _keepAspectRation=false); std::vector<vec2> scaleToOne(const std::vector<vec2>& _points, bool _keepAspectRation=true);
/** /**
* @brief Scale the list of point in a 1.0*1.0 box started at 0.0*0.0 * @brief Scale the list of point in a 1.0*1.0 box started at 0.0*0.0
* @param[in] _points input path * @param[in] _points input path
@ -98,18 +98,20 @@ namespace dollar {
* @param[in] _points List of points in the path * @param[in] _points List of points in the path
* @param[in] _nbSample Number of element to resample * @param[in] _nbSample Number of element to resample
* @param[in] _ignoreRotation Ignore start rotation of the algorithm * @param[in] _ignoreRotation Ignore start rotation of the algorithm
* @param[in] _keepAspectRatio Keep Aspect ratio when scaling to the correct size (1.0,1.0) (it will be centered)
* @return new list of points * @return new list of points
*/ */
std::vector<vec2> normalizePath(std::vector<vec2> _points, size_t _nbSample, bool _ignoreRotation); std::vector<vec2> normalizePath(std::vector<vec2> _points, size_t _nbSample, bool _ignoreRotation, bool _keepAspectRatio);
/** /**
* @brief Transform the path to be comparable, resample the path with a specific number of sample, and limit size at 1.0 square center around 0 * @brief Transform the path to be comparable, resample the path with a specific number of sample, and limit size at 1.0 square center around 0
* @note The difference with @ref normalizePath is thet we do not combinethe path together, that permit to not have unneded point between strokes... * @note The difference with @ref normalizePath is thet we do not combinethe path together, that permit to not have unneded point between strokes...
* @param[in] _points List of points in the path * @param[in] _points List of points in the path
* @param[in] _distance Distance between points * @param[in] _distance Distance between points
* @param[in] _keepAspectRatio Keep Aspect ratio when scaling to the correct size (1.0,1.0) (it will be centered)
* @return new list of points * @return new list of points
*/ */
std::vector<vec2> normalizePathToPoints(std::vector<std::vector<vec2>> _points, float _distance); std::vector<vec2> normalizePathToPoints(std::vector<std::vector<vec2>> _points, float _distance, bool _keepAspectRatio);
} }

View File

@ -135,6 +135,7 @@ void annalyseResult(std::map<std::string, std::vector<std::pair<dollar::Results,
bool testCorpus(const std::string& _srcGesture, const std::string& _srcCorpus) { bool testCorpus(const std::string& _srcGesture, const std::string& _srcCorpus) {
// declare a Gesture (internal API) // declare a Gesture (internal API)
dollar::Engine reco; dollar::Engine reco;
reco.setScaleKeepRatio(false);
TEST_PRINT("---------------------------------------------------------------------------"); TEST_PRINT("---------------------------------------------------------------------------");
TEST_PRINT("-- Load Gestures: " << _srcGesture); TEST_PRINT("-- Load Gestures: " << _srcGesture);
TEST_PRINT("---------------------------------------------------------------------------"); TEST_PRINT("---------------------------------------------------------------------------");
@ -153,6 +154,7 @@ bool testCorpus(const std::string& _srcGesture, const std::string& _srcCorpus) {
// "label_type" ==> list of (result, file test name) // "label_type" ==> list of (result, file test name)
std::map<std::string, std::vector<std::pair<dollar::Results, std::string>>> agregateResults; std::map<std::string, std::vector<std::pair<dollar::Results, std::string>>> agregateResults;
int32_t nbRecognise = 0; int32_t nbRecognise = 0;
int32_t nbRecognise2 = 0;
int32_t nbtested = 0; int32_t nbtested = 0;
for (auto &it : files) { for (auto &it : files) {
std::string label; std::string label;
@ -180,15 +182,20 @@ bool testCorpus(const std::string& _srcGesture, const std::string& _srcCorpus) {
} }
#else #else
if (res.getName() == label) { if (res.getName() == label) {
nbRecognise ++; nbRecognise++;
nbRecognise2++;
TEST_INFO(" " << res.getName() << " score=" << res.getConfidence()); TEST_INFO(" " << res.getName() << " score=" << res.getConfidence());
} else { } else if (etk::toupper(res.getName()) == etk::toupper(label)) {
nbRecognise2++;
TEST_WARNING(" " << res.getName() << " score=" << res.getConfidence());
}else {
TEST_ERROR(" " << res.getName() << " score=" << res.getConfidence()); TEST_ERROR(" " << res.getName() << " score=" << res.getConfidence());
} }
#endif #endif
} }
annalyseResult(agregateResults); annalyseResult(agregateResults);
TEST_PRINT("Recognise: " << nbRecognise << " / " << nbtested << " ==> " << (float(nbRecognise) / float(nbtested) * 100.0f) << " %"); TEST_PRINT("Recognise: " << nbRecognise << " / " << nbtested << " ==> " << (float(nbRecognise) / float(nbtested) * 100.0f) << " %");
TEST_PRINT("Recognise (a==A): " << nbRecognise2 << " / " << nbtested << " ==> " << (float(nbRecognise2) / float(nbtested) * 100.0f) << " %");
// All is done corectly // All is done corectly
return 0; return 0;
} }

View File

@ -119,6 +119,11 @@ bool testCorpus(const std::string& _srcCorpus) {
} }
//listOfElementInCorpus.clear(); //listOfElementInCorpus.clear();
//listOfElementInCorpus.push_back("z"); //listOfElementInCorpus.push_back("z");
// Value to stop grouping in the same element ...
float groupSize = 1.0;
groupSize = 1.0;
bool keepAspectRatio = false;
TEST_PRINT(" will done for: " << listOfElementInCorpus); TEST_PRINT(" will done for: " << listOfElementInCorpus);
for (auto &itTypeOfCorpus : listOfElementInCorpus) { for (auto &itTypeOfCorpus : listOfElementInCorpus) {
TEST_PRINT("---------------------------------------------------------------------------"); TEST_PRINT("---------------------------------------------------------------------------");
@ -141,19 +146,28 @@ bool testCorpus(const std::string& _srcCorpus) {
it.resize(fileFiltered.size(), OUT_OF_RANGE); it.resize(fileFiltered.size(), OUT_OF_RANGE);
} }
// Generate Full Files: // Generate Full Files:
std::string itTypeOfCorpusFileName = itTypeOfCorpus;
if (itTypeOfCorpusFileName == "/") {
itTypeOfCorpusFileName = "slash";
} else if (itTypeOfCorpusFileName == "\\") {
itTypeOfCorpusFileName = "back-slash";
} else if (itTypeOfCorpusFileName == "?") {
itTypeOfCorpusFileName = "question";
}
{ {
std::vector<std::string> listPath; std::vector<std::string> listPath;
for (size_t iii=0; iii<fileFiltered.size(); ++iii) { for (size_t iii=0; iii<fileFiltered.size(); ++iii) {
listPath.push_back(fileFiltered[iii]); listPath.push_back(fileFiltered[iii]);
} }
generateFile("out_dollar/generate-form/pre_generate/" + itTypeOfCorpus + "_FULL.svg", listPath, ""); generateFile("out_dollar/generate-form/pre_generate/" + itTypeOfCorpusFileName + "_FULL.svg", listPath, "");
} }
for (size_t iii=0; iii<fileFiltered.size(); ++iii) { for (size_t iii=0; iii<fileFiltered.size(); ++iii) {
dollar::Gesture gest; dollar::Gesture gest;
std::vector<std::vector<vec2>> listPoints = dollar::loadPoints(fileFiltered[iii]); std::vector<std::vector<vec2>> listPoints = dollar::loadPoints(fileFiltered[iii]);
gest.set(itTypeOfCorpus, 0, listPoints); gest.set(itTypeOfCorpus, 0, listPoints);
gest.configure(10, 8, false, 0.1); gest.configure(10, 8, false, 0.1, keepAspectRatio);
dollar::Engine reco; dollar::Engine reco;
reco.setScaleKeepRatio(keepAspectRatio);
reco.addGesture(gest); reco.addGesture(gest);
std::vector<std::string> path = etk::split(fileFiltered[iii], '/'); std::vector<std::string> path = etk::split(fileFiltered[iii], '/');
std::string filename = path[path.size()-1]; std::string filename = path[path.size()-1];
@ -177,9 +191,7 @@ bool testCorpus(const std::string& _srcCorpus) {
TEST_PRINT("---------------------------------------------------------------------------"); TEST_PRINT("---------------------------------------------------------------------------");
int32_t residualValues = fileFiltered.size(); int32_t residualValues = fileFiltered.size();
int32_t subId = 1; int32_t subId = 1;
// Value to stop grouping in the same element ...
float groupSize = 1.0;
groupSize = 1.0;
while (residualValues > 0) { while (residualValues > 0) {
std::vector<int32_t> countMinimum; std::vector<int32_t> countMinimum;
countMinimum.resize(fileFiltered.size(), 0); countMinimum.resize(fileFiltered.size(), 0);
@ -201,6 +213,10 @@ bool testCorpus(const std::string& _srcCorpus) {
} }
if (bestId == -1) { if (bestId == -1) {
TEST_ERROR("No more elements ... residualValues=" << residualValues); TEST_ERROR("No more elements ... residualValues=" << residualValues);
// TODO : Add the rest of the elements ...
//==> Exit loop //==> Exit loop
residualValues = 0; residualValues = 0;
continue; continue;
@ -279,22 +295,28 @@ bool testCorpus(const std::string& _srcCorpus) {
results[jjj][linkIds[iii]] = OUT_OF_RANGE; results[jjj][linkIds[iii]] = OUT_OF_RANGE;
} }
} }
if (linkIds.size() <= 3) {
TEST_ERROR("Group is too small ... residualValues=" << residualValues);
// TODO : Add the rest of the elements ...
//==> Exit loop
residualValues = 0;
continue;
}
residualValues -= (linkIds.size() +1); residualValues -= (linkIds.size() +1);
TEST_DEBUG("Generate output files (SVG with all added path in one file)"); TEST_DEBUG("Generate output files (SVG with all added path in one file)");
// Generate Files: // Generate Files:
std::vector<std::string> listPath; std::vector<std::string> listPath;
for (size_t iii=0; iii<linkIds.size(); ++iii) { for (size_t iii=0; iii<linkIds.size(); ++iii) {
listPath.push_back(fileFiltered[linkIds[iii]]); listPath.push_back(fileFiltered[linkIds[iii]]);
} }
generateFile("out_dollar/generate-form/pre_generate/" + itTypeOfCorpus + "_" + etk::to_string(subId) + ".svg", listPath, fileFiltered[bestId]); generateFile("out_dollar/generate-form/pre_generate/" + itTypeOfCorpusFileName + "_" + etk::to_string(subId) + ".svg", listPath, fileFiltered[bestId]);
TEST_DEBUG("Generate output file (corpus ...)"); TEST_DEBUG("Generate output file (corpus ...)");
// declare a Gesture (internal API) // declare a Gesture (internal API)
dollar::Gesture ref; dollar::Gesture ref;
ref.set(itTypeOfCorpus, subId, dollar::loadPoints(fileFiltered[bestId])); ref.set(itTypeOfCorpus, subId, dollar::loadPoints(fileFiltered[bestId]));
// Store gesture with his extention type: // Store gesture with his extention type:
ref.store("out_dollar/generate-form/corpus/" + itTypeOfCorpus + "_" + etk::to_string(subId) + ".json"); ref.store("out_dollar/generate-form/corpus/" + itTypeOfCorpusFileName + "_" + etk::to_string(subId) + ".json");
ref.store("out_dollar/generate-form/corpus_svg/" + itTypeOfCorpus + "_" + etk::to_string(subId) + ".svg"); ref.store("out_dollar/generate-form/corpus_svg/" + itTypeOfCorpusFileName + "_" + etk::to_string(subId) + ".svg");
// Increment subId... // Increment subId...