Пример #1
0
        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);
        }
Пример #2
0
        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;
        }