private void FindMarker(Image<Rgb, byte> image, int offsetX, int offsetY, int width, int height, ref Image<Rgb, byte> outputImage)
        {
            if (_glyphRecognizer != null)
            {
                // go through all found glyphs, highlight them and put the recognized ones in a list

                _recognizedGlyphs.Clear();
                _recognizedQuads.Clear();
                var glyphs = _glyphRecognizer.FindGlyphs(image.Bitmap);

                foreach (var glyph in glyphs)
                {
                    // highlight quadrilateral (of all found glyphs)
                    var quad = glyph.Quadrilateral;

                    if (IsRenderContent && quad != null && quad.Count == 4)
                    {
                        outputImage.DrawPolyline(
                            new[]
                            {
                                new Point(quad[0].X + offsetX, quad[0].Y + offsetY),
                                new Point(quad[1].X + offsetX, quad[1].Y + offsetY),
                                new Point(quad[2].X + offsetX, quad[2].Y + offsetY),
                                new Point(quad[3].X + offsetX, quad[3].Y + offsetY)
                            },
                            true, Rgbs.Red, 1);

                        // write numbers on edge points (of all found glyphs)
                        var i = 0;
                        foreach (var point in quad)
                        {
                            outputImage.Draw(i++.ToString(CultureInfo.InvariantCulture), ref EmguFont, new Point(point.X + offsetX, point.Y + offsetY), Rgbs.TrueRed);
                        }
                    }

                    // 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, recQuad);

                        if (IsRenderContent)
                        {
                            String label = recGlyph.Name;
                            Point labelPos = new Point(recQuad[2].X + offsetX, recQuad[2].Y + offsetY);
                            outputImage.Draw(label, ref EmguFontBig, labelPos, Rgbs.Green);
                        }
                    }
                }

                // update all entries in glyph table using recognized glyphs

                for (int i = 0; i < _glyphTable.Length; i++)
                {
                    var name = i.ToString(CultureInfo.InvariantCulture);

                    Glyph glyph = null;
                    List<IntPoint> 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)
                    {
                        // if there is no entry yet, create it
                        if (_glyphTable[i] == null)
                            _glyphTable[i] = new GlyphMetadata();

                        var gmd = _glyphTable[i];

                        gmd.aliveFrames++;

                        IntPoint upVector1 = quad[0] - quad[3];
                        IntPoint upVector2 = quad[1] - quad[2];
                        upVector1 = (upVector1 + upVector2) / 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)
                        {
                            double radOrientation = gmd.prevOrientations.Average() + Math.PI / 2;

                            if (IsRenderContent)
                            {
                                Point p1 = new Point(quad[0].X + offsetX, quad[0].Y + offsetY);
                                Point p2 = new Point(
                                    (int)(quad[0].X + offsetX + Math.Cos(orientation) * 100.0),
                                    (int)(quad[0].Y + offsetY + Math.Sin(orientation) * 100.0)
                                    );

                                outputImage.Draw(new LineSegment2D(p1, p2), Rgbs.Yellow, 2);
                            }

                            double degOrientation = orientation.RadiansToDegree() + 90;

                            // find bounding rectangle
                            float minX = image.Width;
                            float minY = image.Height;
                            float maxX = 0;
                            float maxY = 0;

                            foreach (IntPoint 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);
                            }

                            float centerX = offsetX + minX + (maxX - minX) / 2.0f;
                            float centerY = offsetY + minY + (maxY - minY) / 2.0f;

                            if (IsRenderContent)
                                outputImage.Draw(new Cross2DF(new PointF(centerX, centerY), 6, 6), Rgbs.Red, 1);

                            // Stage data for later push
                            Stage(new Marker(this, string.Format("Glyph{0}", name))
                            {
                                Id = name,
                                Center = new System.Windows.Point(centerX / width, centerY / height),
                                Angle = degOrientation
                            });

                            if (IsRenderContent)
                            {
                                // bring to human readable form
                                radOrientation = Math.Round(radOrientation, 2);
                                degOrientation = Math.Round(degOrientation, 2);

                                String label = radOrientation + " " + degOrientation;
                                Point labelPos = new Point(quad[0].X + offsetX, quad[0].Y + offsetY);
                                outputImage.Draw(label, ref EmguFontBig, labelPos, Rgbs.Yellow);
                            }
                        }
                    }
                    else
                    {
                        // if glyph disappeared remove entry from table
                        _recognizedGlyphs[name] = null;
                    }
                }

            }
        }
