public Contour Extract(UnmanagedImage blob) { switch (Method) { case PreprocessMethod.ExtendAndDilatation: // extend with 1px indention UnmanagedImage preprocessed = UnmanagedImage.Create(blob.Width + 2, blob.Height + 2, blob.PixelFormat); blob.CopyWithOffset(preprocessed, new IntPoint(1, 1)); // dilatation m_dilatation.ApplyInPlace(preprocessed); // delete internal pixels m_deleteInternal.ApplyInPlace(preprocessed); // trace edge return(m_edgeTracer.Extract(preprocessed)); case PreprocessMethod.Scale: int scaleMultiplier = 3; m_resizer.NewHeight = blob.Height * scaleMultiplier; m_resizer.NewWidth = blob.Width * scaleMultiplier; // scale blob UnmanagedImage resized = m_resizer.Apply(blob); // delete internal pixels m_deleteInternal.ApplyInPlace(resized); // trace edge return(m_edgeTracer.Extract(resized)); case PreprocessMethod.None: // delete internal pixels m_deleteInternal.ApplyInPlace(blob); // trace edge return(m_edgeTracer.Extract(blob)); default: throw new Exception(); } }
private void PatternRecognition(Bitmap bitmap) { // Prvi korak - grayscalling originalne slike Bitmap frame = grayscaleFilter.Apply(bitmap); BitmapData frameData = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), ImageLockMode.ReadWrite, frame.PixelFormat); // Drugi korak - detekcija ivica pomocu Sobel filtra sobelFilter.ApplyInPlace(frameData); // Treći korak - konvertuj sliku u crno-bijelu pri čemu je threshold = 100 odnoso od 0 do 155 je crna boja, a od 156 do 255 je bijela boja thresholdFilter.ApplyInPlace(frameData); // Četvrti korak - dilitacija / pojacavanje bijele boje jer dilitationFilter.ApplyInPlace(frameData); // Peti korak - kreiranje binarne slike frame = frame.Clone(new Rectangle(0, 0, frame.Width, frame.Height), PixelFormat.Format8bppIndexed); // Šesti korak - pronalazak potencijalnih oblika na slici blobCounter.ProcessImage(frameData); Blob[] blobs = blobCounter.GetObjectsInformation(); // za crtanje po originalnoj slici Graphics g = Graphics.FromImage(bitmap); // Sedmi korak - provjeri svaki oblik foreach (Blob blob in blobs) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); List<IntPoint> hullPoints = hullFinder.FindHull(edgePoints); List<IntPoint> corners = null; // da li je četverougao? if (shapeChecker.IsQuadrilateral(hullPoints, out corners)) // da li je kvadrat? if (shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Square) { if (!detected) { // Osmi korak - odrđivanje centra gravitacije i gornjeg lijevog tjemena FindNewCorners(corners); // Deveti korak - ekstrakcija prepoznatog kvadrata sa originalne slike u novu sliku dimenzija 100x100 SimpleQuadrilateralTransformation quadrilateralTransformation = new SimpleQuadrilateralTransformation(corners, 100, 100); Bitmap recognizedSquare = quadrilateralTransformation.Apply(bitmap); recognizedSquare = recognizedSquare.Clone(new Rectangle(0, 0, recognizedSquare.Width, recognizedSquare.Height), PixelFormat.Format8bppIndexed); // Deseti korak - od nove slike ponovo napravi crno-bijelu otsuThresholdFilter.ApplyInPlace(recognizedSquare); // Jedanaesti korak - invertuj boje invertFilter.ApplyInPlace(recognizedSquare); //Dvanaesti korak - prepoznaj oblik (formiraj matricu) float confidence; // vjerovatnoća da je prepoznat pravi oblik (odnos borja crnih i bijelih piksela u ćeliji byte[,] pattern = binaryGlyphRecognizer.Recognize(recognizedSquare, new Rectangle(0, 0, recognizedSquare.Width, recognizedSquare.Height), out confidence); recognizedSquare.Dispose(); if (confidence >= 0.6) { oldPatterns.Add(pattern); Boolean canDraw = CheckPrevious(); if (canDraw) { // Trinaesti korak - iscrtaj matricu DrawPattern(pattern); detected = true; // pravim delay od 3s nakon što prepozna pattern new Task(() => { Thread.Sleep(3*1000); detected = false; }).Start(); // Komunikacija sa warehouse uređajem. //new Thread(new RS232Communication(shape).Run).Start(); } } } // iscrtaj ivice oko prepoznatog kvadrata g.DrawPolygon(pen, ToPointsArray(hullPoints)); } } g.Dispose(); frame.UnlockBits(frameData); frame.Dispose(); }
static void Main(string[] args) { Threshold thresh = new Threshold(10); Median median = new Median(9); Erosion3x3 erode = new Erosion3x3(); Dilatation3x3 dilate = new Dilatation3x3(); GrahamConvexHull hullFinder = new GrahamConvexHull(); ConnectedComponentsLabeling ccLabeler = new ConnectedComponentsLabeling(); BorderFollowing contourFinder = new BorderFollowing(); GrayscaleToRGB rgb = new GrayscaleToRGB(); ConvexHullDefects defectFinder = new ConvexHullDefects(10); Bitmap img = (Bitmap)Bitmap.FromFile("hand3.jpg"); Bitmap image = Grayscale.CommonAlgorithms.BT709.Apply(img); thresh.ApplyInPlace(image); //median.ApplyInPlace(image); erode.ApplyInPlace(image); dilate.ApplyInPlace(image); BlobCounter counter = new BlobCounter(image); counter.ObjectsOrder = ObjectsOrder.Area; Blob[] blobs = counter.GetObjectsInformation(); if (blobs.Length > 0) { counter.ExtractBlobsImage(image, blobs[0], true); UnmanagedImage hand = blobs[0].Image; var contour = contourFinder.FindContour(hand); if (contour.Count() > 0) { var initialHull = hullFinder.FindHull(contour); var defects = defectFinder.FindDefects(contour, initialHull); var filteredHull = initialHull.ClusterHullPoints().FilterLinearHullPoints(); var palmCenter = defects.Centroid(contour); var wristPoints = filteredHull.SelectWristPoints(defects, contour); Bitmap color = rgb.Apply(hand).ToManagedImage(); //BitmapData data = color.LockBits(new Rectangle(0, 0, color.Width, color.Height), ImageLockMode.ReadWrite, color.PixelFormat); //Drawing.Polyline(data, contour, Color.Blue); //Drawing.Polygon(data, filteredHull, Color.Red); //color.UnlockBits(data); Graphics gr = Graphics.FromImage(color); gr.DrawPolygon(new Pen(Brushes.Red, 3), filteredHull.ToPtArray()); gr.DrawLines(new Pen(Brushes.Blue, 3), contour.ToPtArray()); gr.DrawEllipse(new Pen(Brushes.Red, 3), palmCenter.X - 10, palmCenter.Y - 10, 20, 20); foreach (ConvexityDefect defect in defects) { gr.DrawEllipse(new Pen(Brushes.Green, 6), contour[defect.Point].X - 10, contour[defect.Point].Y - 10, 20, 20); } foreach (AForge.IntPoint pt in filteredHull) { gr.DrawEllipse(new Pen(Brushes.Yellow, 6), pt.X - 10, pt.Y - 10, 20, 20); } foreach (AForge.IntPoint pt in wristPoints) { gr.DrawEllipse(new Pen(Brushes.PowderBlue, 6), pt.X - 10, pt.Y - 10, 20, 20); } ImageBox.Show(color); } } }