private IEnumerable <Marker> GetMarkers(ref Image <Rgb, byte> image, Rectangle roi, int width, int height, ref Image <Rgb, byte> debugImage, out List <Point[]> quadrilaterals) { if (_glyphRecognizer == null) { quadrilaterals = new List <Point[]>(); return(null); } var imageWidth = image.Width; var imageHeight = image.Height; var imageRoi = image.ROI; var markers = new List <Marker>(); var minFramesProperty = MinFramesProperty; // Draw new Roi if (IsRenderContent) { debugImage.Draw(roi, Rgbs.Red, 2); } _recognizedGlyphs.Clear(); _recognizedQuads.Clear(); var glyphs = _glyphRecognizer.FindGlyphs(image.Bitmap); foreach (var glyph in glyphs) { // highlight quadrilateral (of all found glyphs) var tmpQuad = glyph.Quadrilateral; if (tmpQuad == null || tmpQuad.Count != 4) { continue; } var quad = new[] { new Point(tmpQuad[0].X, tmpQuad[0].Y), new Point(tmpQuad[1].X, tmpQuad[1].Y), new Point(tmpQuad[2].X, tmpQuad[2].Y), new Point(tmpQuad[3].X, tmpQuad[3].Y) }; if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; debugImage.DrawPolyline(quad, true, Rgbs.Yellow, 1); debugImage.ROI = debugImageRoi; } // if glyphs are recognized then store and draw name var recQuad = glyph.RecognizedQuadrilateral; var recGlyph = glyph.RecognizedGlyph; if (recQuad != null && recGlyph != null) { _recognizedGlyphs.Add(recGlyph.Name, recGlyph); _recognizedQuads.Add(recGlyph.Name, quad); if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; var labelPos = new Point(recQuad[2].X, recQuad[2].Y); debugImage.Draw(recGlyph.Name, ref EmguFontBig, labelPos, Rgbs.Green); debugImage.ROI = debugImageRoi; } } } // update all entries in glyph table using recognized glyphs quadrilaterals = new List <Point[]>(); var length = _glyphTable.Length; for (int i = 0; i < length; i++) { var name = (i + 1).ToString(CultureInfo.InvariantCulture); Glyph glyph = null; Point[] quad = null; if (_recognizedGlyphs.ContainsKey(name)) { glyph = _recognizedGlyphs[name]; } if (_recognizedQuads.ContainsKey(name)) { quad = _recognizedQuads[name]; } // if glyph for this entry was recognized, update entry if (glyph != null && quad != null) { quadrilaterals.Add(quad); // if there is no entry yet, create it if (_glyphTable[i] == null) { _glyphTable[i] = new GlyphMetadata(); } var gmd = _glyphTable[i]; gmd.aliveFrames++; Point upVector1 = quad[0].Sub(quad[3]); Point upVector2 = quad[1].Sub(quad[2]); upVector1 = (upVector1.Add(upVector2)).Div(2); double orientation = Math.Atan2(upVector1.Y, upVector2.X); // always keep only the last X frames in list if (gmd.prevX.Count == minFramesProperty) { gmd.prevX.RemoveAt(0); gmd.prevY.RemoveAt(0); gmd.prevOrientations.RemoveAt(0); } gmd.prevX.Add(quad[0].X); gmd.prevY.Add(quad[0].Y); gmd.prevOrientations.Add(orientation); // check if marker stops moving and rotating if (Math.Abs(gmd.prevX.Max() - gmd.prevX.Min()) < 5 && Math.Abs(gmd.prevY.Max() - gmd.prevY.Min()) < 5 && gmd.aliveFrames >= minFramesProperty) { var x = orientation + Math.PI / 2; var degOrientation = (x > 0.0 ? x : (2.0 * Math.PI + x)) * 360 / (2.0 * Math.PI); // find bounding rectangle float minX = image.Width; float minY = image.Height; float maxX = 0; float maxY = 0; foreach (Point p in quad) { minX = Math.Min(minX, p.X); minY = Math.Min(minY, p.Y); maxX = Math.Max(maxX, p.X); maxY = Math.Max(maxY, p.Y); } var centerX = roi.X + minX + (maxX - minX) / 2.0f; var centerY = roi.Y + minY + (maxY - minY) / 2.0f; markers.Add(new Marker(this, "Display") { Id = name, Center = new System.Windows.Point(centerX / width, centerY / height), RelativeCenter = new System.Windows.Point(centerX / imageWidth, centerY / imageHeight), Angle = degOrientation }); // Render center and orientation of marker if (IsRenderContent) { var markerCenter = new PointF(centerX, centerY); var p2 = new Point( (int)(markerCenter.X + Math.Cos(orientation) * 100.0), (int)(markerCenter.Y + Math.Sin(orientation) * 100.0) ); var p3 = new Point( (int)(markerCenter.X + Math.Cos(orientation + Math.PI / 16) * 75.0), (int)(markerCenter.Y + Math.Sin(orientation + Math.PI / 16) * 75.0) ); debugImage.Draw(new Cross2DF(markerCenter, 6, 6), Rgbs.Green, 2); debugImage.Draw(new LineSegment2DF(markerCenter, p2), Rgbs.Green, 2); debugImage.Draw(string.Format("{0} deg", Math.Round(degOrientation, 1)), ref EmguFont, p3, Rgbs.Green); } } else { // if glyph disappeared remove entry from table _recognizedGlyphs[name] = null; } } } image.ROI = imageRoi; return(markers); }
private IEnumerable<Marker> GetMarkers(ref Image<Rgb, byte> image, Rectangle roi, int width, int height, ref Image<Rgb, byte> debugImage, out List<Point[]> quadrilaterals) { if (_glyphRecognizer == null) { quadrilaterals = new List<Point[]>(); return null; } var imageWidth = image.Width; var imageHeight = image.Height; var imageRoi = image.ROI; var markers = new List<Marker>(); var minFramesProperty = MinFramesProperty; // Draw new Roi if (IsRenderContent) { debugImage.Draw(roi, Rgbs.Red, 2); } _recognizedGlyphs.Clear(); _recognizedQuads.Clear(); var glyphs = _glyphRecognizer.FindGlyphs(image.Bitmap); foreach (var glyph in glyphs) { // highlight quadrilateral (of all found glyphs) var tmpQuad = glyph.Quadrilateral; if (tmpQuad == null || tmpQuad.Count != 4) continue; var quad = new[] { new Point(tmpQuad[0].X, tmpQuad[0].Y), new Point(tmpQuad[1].X, tmpQuad[1].Y), new Point(tmpQuad[2].X, tmpQuad[2].Y), new Point(tmpQuad[3].X, tmpQuad[3].Y) }; if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; debugImage.DrawPolyline(quad, true, Rgbs.Yellow, 1); debugImage.ROI = debugImageRoi; } // if glyphs are recognized then store and draw name var recQuad = glyph.RecognizedQuadrilateral; var recGlyph = glyph.RecognizedGlyph; if (recQuad != null && recGlyph != null) { _recognizedGlyphs.Add(recGlyph.Name, recGlyph); _recognizedQuads.Add(recGlyph.Name, quad); if (IsRenderContent) { var debugImageRoi = debugImage.ROI; debugImage.ROI = roi; var labelPos = new Point(recQuad[2].X, recQuad[2].Y); debugImage.Draw(recGlyph.Name, ref EmguFontBig, labelPos, Rgbs.Green); debugImage.ROI = debugImageRoi; } } } // update all entries in glyph table using recognized glyphs quadrilaterals = new List<Point[]>(); var length = _glyphTable.Length; for (int i = 0; i < length; i++) { var name = (i + 1).ToString(CultureInfo.InvariantCulture); Glyph glyph = null; Point[] quad = null; if (_recognizedGlyphs.ContainsKey(name)) glyph = _recognizedGlyphs[name]; if (_recognizedQuads.ContainsKey(name)) quad = _recognizedQuads[name]; // if glyph for this entry was recognized, update entry if (glyph != null && quad != null) { quadrilaterals.Add(quad); // if there is no entry yet, create it if (_glyphTable[i] == null) _glyphTable[i] = new GlyphMetadata(); var gmd = _glyphTable[i]; gmd.aliveFrames++; Point upVector1 = quad[0].Sub(quad[3]); Point upVector2 = quad[1].Sub(quad[2]); upVector1 = (upVector1.Add(upVector2)).Div(2); double orientation = Math.Atan2(upVector1.Y, upVector2.X); // always keep only the last X frames in list if (gmd.prevX.Count == minFramesProperty) { gmd.prevX.RemoveAt(0); gmd.prevY.RemoveAt(0); gmd.prevOrientations.RemoveAt(0); } gmd.prevX.Add(quad[0].X); gmd.prevY.Add(quad[0].Y); gmd.prevOrientations.Add(orientation); // check if marker stops moving and rotating if (Math.Abs(gmd.prevX.Max() - gmd.prevX.Min()) < 5 && Math.Abs(gmd.prevY.Max() - gmd.prevY.Min()) < 5 && gmd.aliveFrames >= minFramesProperty) { var x = orientation + Math.PI / 2; var degOrientation = (x > 0.0 ? x : (2.0 * Math.PI + x)) * 360 / (2.0 * Math.PI); // find bounding rectangle float minX = image.Width; float minY = image.Height; float maxX = 0; float maxY = 0; foreach (Point p in quad) { minX = Math.Min(minX, p.X); minY = Math.Min(minY, p.Y); maxX = Math.Max(maxX, p.X); maxY = Math.Max(maxY, p.Y); } var centerX = roi.X + minX + (maxX - minX) / 2.0f; var centerY = roi.Y + minY + (maxY - minY) / 2.0f; markers.Add(new Marker(this, "Display") { Id = name, Center = new System.Windows.Point(centerX / width, centerY / height), RelativeCenter = new System.Windows.Point(centerX / imageWidth, centerY / imageHeight), Angle = degOrientation }); // Render center and orientation of marker if (IsRenderContent) { var markerCenter = new PointF(centerX, centerY); var p2 = new Point( (int)(markerCenter.X + Math.Cos(orientation) * 100.0), (int)(markerCenter.Y + Math.Sin(orientation) * 100.0) ); var p3 = new Point( (int)(markerCenter.X + Math.Cos(orientation + Math.PI / 16) * 75.0), (int)(markerCenter.Y + Math.Sin(orientation + Math.PI / 16) * 75.0) ); debugImage.Draw(new Cross2DF(markerCenter, 6, 6), Rgbs.Green, 2); debugImage.Draw(new LineSegment2DF(markerCenter, p2), Rgbs.Green, 2); debugImage.Draw(string.Format("{0} deg", Math.Round(degOrientation, 1)), ref EmguFont, p3, Rgbs.Green); } } else { // if glyph disappeared remove entry from table _recognizedGlyphs[name] = null; } } } image.ROI = imageRoi; return markers; }