// Process image searching for glyphs and highlighting them
        public List <ExtractedGlyphData> ProcessImage(Bitmap image)
        {
            var glyphs = new List <ExtractedGlyphData>();

            lock (_sync)
            {
                _glyphTracker.ImageSize = image.Size;

                // get list of recognized glyphs
                glyphs.AddRange(_recognizer.FindGlyphs(image));
                if (glyphs.Count <= 0)
                {
                    return(glyphs);
                }

                // visualizing glyphs
                var glyphIDs = _glyphTracker.TrackGlyphs(glyphs);

                var g = Graphics.FromImage(image);
                var i = 0;

                // highlight each found glyph
                foreach (var glyphData in glyphs)
                {
                    var glyphPoints = (glyphData.RecognizedGlyph == null)
                        ? glyphData.Quadrilateral
                        : glyphData.RecognizedQuadrilateral;

                    var pen = new Pen(Color.Red);

                    // highlight border
                    g.DrawPolygon(pen, ToPointsArray(glyphPoints));

                    // prepare glyph's title
                    var glyphTitle = glyphData.RecognizedGlyph != null
                        ? glyphData.RecognizedGlyph.Name
                        : string.Format("ID: {0}", glyphIDs[i]);

                    // show glyph's title
                    if (!string.IsNullOrEmpty(glyphTitle))
                    {
                        // get glyph's center point
                        IntPoint minXY, maxXY;
                        PointsCloud.GetBoundingRectangle(glyphPoints, out minXY, out maxXY);
                        var center = (minXY + maxXY) / 2;

                        // glyph's name size
                        var nameSize = g.MeasureString(glyphTitle, _defaultFont);

                        // paint the name
                        var brush = new SolidBrush(pen.Color);

                        g.DrawString(glyphTitle, _defaultFont, brush,
                                     new System.Drawing.Point(center.X - (int)nameSize.Width / 2,
                                                              center.Y - (int)nameSize.Height / 2));

                        brush.Dispose();
                    }

                    i++;
                    pen.Dispose();
                }
            }

            return(glyphs);
        }
        // Process image searching for glyphs and highlighting them
        public List <ExtractedGlyphData> ProcessImage(Bitmap bitmap)
        {
            List <ExtractedGlyphData> glyphs = new List <ExtractedGlyphData>( );

            lock ( sync )
            {
                glyphTracker.ImageSize = bitmap.Size;

                // get list of recognized glyphs
                glyphs.AddRange(recognizer.FindGlyphs(bitmap));
                List <int> glyphIDs = glyphTracker.TrackGlyphs(glyphs);

                if (glyphs.Count > 0)
                {
                    if ((visualizationType == VisualizationType.BorderOnly) ||
                        (visualizationType == VisualizationType.Name))
                    {
                        Graphics g = Graphics.FromImage(bitmap);
                        int      i = 0;

                        // highlight each found glyph
                        foreach (ExtractedGlyphData glyphData in glyphs)
                        {
                            List <IntPoint> glyphPoints = (glyphData.RecognizedGlyph == null) ?
                                                          glyphData.Quadrilateral : glyphData.RecognizedQuadrilateral;

                            Pen pen = new Pen(((glyphData.RecognizedGlyph == null) || (glyphData.RecognizedGlyph.UserData == null)) ?
                                              Color.Red : ((GlyphVisualizationData)glyphData.RecognizedGlyph.UserData).Color, 3);

                            // highlight border
                            g.DrawPolygon(pen, ToPointsArray(glyphPoints));

                            string glyphTitle = null;

                            // prepare glyph's title
                            if ((visualizationType == VisualizationType.Name) && (glyphData.RecognizedGlyph != null))
                            {
                                glyphTitle = string.Format("{0}: {1}",
                                                           glyphIDs[i], glyphData.RecognizedGlyph.Name);
                            }
                            else
                            {
                                glyphTitle = string.Format("Tracking ID: {0}", glyphIDs[i]);
                            }

                            // show glyph's title
                            if (!string.IsNullOrEmpty(glyphTitle))
                            {
                                // get glyph's center point
                                IntPoint minXY, maxXY;
                                PointsCloud.GetBoundingRectangle(glyphPoints, out minXY, out maxXY);
                                IntPoint center = (minXY + maxXY) / 2;

                                // glyph's name size
                                SizeF nameSize = g.MeasureString(glyphTitle, defaultFont);

                                // paint the name
                                Brush brush = new SolidBrush(pen.Color);

                                g.DrawString(glyphTitle, defaultFont, brush,
                                             new System.Drawing.Point(center.X - (int)nameSize.Width / 2, center.Y - (int)nameSize.Height / 2));

                                brush.Dispose( );
                            }

                            i++;
                            pen.Dispose( );
                        }
                    }
                    else if (visualizationType == VisualizationType.Image)
                    {
                        // lock image for further processing
                        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                                                ImageLockMode.ReadWrite, bitmap.PixelFormat);
                        UnmanagedImage unmanagedImage = new UnmanagedImage(bitmapData);

                        // highlight each found glyph
                        foreach (ExtractedGlyphData glyphData in glyphs)
                        {
                            if ((glyphData.RecognizedGlyph != null) && (glyphData.RecognizedGlyph.UserData != null))
                            {
                                GlyphVisualizationData visualization =
                                    (GlyphVisualizationData)glyphData.RecognizedGlyph.UserData;

                                if (visualization.ImageName != null)
                                {
                                    // get image associated with the glyph
                                    Bitmap glyphImage = EmbeddedImageCollection.Instance.GetImage(visualization.ImageName);

                                    if (glyphImage != null)
                                    {
                                        // put glyph's image onto the glyph using quadrilateral transformation
                                        quadrilateralTransformation.SourceImage = glyphImage;
                                        quadrilateralTransformation.DestinationQuadrilateral = glyphData.RecognizedQuadrilateral;

                                        quadrilateralTransformation.ApplyInPlace(unmanagedImage);
                                    }
                                }
                            }
                        }

                        bitmap.UnlockBits(bitmapData);
                    }
                }
            }

            return(glyphs);
        }