Beispiel #2
0
        private void FindMarker(Image <Rgb, byte> image, int offsetX, int offsetY, int width, int height, ref Image <Rgb, byte> outputImage)
        {
            if (_glyphRecognizer != null)
            {
                // go through all found glyphs, highlight them and put the recognized ones in a list

                _recognizedGlyphs.Clear();
                _recognizedQuads.Clear();
                var glyphs = _glyphRecognizer.FindGlyphs(image.Bitmap);

                foreach (var glyph in glyphs)
                {
                    // highlight quadrilateral (of all found glyphs)
                    var quad = glyph.Quadrilateral;

                    if (IsRenderContent && quad != null && quad.Count == 4)
                    {
                        outputImage.DrawPolyline(
                            new[]
                        {
                            new Point(quad[0].X + offsetX, quad[0].Y + offsetY),
                            new Point(quad[1].X + offsetX, quad[1].Y + offsetY),
                            new Point(quad[2].X + offsetX, quad[2].Y + offsetY),
                            new Point(quad[3].X + offsetX, quad[3].Y + offsetY)
                        },
                            true, Rgbs.Red, 1);

                        // write numbers on edge points (of all found glyphs)
                        var i = 0;
                        foreach (var point in quad)
                        {
                            outputImage.Draw(i++.ToString(CultureInfo.InvariantCulture), ref EmguFont, new Point(point.X + offsetX, point.Y + offsetY), Rgbs.TrueRed);
                        }
                    }

                    // 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, recQuad);

                        if (IsRenderContent)
                        {
                            String label    = recGlyph.Name;
                            Point  labelPos = new Point(recQuad[2].X + offsetX, recQuad[2].Y + offsetY);
                            outputImage.Draw(label, ref EmguFontBig, labelPos, Rgbs.Green);
                        }
                    }
                }


                // update all entries in glyph table using recognized glyphs

                for (int i = 0; i < _glyphTable.Length; i++)
                {
                    var name = i.ToString(CultureInfo.InvariantCulture);

                    Glyph           glyph = null;
                    List <IntPoint> 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)
                    {
                        // if there is no entry yet, create it
                        if (_glyphTable[i] == null)
                        {
                            _glyphTable[i] = new GlyphMetadata();
                        }

                        var gmd = _glyphTable[i];

                        gmd.aliveFrames++;

                        IntPoint upVector1 = quad[0] - quad[3];
                        IntPoint upVector2 = quad[1] - quad[2];
                        upVector1 = (upVector1 + upVector2) / 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)
                        {
                            double radOrientation = gmd.prevOrientations.Average() + Math.PI / 2;

                            if (IsRenderContent)
                            {
                                Point p1 = new Point(quad[0].X + offsetX, quad[0].Y + offsetY);
                                Point p2 = new Point(
                                    (int)(quad[0].X + offsetX + Math.Cos(orientation) * 100.0),
                                    (int)(quad[0].Y + offsetY + Math.Sin(orientation) * 100.0)
                                    );

                                outputImage.Draw(new LineSegment2D(p1, p2), Rgbs.Yellow, 2);
                            }

                            double degOrientation = orientation.RadiansToDegree() + 90;

                            // find bounding rectangle
                            float minX = image.Width;
                            float minY = image.Height;
                            float maxX = 0;
                            float maxY = 0;

                            foreach (IntPoint 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);
                            }

                            float centerX = offsetX + minX + (maxX - minX) / 2.0f;
                            float centerY = offsetY + minY + (maxY - minY) / 2.0f;

                            if (IsRenderContent)
                            {
                                outputImage.Draw(new Cross2DF(new PointF(centerX, centerY), 6, 6), Rgbs.Red, 1);
                            }

                            // Stage data for later push
                            Stage(new Marker(this, string.Format("Glyph{0}", name))
                            {
                                Id     = name,
                                Center = new System.Windows.Point(centerX / width, centerY / height),
                                Angle  = degOrientation
                            });

                            if (IsRenderContent)
                            {
                                // bring to human readable form
                                radOrientation = Math.Round(radOrientation, 2);
                                degOrientation = Math.Round(degOrientation, 2);

                                String label    = radOrientation + " " + degOrientation;
                                Point  labelPos = new Point(quad[0].X + offsetX, quad[0].Y + offsetY);
                                outputImage.Draw(label, ref EmguFontBig, labelPos, Rgbs.Yellow);
                            }
                        }
                    }
                    else
                    {
                        // if glyph disappeared remove entry from table
                        _recognizedGlyphs[name] = null;
                    }
                }
            }
        }