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();
            }
        }
Example #2
0
        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);
                }
            }
        }