public bool DetectGlyph(Bitmap bitmap) { bool found = false; foundGlyphs = recognizer.FindGlyphs(bitmap); if (foundGlyphs.Count > 0) { found = true; } return(found); }
// Find glyphs in image, returns list with extracted data public List <ExtractedGlyphData> GetGlyphPosition(Bitmap image) { List <ExtractedGlyphData> glyphs; if (glyphScalingFactor != 1) { image = new Bitmap(image, (int)(image.Width * glyphScalingFactor), (int)(image.Height * glyphScalingFactor)); glyphs = recognizer.FindGlyphs(image); for (int i = 0; i < glyphs.Count; i++) { for (int j = 0; j < glyphs[i].Quadrilateral.Count; j++) { glyphs[i].Quadrilateral[j] = new IntPoint((int)(glyphs[i].Quadrilateral[j].X / glyphScalingFactor), (int)(glyphs[i].Quadrilateral[j].Y / glyphScalingFactor)); } } } else { glyphs = recognizer.FindGlyphs(image); } return(glyphs); }
private void camCapturer_NewFrame(System.Drawing.Bitmap bitmap) { var glyphs = _glyphRecognizer.FindGlyphs(bitmap); if (glyphs.Count > 0) { var glyph = glyphs[0]; List <IntPoint> glyphPoints = glyph.RecognizedGlyph == null ? glyph.Quadrilateral : glyph.RecognizedQuadrilateral; System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Red, 3); Graphics g = Graphics.FromImage(bitmap); g.DrawPolygon(pen, ToPointsArray(glyphPoints)); g.DrawEllipse(new System.Drawing.Pen(System.Drawing.Brushes.Green, 3), glyphPoints[0].X, glyphPoints[0].Y, 10, 10); } BitmapImage bitmapImage = BitmapToBitmapImage(bitmap); UpdateImage_Frame(bitmapImage); }
// 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); }
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 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; } } } }
void camera_NewFrame(object sender, NewFrameEventArgs eventArgs) { float sizeHalf = 113.0f / 2; Vector3[] glyphModel = new Vector3[] { new Vector3(-sizeHalf, 0, sizeHalf), new Vector3(sizeHalf, 0, sizeHalf), new Vector3(sizeHalf, 0, -sizeHalf), new Vector3(-sizeHalf, 0, -sizeHalf), }; try { GlyphRecognizer gr = new GlyphRecognizer(glyphDatabase); List <ExtractedGlyphData> glyphs = gr.FindGlyphs(eventArgs.Frame); System.Drawing.Image img = (Bitmap)eventArgs.Frame.Clone(); double x = 0; double y = 0; String glyphName = String.Empty; AForge.Point[] glyphPoints = new AForge.Point[4]; foreach (var glyph in glyphs) { if (glyph.RecognizedGlyph != null) { glyphName = glyph.RecognizedGlyph.Name; x = (glyph.Quadrilateral[0].X + glyph.Quadrilateral[2].X) / 2; y = (glyph.Quadrilateral[0].Y + glyph.Quadrilateral[2].Y) / 2; for (int i = 0; i < 4; i++) { glyphPoints[i] = new AForge.Point( (int)(glyph.RecognizedQuadrilateral[i].X - x), (int)y - glyph.RecognizedQuadrilateral[i].Y); } break; } } MemoryStream ms = new MemoryStream(); img.Save(ms, ImageFormat.Bmp); ms.Seek(0, SeekOrigin.Begin); BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = ms; bi.EndInit(); bi.Freeze(); Dispatcher.BeginInvoke(new ThreadStart(delegate { //Canvas.SetLeft(pictureGlyph, x-60); //Canvas.SetTop(pictureGlyph, y-60); image1.Source = bi; Title = "Found glyphs " + glyphs.Count + " " + glyphName; if (glyphName != "") { Dispatcher.BeginInvoke(new ThreadStart(delegate { Console.WriteLine(MODEL_PATH); MODEL_PATH = CurrentGallery.UrlPrefix + "\\" + glyphName + ".3ds"; float yaw, pitch, roll; CoplanarPosit posit = new CoplanarPosit(glyphModel, 1); Matrix3x3 positRotation; Vector3 positTranslation; posit.EstimatePose(glyphPoints, out positRotation, out positTranslation); positRotation.ExtractYawPitchRoll(out yaw, out pitch, out roll); visualisation3Dmodel(MODEL_PATH, yaw, pitch, roll, new Vector3D(positTranslation.X, positTranslation.Y, positTranslation.Z)); })); } })); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
// 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); }