// Increase age of tracked glyph and remove old ones private void IncreaseHistoryAge( ) { List <int> keys = new List <int>(trackedGlyphs.Keys); for (int i = 0; i < keys.Count; i++) { int id = keys[i]; TrackedGlyph trackedGlyph = trackedGlyphs[id]; trackedGlyph.Age++; if (((trackedGlyph.Age > MaxGlyphAge) && (trackedGlyph.AverageRecentMotion >= StalledAverageMotionLimit)) || (trackedGlyph.Age > MaxStalledGlyphAge)) { trackedGlyphs.Remove(id); if (prevRotation.ContainsKey(id)) { prevRotation.Remove(id); } } } }
// Get ID of the specified glyph // Note (todo?): glyph tracking needs to be improved since current implementation // is not reliable enough for the case when several glyphs of the same type are // found and those do not move smoothely. private int GetGlyphID(ExtractedGlyphData glyph) { int glyphID = -1; // get CoG of the provided glyph Point glyphCog = PointsCloud.GetCenterOfGravity(glyph.Quadrilateral); // distance to the closest simlar glyph kept in history float minDistance = float.MaxValue; // name of the passed specifed glyph string glyphName = (glyph.RecognizedGlyph != null) ? glyph.RecognizedGlyph.Name : string.Empty; // check all currently tracked glyphs foreach (TrackedGlyph trackedGlyph in trackedGlyphs.Values) { if (trackedGlyph.Age == 0) { // skip glyph whichs were already taken or just added continue; } if ( // recognized case - compare names ((trackedGlyph.Glyph.RecognizedGlyph != null) && (trackedGlyph.Glyph.RecognizedGlyph.Name == glyphName)) || // unrecognized case - compare raw data (Glyph.CheckForMatching(glyph.RawData, trackedGlyph.Glyph.RawData) != -1)) { float distance = glyphCog.DistanceTo(trackedGlyph.Position); if (distance < minDistance) { // get ID of the closest glyph with the same name minDistance = distance; glyphID = trackedGlyph.ID; } } } // if the glyph is further away than the maximum specified limit, // then it is no way can be treated as smooth motion, so reset ID // (TODO: should probably depend on glyph size ...) if ((glyphID != -1) && (minDistance > MaxAllowedDistance)) { glyphID = -1; } // if glyph was not found within tracked glyphs, then add new // glyph to tracker if (glyphID == -1) { glyphID = counter++; trackedGlyphs.Add(glyphID, new TrackedGlyph(glyphID, (ExtractedGlyphData)glyph.Clone( ), glyphCog)); } else { TrackedGlyph trackedGlyph = trackedGlyphs[glyphID]; if ((glyph.RecognizedGlyph != null) && (!IsCoordinatesDifferenceSignificant(glyph.RecognizedQuadrilateral, trackedGlyphs[glyphID].Glyph.RecognizedQuadrilateral))) { // correct coordinates of recognized glyphs to eliminate small noisy shaking glyph.RecognizedQuadrilateral = trackedGlyph.Glyph.RecognizedQuadrilateral; glyphCog = trackedGlyph.Position; } else { // update glyph with the latest CoG and recognized info trackedGlyph.Position = glyphCog; trackedGlyph.Glyph = (ExtractedGlyphData)glyph.Clone( ); } // reset age of the tracked glyph trackedGlyph.Age = 0; // add glyph's position to history trackedGlyph.AddMotionHistory(glyphCog); } return(glyphID); }