// 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);
        }
Example #2
0
        private void ProcessImage(Bitmap bitmap)
        {
            // lock image
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            // step 1 - turn background to black
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red              = new IntRange(Properties.Settings.Default.camFilterRed1, Properties.Settings.Default.camFilterRed2);
            colorFilter.Green            = new IntRange(Properties.Settings.Default.camFilterGreen1, Properties.Settings.Default.camFilterGreen2);
            colorFilter.Blue             = new IntRange(Properties.Settings.Default.camFilterBlue1, Properties.Settings.Default.camFilterBlue2);
            colorFilter.FillOutsideRange = Properties.Settings.Default.camFilterOutside;

            colorFilter.ApplyInPlace(bitmapData);

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight   = (int)Properties.Settings.Default.camShapeSizeMin * (int)cameraZoom;
            blobCounter.MinWidth    = (int)Properties.Settings.Default.camShapeSizeMin * (int)cameraZoom;
            blobCounter.MaxHeight   = (int)Properties.Settings.Default.camShapeSizeMax * (int)cameraZoom;
            blobCounter.MaxWidth    = (int)Properties.Settings.Default.camShapeSizeMax * (int)cameraZoom;

            blobCounter.ProcessImage(bitmapData);

            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            shapeChecker.MinAcceptableDistortion = (float)Properties.Settings.Default.camShapeDist;
            shapeChecker.RelativeDistortionLimit = (float)Properties.Settings.Default.camShapeDistMax;

            Graphics g         = Graphics.FromImage(bitmap);
            Pen      yellowPen = new Pen(Color.Yellow, 5); // circles
            Pen      redPen    = new Pen(Color.Red, 10);   // circles
            Pen      greenPen  = new Pen(Color.Green, 5);  // known triangle

            double lowestDistance = xmid;
            double distance;

            shapeFound = false;
            DoublePoint center;
            double      shapeRadius = 1;

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                double          radius;
                // is circle ?
                //          g.DrawPolygon(greenPen, ToPointsArray(edgePoints));

                if (Properties.Settings.Default.camShapeCircle && shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    shapeFound = true;
                    distance   = center.DistanceTo(picCenter);
                    g.DrawEllipse(yellowPen,
                                  (float)(shapeCenter.X - shapeRadius), (float)(shapeCenter.Y - shapeRadius),
                                  (float)(shapeRadius * 2), (float)(shapeRadius * 2));

                    if (lowestDistance > Math.Abs(distance))
                    {
                        lowestDistance = Math.Abs(distance);
                        shapeCenter    = center;
                        shapeRadius    = radius;
                    }
                }
                List <IntPoint> corners;
                if (Properties.Settings.Default.camShapeRect && shapeChecker.IsQuadrilateral(edgePoints, out corners))  //.IsConvexPolygon
                {
                    IntPoint minxy, maxxy, centxy;
                    shapeFound = true;
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
                    g.DrawPolygon(yellowPen, ToPointsArray(corners));
                    PointsCloud.GetBoundingRectangle(corners, out minxy, out maxxy);
                    centxy   = (minxy + maxxy) / 2;
                    distance = picCenter.DistanceTo(centxy);// PointsCloud.GetCenterOfGravity(corners));
                    if (lowestDistance > Math.Abs(distance))
                    {
                        lowestDistance = Math.Abs(distance);
                        shapeCenter    = centxy;                      // PointsCloud.GetCenterOfGravity(corners);
                        shapeRadius    = maxxy.DistanceTo(minxy) / 2; // 50;
                    }
                }
            }
            if (shapeFound)
            {
                g.DrawEllipse(redPen,
                              (float)(shapeCenter.X - shapeRadius * 1.2), (float)(shapeCenter.Y - shapeRadius * 1.2),
                              (float)(shapeRadius * 2.4), (float)(shapeRadius * 2.4));
            }

            yellowPen.Dispose();
            redPen.Dispose();
            greenPen.Dispose();
            g.Dispose();

            // put new image to clipboard
            //           Clipboard.SetDataObject(bitmap);
            // and to picture box
            pictureBoxVideo.BackgroundImage = bitmap;
            //UpdatePictureBoxPosition();
        }
        /// <summary>
        /// Find corners of quadrilateral/triangular area in the specified image.
        /// </summary>
        ///
        /// <param name="image">Source image to search quadrilateral for.</param>
        ///
        /// <returns>Returns a list of points, which are corners of the quadrilateral/triangular area found
        /// in the specified image. The first point in the list is the point with lowest
        /// X coordinate (and with lowest Y if there are several points with the same X value).
        /// Points are in clockwise order (screen coordinates system).</returns>
        ///
        /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of the source image.</exception>
        ///
        public List <IntPoint> ProcessImage(UnmanagedImage image)
        {
            CheckPixelFormat(image.PixelFormat);

            // get source image size
            int width  = image.Width;
            int height = image.Height;

            // collection of points
            List <IntPoint> points = new List <IntPoint>( );

            // collect edge points
            unsafe
            {
                byte *src    = (byte *)image.ImageData.ToPointer( );
                int   stride = image.Stride;

                bool lineIsEmpty;

                if (image.PixelFormat == PixelFormat.Format8bppIndexed)
                {
                    // for each row
                    for (int y = 0; y < height; y++)
                    {
                        lineIsEmpty = true;

                        // scan from left to right
                        for (int x = 0; x < width; x++)
                        {
                            if (src[x] != 0)
                            {
                                points.Add(new IntPoint(x, y));
                                lineIsEmpty = false;
                                break;
                            }
                        }
                        if (!lineIsEmpty)
                        {
                            // scan from right to left
                            for (int x = width - 1; x >= 0; x--)
                            {
                                if (src[x] != 0)
                                {
                                    points.Add(new IntPoint(x, y));
                                    break;
                                }
                            }
                        }
                        src += stride;
                    }
                }
                else
                {
                    // 24 or 32 bpp color image
                    int pixelSize = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8;

                    byte *ptr = null;

                    // for each row
                    for (int y = 0; y < height; y++)
                    {
                        lineIsEmpty = true;
                        // scan from left to right
                        ptr = src;
                        for (int x = 0; x < width; x++, ptr += pixelSize)
                        {
                            if ((ptr[RGB.R] != 0) || (ptr[RGB.G] != 0) || (ptr[RGB.B] != 0))
                            {
                                points.Add(new IntPoint(x, y));
                                lineIsEmpty = false;
                                break;
                            }
                        }
                        if (!lineIsEmpty)
                        {
                            // scan from right to left
                            ptr = src + width * pixelSize - pixelSize;
                            for (int x = width - 1; x >= 0; x--, ptr -= pixelSize)
                            {
                                if ((ptr[RGB.R] != 0) || (ptr[RGB.G] != 0) || (ptr[RGB.B] != 0))
                                {
                                    points.Add(new IntPoint(x, y));
                                    break;
                                }
                            }
                        }
                        src += stride;
                    }
                }
            }

            return(PointsCloud.FindQuadrilateralCorners(points));
        }
Example #4
0
        // Process both images transforming source image into quadrilateral in destination image
        private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage)
        {
            // get source and destination images size
            int srcWidth  = srcImage.Width;
            int srcHeight = srcImage.Height;
            int dstWidth  = dstImage.Width;
            int dstHeight = dstImage.Height;

            int pixelSize = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8;
            int srcStride = srcImage.Stride;
            int dstStride = dstImage.Stride;

            // get bounding rectangle of the quadrilateral
            IntPoint minXY, maxXY;

            PointsCloud.GetBoundingRectangle(destinationQuadrilateral, out minXY, out maxXY);

            // make sure the rectangle is inside of destination image
            if ((maxXY.X < 0) || (maxXY.Y < 0) || (minXY.X >= dstWidth) || (minXY.Y >= dstHeight))
            {
                return; // nothing to do, since quadrilateral is completely outside
            }
            // correct rectangle if required
            if (minXY.X < 0)
            {
                minXY.X = 0;
            }
            if (minXY.Y < 0)
            {
                minXY.Y = 0;
            }
            if (maxXY.X >= dstWidth)
            {
                maxXY.X = dstWidth - 1;
            }
            if (maxXY.Y >= dstHeight)
            {
                maxXY.Y = dstHeight - 1;
            }

            int startX = minXY.X;
            int startY = minXY.Y;
            int stopX  = maxXY.X + 1;
            int stopY  = maxXY.Y + 1;
            int offset = dstStride - (stopX - startX) * pixelSize;

            // calculate tranformation matrix
            List <IntPoint> srcRect = new List <IntPoint>( );

            srcRect.Add(new IntPoint(0, 0));
            srcRect.Add(new IntPoint(srcWidth - 1, 0));
            srcRect.Add(new IntPoint(srcWidth - 1, srcHeight - 1));
            srcRect.Add(new IntPoint(0, srcHeight - 1));

            double[,] matrix = QuadTransformationCalcs.MapQuadToQuad(destinationQuadrilateral, srcRect);

            // do the job
            byte *ptr     = (byte *)dstImage.ImageData.ToPointer( );
            byte *baseSrc = (byte *)srcImage.ImageData.ToPointer( );

            // allign pointer to the first pixel to process
            ptr += (startY * dstStride + startX * pixelSize);

            if (!useInterpolation)
            {
                byte *p;

                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            // get pointer to the pixel in the source image
                            p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize;
                            // copy pixel's values
                            for (int i = 0; i < pixelSize; i++, ptr++, p++)
                            {
                                *ptr = *p;
                            }
                        }
                        else
                        {
                            // skip the pixel
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
            else
            {
                int srcWidthM1  = srcWidth - 1;
                int srcHeightM1 = srcHeight - 1;

                // coordinates of source points
                double dx1, dy1, dx2, dy2;
                int    sx1, sy1, sx2, sy2;

                // temporary pointers
                byte *p1, p2, p3, p4;

                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            sx1 = (int)srcX;
                            sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1;
                            dx1 = srcX - sx1;
                            dx2 = 1.0 - dx1;

                            sy1 = (int)srcY;
                            sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1;
                            dy1 = srcY - sy1;
                            dy2 = 1.0 - dy1;

                            // get four points
                            p1  = p2 = baseSrc + sy1 * srcStride;
                            p1 += sx1 * pixelSize;
                            p2 += sx2 * pixelSize;

                            p3  = p4 = baseSrc + sy2 * srcStride;
                            p3 += sx1 * pixelSize;
                            p4 += sx2 * pixelSize;

                            // interpolate using 4 points
                            for (int i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++)
                            {
                                *ptr = (byte)(
                                    dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
                                    dy1 * (dx2 * (*p3) + dx1 * (*p4)));
                            }
                        }
                        else
                        {
                            // skip the pixel
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
        }
Example #5
0
        public unsafe List <IntPoint> ProcessImage(UnmanagedImage image)
        {
            CheckPixelFormat(image.PixelFormat);
            int             width  = image.Width;
            int             height = image.Height;
            List <IntPoint> list   = new List <IntPoint>();
            byte *          ptr    = (byte *)image.ImageData.ToPointer();
            int             stride = image.Stride;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                for (int i = 0; i < height; i++)
                {
                    bool flag = true;
                    for (int j = 0; j < width; j++)
                    {
                        if (ptr[j] != 0)
                        {
                            list.Add(new IntPoint(j, i));
                            flag = false;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        for (int num = width - 1; num >= 0; num--)
                        {
                            if (ptr[num] != 0)
                            {
                                list.Add(new IntPoint(num, i));
                                break;
                            }
                        }
                    }
                    ptr += stride;
                }
            }
            else
            {
                int   num2 = System.Drawing.Image.GetPixelFormatSize(image.PixelFormat) / 8;
                byte *ptr2 = null;
                for (int k = 0; k < height; k++)
                {
                    bool flag = true;
                    ptr2 = ptr;
                    int num3 = 0;
                    while (num3 < width)
                    {
                        if (ptr2[2] != 0 || ptr2[1] != 0 || *ptr2 != 0)
                        {
                            list.Add(new IntPoint(num3, k));
                            flag = false;
                            break;
                        }
                        num3++;
                        ptr2 += num2;
                    }
                    if (!flag)
                    {
                        ptr2 = ptr + (long)width * (long)num2 - num2;
                        int num4 = width - 1;
                        while (num4 >= 0)
                        {
                            if (ptr2[2] != 0 || ptr2[1] != 0 || *ptr2 != 0)
                            {
                                list.Add(new IntPoint(num4, k));
                                break;
                            }
                            num4--;
                            ptr2 -= num2;
                        }
                    }
                    ptr += stride;
                }
            }
            return(PointsCloud.FindQuadrilateralCorners(list));
        }
Example #6
0
        public unsafe List <IntPoint> ProcessImage(UnmanagedImage image)
        {
            bool flag;

            this.CheckPixelFormat(image.PixelFormat);
            int             width  = image.Width;
            int             height = image.Height;
            List <IntPoint> list   = new List <IntPoint>();
            byte *          numPtr = (byte *)image.ImageData.ToPointer();
            int             stride = image.Stride;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                for (int i = 0; i < height; i++)
                {
                    flag = true;
                    for (int j = 0; j < width; j++)
                    {
                        if (numPtr[j] != 0)
                        {
                            list.Add(new IntPoint(j, i));
                            flag = false;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        for (int k = width - 1; k >= 0; k--)
                        {
                            if (numPtr[k] != 0)
                            {
                                list.Add(new IntPoint(k, i));
                                break;
                            }
                        }
                    }
                    numPtr += stride;
                }
            }
            else
            {
                int   num7    = Image.GetPixelFormatSize(image.PixelFormat) / 8;
                byte *numPtr2 = null;
                for (int m = 0; m < height; m++)
                {
                    flag    = true;
                    numPtr2 = numPtr;
                    int x = 0;
                    while (x < width)
                    {
                        if (((numPtr2[2] != 0) || (numPtr2[1] != 0)) || (numPtr2[0] != 0))
                        {
                            list.Add(new IntPoint(x, m));
                            flag = false;
                            break;
                        }
                        x++;
                        numPtr2 += num7;
                    }
                    if (!flag)
                    {
                        numPtr2 = (numPtr + (width * num7)) - num7;
                        int num10 = width - 1;
                        while (num10 >= 0)
                        {
                            if (((numPtr2[2] != 0) || (numPtr2[1] != 0)) || (numPtr2[0] != 0))
                            {
                                list.Add(new IntPoint(num10, m));
                                break;
                            }
                            num10--;
                            numPtr2 -= num7;
                        }
                    }
                    numPtr += stride;
                }
            }
            return(PointsCloud.FindQuadrilateralCorners(list));
        }
        private async Task CalibThread(FrameReadyEventArgs e)
        {
            Debug.WriteLine("Calibrating " + _calibrationStep + " ");
            e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep < 10?"0":"") + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg);
            if (_errors > 100)
            {
                //calibration not possible
                return;
            }
            if (_calibrationStep > CalibrationFrames)
            {
                // A concurrency problem, do nothing
            }
            if (_calibrationStep == CalibrationFrames)
            {
                _cc.FrameReady -= BaseCalibration;
                _calibrationStep++;
                //Grid.Calculate();
                _vs.Close();
                CalibrationCompleted(this, new EventArgs());
            }
            else
            {
                if (_calibrationStep > 2)
                {
                    // analyse diffimage
                    _vs.Clear();
                    var img = diffFilter.Apply(e.Frame.Bitmap);
                    var mf  = new GaussianBlur(0.6, 5);
                    var gf  = Grayscale.CommonAlgorithms.BT709;
#if DEBUG
                    actImg = (Bitmap)img.Clone();
#endif
                    img = gf.Apply(img);
                    var stats = new ImageStatistics(img);
                    mf.ApplyInPlace(img);
                    mf = new GaussianBlur(0.7, 7);
                    mf.ApplyInPlace(img);
                    var tf = new Threshold((int)(stats.GrayWithoutBlack.Mean + stats.GrayWithoutBlack.StdDev * 2.0));
                    tf.ApplyInPlace(img);
                    img.Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.MemoryBmp);
                    var blobCounter = new BlobCounter
                    {
                        ObjectsOrder         = ObjectsOrder.YX,
                        MaxHeight            = 30,
                        MinHeight            = 10,
                        MaxWidth             = 30,
                        MinWidth             = 10,
                        FilterBlobs          = true,
                        CoupledSizeFiltering = false
                    };
                    blobCounter.ProcessImage(img);
                    if (ProcessBlobs(blobCounter))
                    {
                        _calibrationStep++;
                    }
                    else
                    {
                        _errors++;
                    }
#if DEBUG
                    actImg.Save(@"C:\temp\daforge\squares\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg);
#endif
                    DrawMarkers();
                }
                else
                {
                    switch (_calibrationStep)
                    {
                    case 2:
                        var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap);
                        //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg);
                        bm = diffFilter.Apply(bm);
                        var gf = new GaussianBlur(0.8, 5);
                        gf.ApplyInPlace(bm);
                        var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255),
                                                    new IntRange(20, 255));
                        cf.ApplyInPlace(bm);
                        var blobCounter = new BlobCounter
                        {
                            ObjectsOrder = ObjectsOrder.Size,
                            MinHeight    = 200,
                            MinWidth     = 300,
                            //BackgroundThreshold = Color.FromArgb(255, 20, 20, 50),
                            //CoupledSizeFiltering = false,
                            FilterBlobs = true
                        };
                        blobCounter.ProcessImage(bm);
                        bm.ToManagedImage()
                        .Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg",
                              ImageFormat.Jpeg);
                        var blobs = blobCounter.GetObjectsInformation();
                        if (blobs.Any())
                        {
                            int             i = 0;
                            List <IntPoint> corners;
                            do
                            {
                                corners =
                                    PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++]));
                            } while (corners.Count != 4);
                            RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners);
                            Grid.TopLeft     = new Point(corners[0].X, corners[0].Y);
                            Grid.TopRight    = new Point(corners[1].X, corners[1].Y);
                            Grid.BottomLeft  = new Point(corners[2].X, corners[2].Y);
                            Grid.BottomRight = new Point(corners[3].X, corners[3].Y);
                            if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 &&
                                Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 &&
                                Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 &&
                                Grid.TopLeft.X < Grid.BottomRight.X &&
                                Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X &&
                                Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y &&
                                Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y)
                            {
                                _calibrationStep++;
                                _vs.Clear();
                                Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y));
                                Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y));
                                Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y));
                                Grid.AddPoint(new Point(_vs.Width, _vs.Height),
                                              new Point(corners[3].X, corners[3].Y));
                                DrawMarkers();
                            }
                            else
                            {
                                _calibrationStep = 0;
                                _errors++;
                            }
                        }
                        else
                        {
                            _calibrationStep = 0;
                            _errors++;
                        }
                        break;

                    case 1:
                        diffFilter.OverlayImage = e.Frame.Bitmap;
                        //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg);
                        //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255));
                        _vs.Clear();
                        DrawInverted(0, 0, _vs.Width, _vs.Height);
                        _vs.Draw();
                        _calibrationStep++;
                        break;

                    case 0:
                        Grid            = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height);
                        Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height);
                        var thread = new Thread(() =>
                        {
                            _vs.Show();
                        });
                        thread.SetApartmentState(ApartmentState.STA);
                        thread.Start();
                        thread.Join();
                        DrawBackground();
                        _vs.Draw();
                        _calibrationStep++;
                        break;
                    }
                }
            }
            Debug.WriteLine("Releasing");
            await Task.Delay(500);

            _sem.Release();
        }
Example #8
0
        // Set image to display by the control
        public int SetImage(Bitmap image)
        {
            leftEdges.Clear();
            rightEdges.Clear();
            topEdges.Clear();
            bottomEdges.Clear();
            hulls.Clear();
            quadrilaterals.Clear();

            this.image  = global::AForge.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb);
            imageWidth  = this.image.PixelWidth;
            imageHeight = this.image.PixelHeight;

#if !SILVERLIGHT && !UNITY_WEBPLAYER
            selectedBlobID = 0;

            blobCounter.ProcessImage(this.image);
            blobs = blobCounter.GetObjectsInformation();

            GrahamConvexHull grahamScan = new GrahamConvexHull();

            foreach (Blob blob in blobs)
            {
                List <IntPoint> leftEdge   = new List <IntPoint>();
                List <IntPoint> rightEdge  = new List <IntPoint>();
                List <IntPoint> topEdge    = new List <IntPoint>();
                List <IntPoint> bottomEdge = new List <IntPoint>();

                // collect edge points
                blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge);
                blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge);

                leftEdges.Add(blob.ID, leftEdge);
                rightEdges.Add(blob.ID, rightEdge);
                topEdges.Add(blob.ID, topEdge);
                bottomEdges.Add(blob.ID, bottomEdge);

                // find convex hull
                List <IntPoint> edgePoints = new List <IntPoint>();
                edgePoints.AddRange(leftEdge);
                edgePoints.AddRange(rightEdge);

                List <IntPoint> hull = grahamScan.FindHull(edgePoints);
                hulls.Add(blob.ID, hull);

                List <IntPoint> quadrilateral = null;

                // find quadrilateral
                if (hull.Count < 4)
                {
                    quadrilateral = new List <IntPoint>(hull);
                }
                else
                {
                    quadrilateral = PointsCloud.FindQuadrilateralCorners(hull);
                }
                quadrilaterals.Add(blob.ID, quadrilateral);

                // shift all points for vizualization
                IntPoint shift = new IntPoint(1, 1);

                PointsCloud.Shift(leftEdge, shift);
                PointsCloud.Shift(rightEdge, shift);
                PointsCloud.Shift(topEdge, shift);
                PointsCloud.Shift(bottomEdge, shift);
                PointsCloud.Shift(hull, shift);
                PointsCloud.Shift(quadrilateral, shift);
            }
#endif

            UpdateDrawOffset();

            Refresh();// Invalidate();

            return
                (#if SILVERLIGHT || UNITY_WEBPLAYER
                 0);
#else
                 blobs.Length;
#endif
        }
        /// <summary>
        /// Given the Window UI Screenshot, tries to detect all the buttons in it and returns all of them.
        /// </summary>
        /// <param name="res">Where to put candidate controls</param>
        /// <param name="bitmap">Bitmap containing the pixels of the UI to analyze</param>
        /// <param name="shouldInvert">If true, the bitmap will be inverted before analysis</param>
        /// <param name="minWidth">Minimum width of patterns to recognize</param>
        /// <param name="minHeight">Minimum height of patterns to recognize</param>
        /// <returns>void</returns>
        private void ScanWithVisualRecognition(ref CandidateSet res, Bitmap original, bool shouldInvert, int minWidth, int minHeight, Window w, IRankingPolicy policy)
        {
            // Setup the Blob counter
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.BackgroundThreshold  = Color.FromArgb(10, 10, 10);
            blobCounter.FilterBlobs          = true;
            blobCounter.CoupledSizeFiltering = false;
            blobCounter.MinHeight            = minHeight;
            blobCounter.MinWidth             = minWidth;

            List <Blob> blobs = new List <Blob>();

            // Button scanning
            // Apply the grayscale. This is needed for AForge's filters
            using (Bitmap grey_scaled = Grayscale.CommonAlgorithms.BT709.Apply(original))
            {
                // Invert the image if requested
                if (shouldInvert)
                {
                    Invert invert = new Invert();
                    invert.ApplyInPlace(grey_scaled);
                }

                //grey_scaled.Save("C:\\users\\alberto geniola\\desktop\\dbg\\gray_scaled_" + toinvert + ".bmp");

                using (Bitmap t1 = new Threshold(64).Apply(grey_scaled))
                {
                    using (var tmp = new Bitmap(t1.Width, t1.Height))
                    {
                        using (Graphics g = Graphics.FromImage(tmp))
                        {
                            g.DrawImage(t1, 0, 0);
                        }

                        // The blob counter will analyze the bitmap looking for shapes
                        blobCounter.ProcessImage(tmp);
                        var tmparr = blobCounter.GetObjectsInformation();
                        blobs.AddRange(tmparr);
                    }
                }

                using (Bitmap t2 = new SISThreshold().Apply(grey_scaled))
                {
                    using (var tmp = new Bitmap(t2.Width, t2.Height))
                    {
                        using (Graphics g = Graphics.FromImage(tmp))
                        {
                            g.DrawImage(t2, 0, 0);
                        }
                        //tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t2_" + toinvert + ".bmp");
                        // The blob counter will analyze the bitmap looking for shapes
                        blobCounter.ProcessImage(tmp);
                        var tmparr = blobCounter.GetObjectsInformation();
                        blobs.AddRange(tmparr);
                    }
                }
            }

            // Let's analyze every single shape
            for (int i = 0, n = blobs.Count; i < n; i++)
            {
                List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                if (edgePoints.Count > 1)
                {
                    IntPoint p0, p1;
                    PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1);
                    var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y);

                    // Skip any shape representing the border of the whole window ( +10px padding)
                    if (r.Width >= (original.Width - 10))
                    {
                        continue;
                    }

                    // This is most-likely a button!
                    // Crop the image and pass it to the OCR engine for text recognition
                    using (Bitmap button = new Bitmap(r.Width, r.Height))
                    {
                        // Scan the original shape
                        String txt = null;
                        using (var g1 = Graphics.FromImage(button))
                        {
                            g1.DrawImage(original, 0, 0, r, GraphicsUnit.Pixel);
                        }

                        // Process OCR on that image
                        txt = scanButton(button);

                        if (String.IsNullOrEmpty(txt))
                        {
                            using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button))
                            {
                                if (shouldInvert)
                                {
                                    new Invert().ApplyInPlace(tmp);
                                }

                                new SISThreshold().ApplyInPlace(tmp);
                                txt = scanButton(tmp);
                            }
                        }

                        // If still nothing is found, repeat the analysis with the second version of the filter
                        if (String.IsNullOrEmpty(txt))
                        {
                            using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button))
                            {
                                if (shouldInvert)
                                {
                                    new Invert().ApplyInPlace(tmp);
                                }
                                new Threshold(64).ApplyInPlace(tmp);
                                txt = scanButton(tmp);
                            }
                        }

                        // At this point we should have a result. Add it to list if it does not overlap any UIAutomated element
                        UIControlCandidate t = new UIControlCandidate();
                        t.PositionWindowRelative = r;
                        var winLoc = w.WindowLocation;
                        t.PositionScreenRelative = new Rectangle(r.X + winLoc.X, r.Y + winLoc.Y, r.Width, r.Height);
                        t.Text  = txt;
                        t.Score = policy.RankElement(t);

                        // If the item falls into the same area of a UI element, ignore it.
                        bool overlaps = false;
                        foreach (var el in res)
                        {
                            if (el.AutoElementRef != null && el.PositionScreenRelative.IntersectsWith(t.PositionScreenRelative))
                            {
                                overlaps = true;
                                break;
                            }
                        }
                        if (!overlaps)
                        {
                            res.Add(t);
                        }
                    }
                }
            }
        }
Example #10
0
        public void GetBlobs(string input, string output)
        {
            // process binary image
            Bitmap image = new Bitmap(input);

            // lock image
            BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);

            // step 1 - turn background to black
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red              = new IntRange(0, 64);
            colorFilter.Green            = new IntRange(0, 64);
            colorFilter.Blue             = new IntRange(0, 64);
            colorFilter.FillOutsideRange = false;
            colorFilter.ApplyInPlace(bitmapData);

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight   = 5;
            blobCounter.MinWidth    = 5;

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            image.UnlockBits(bitmapData);

            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            Graphics           g            = Graphics.FromImage(image);
            Pen redPen    = new Pen(Color.Red, 2);
            Pen yellowPen = new Pen(Color.Yellow, 2);
            Pen greenPen  = new Pen(Color.Green, 2);
            Pen bluePen   = new Pen(Color.Blue, 2);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List <IntPoint> edgePoints =
                    blobCounter.GetBlobsEdgePoints(blobs[i]);

                Accord.Point center;
                float        radius;

                if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    g.DrawEllipse(yellowPen,
                                  (float)(center.X - radius), (float)(center.Y - radius),
                                  (float)(radius * 2), (float)(radius * 2));
                }
                else
                {
                    List <IntPoint> corners;

                    if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                    {
                        if (shapeChecker.CheckPolygonSubType(corners) ==
                            PolygonSubType.Rectangle)
                        {
                            g.DrawPolygon(greenPen, ToPointsArray(corners));
                        }
                        else
                        {
                            g.DrawPolygon(bluePen, ToPointsArray(corners));
                        }
                    }
                    else
                    {
                        corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
                        g.DrawPolygon(redPen, ToPointsArray(corners));
                    }
                }
            }

            redPen.Dispose();
            greenPen.Dispose();
            bluePen.Dispose();
            yellowPen.Dispose();
            g.Dispose();

            // step 4 - save the image
            image.Save(output);
        }
Example #11
0
        /// <summary>
        /// Detects and recognizes cards from source image
        /// </summary>
        /// <param name="source">Source image to be scanned</param>
        /// <returns>Recognized Cards</returns>
        public CardCollection Recognize(Bitmap source)
        {
            var            height       = ((double)source.Height / (double)source.Width * 640d);
            ResizeBilinear ImageResizer = new ResizeBilinear(640, (int)height);

            source = ImageResizer.Apply(source);
            CardCollection collection = new CardCollection();     //Collection that will hold cards
            Bitmap         temp       = source.Clone() as Bitmap; //Clone image to keep original image

            FiltersSequence seq = new FiltersSequence();

            seq.Add(Grayscale.CommonAlgorithms.BT709); //First add  grayScaling filter
            seq.Add(new OtsuThreshold());              //Then add binarization(thresholding) filter
            temp = seq.Apply(source);                  // Apply filters on source image


            //Extract blobs from image whose size width and height larger than 150
            BlobCounter extractor = new BlobCounter();

            extractor.FilterBlobs = true;
            extractor.MinWidth    = extractor.MinHeight = 150;
            extractor.MaxWidth    = extractor.MaxHeight = 350;
            extractor.ProcessImage(temp);

            //Will be used transform(extract) cards on source image
            QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation();

            //Will be used resize(scaling) cards
            ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight);

            var Blobs = extractor.GetObjectsInformation();

            foreach (Blob blob in Blobs)
            {
                //Get Edge points of card
                List <IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob);
                //Calculate/Find corners of card on source image from edge points
                List <IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);

                quadTransformer.SourceQuadrilateral     = corners; //Set corners for transforming card
                quadTransformer.AutomaticSizeCalculaton = true;

                Bitmap cardImg = quadTransformer.Apply(source);          //Extract(transform) card image

                if (cardImg.Width > cardImg.Height)                      //If card is positioned horizontally
                {
                    cardImg.RotateFlip(RotateFlipType.Rotate90FlipNone); //Rotate
                }
                cardImg = resizer.Apply(cardImg);                        //Normalize card size

                Card card = new Card(cardImg, corners.ToArray());        //Create Card Object
                char color;
                try
                {
                    color = ScanColor(card.GetTopLeftPart()); //Scan color
                }
                catch (Exception ex)
                {
                    continue;
                }
                bool faceCard = IsFaceCard(cardImg); //Determine type of card(face or not)

                if (!faceCard)
                {
                    card.Suit = ScanSuit(cardImg, color); //Scan Suit of non-face card
                    card.Rank = ScanRank(cardImg);        //Scan Rank of non-face card
                }
                else
                {
                    Bitmap topLeft = card.GetTopLeftPart();
                    seq.Clear();
                    seq.Add(Grayscale.CommonAlgorithms.BT709);
                    seq.Add(new BradleyLocalThresholding());
                    topLeft = seq.Apply(topLeft);
                    BlobsFiltering bFilter = new BlobsFiltering(5, 5, 150, 150);
                    bFilter.ApplyInPlace(topLeft); //Filter blobs that can not be a suit

                    // topLeft.Save("topleft.bmp", ImageFormat.Bmp);

                    card.Suit = ScanFaceSuit(topLeft, color); //Scan suit of face card
                    card.Rank = ScanFaceRank(topLeft);        //Scan rank of face card
                }
                collection.Add(card);                         //Add card to collection
            }
            return(collection);
        }
Example #12
0
        /// <summary>
        /// Scans dominant color on image and returns it.
        /// Crops rank part on image and analyzes suit part on image
        /// </summary>
        /// <param name="bmp">Bitmap to be scanned</param>
        /// <returns>Returns 'B' for black , 'R' for red</returns>
        private char ScanColor(Bitmap bmp)
        {
            System.Diagnostics.Debug.Flush();
            System.Diagnostics.Debug.Print("I'm here");
            char color = 'B';
            //Crop rank part


            Crop crop = new Crop(new Rectangle(0, bmp.Height / 2, bmp.Width, bmp.Height / 2));

            bmp = crop.Apply(bmp);
            Bitmap temp = commonSeq.Apply(bmp); //Apply filters

            //Find suit blob on image
            BlobCounter counter = new BlobCounter();

            counter.ProcessImage(temp);
            Blob[] blobs = counter.GetObjectsInformation();

            if (blobs.Length > 0) //If blobs found
            {
                Blob max = blobs[0];
                //Find blob whose size is biggest
                foreach (Blob blob in blobs)
                {
                    if (blob.Rectangle.Height > max.Rectangle.Height)
                    {
                        max = blob;
                    }
                    else if (blob.Rectangle.Height == max.Rectangle.Height)
                    {
                        max = blob.Rectangle.Width > max.Rectangle.Width ? blob : max;
                    }
                }

                QuadrilateralTransformation trans = new QuadrilateralTransformation();
                trans.SourceQuadrilateral = PointsCloud.FindQuadrilateralCorners(counter.GetBlobsEdgePoints(max));
                bmp = trans.Apply(bmp); //Extract suit
            }
            //Lock Bits for processing
            BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                                ImageLockMode.ReadOnly, bmp.PixelFormat);
            int totalRed   = 0;
            int totalBlack = 0;

            unsafe
            {
                //Count red and black pixels
                try
                {
                    UnmanagedImage img = new UnmanagedImage(imageData);

                    int   height    = img.Height;
                    int   width     = img.Width;
                    int   pixelSize = (img.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
                    byte *p         = (byte *)img.ImageData.ToPointer();

                    // for each line
                    for (int y = 0; y < height; y++)
                    {
                        // for each pixel
                        for (int x = 0; x < width; x++, p += pixelSize)
                        {
                            int r = (int)p[RGB.R];                     //Red pixel value
                            int g = (int)p[RGB.G];                     //Green pixel value
                            int b = (int)p[RGB.B];                     //Blue pixel value

                            if (r > g + b)                             //If red component is bigger then total of green and blue component
                            {
                                totalRed++;                            //then its red
                            }
                            else if (r <= g + b && (r < 50 && g < 50)) //If all components less 70
                            {
                                totalBlack++;                          //then its black
                            }
                        }
                    }
                }
                finally
                {
                    bmp.UnlockBits(imageData); //Unlock
                }
            }



            if (totalRed > totalBlack) //If red is dominant
            {
                color = 'R';           //Set color as Red
            }
            return(color);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(pictureBox1.Image);
            Bitmap bmpsobe;
            Bitmap bmpmedian;
            Bitmap otsu;

            if (pictureBox1.Image == null)
            {
                MessageBox.Show("Lütfen önce bir resim Seçin");
            }
            else
            {
                progressBar1.Visible = true;
                int   i, j;
                Color ort;//Color sınıfından bir renk nesne tanımlıyoruz.

                //int r,g,b;
                progressBar1.Maximum = bmp.Width * bmp.Height; //İşlem çubuğunun maksimim olduğu yer for döngüsünün sonundaki piksel değerine erişmemiz durumundadır.
                for (i = 0; i <= bmp.Width - 1; i++)           //dikey olarak görüntümüzü tarıyoruz.
                {
                    for (j = 0; j <= bmp.Height - 1; j++)      //yatay olarak görüntümüzü tarıyoruz.
                    {
                        ort = bmp.GetPixel(i, j);
                        ort = Color.FromArgb((byte)((ort.R + ort.G + ort.B) / 3), (byte)((ort.R + ort.G + ort.B) / 3), (byte)((ort.R + ort.G + ort.B) / 3));
                        bmp.SetPixel(i, j, ort);
                        if ((i % 10) == 0)//her on satırda bir göstergeyi güncelle
                        {
                            progressBar1.Value = i * bmp.Height + j;
                            Application.DoEvents();
                        }
                    }
                }
            }
            //////////////////////// Median //////////////

            bmpmedian = ExtBitmap.MedianFilter(bmp, 3);

            /////////////////////// SOBEL ///////////////

            bmpsobe = ExtBitmap.Sobel3x3Filter(bmpmedian, true);
            Bitmap bmpsobe1 = (Bitmap)bmpsobe.Clone();

            /////////// otsu
            int x, y;
            int genislik  = bmpsobe1.Width;
            int yukseklik = bmpsobe1.Height;

            byte[] pixeller = new byte[(int)genislik * yukseklik];
            Bitmap resim    = (Bitmap)bmpsobe1.Clone();

            for (y = 0; y < yukseklik; y++)
            {
                for (x = 0; x < genislik; x++)
                {
                    // Pixelleri kütüphanenin işleyebileceği tek boyutlu bir diziye atıyoruz.
                    // Gri seviyede tüm ana renkler eşit olduğu için sadece kırmızıyı okumak gri seviye için yeterli.
                    pixeller[y * genislik + x] = resim.GetPixel(x, y).R;
                }
            }

            byte esikDeger = 0;

            OtsuEsikleme(ref pixeller[0], ref esikDeger, genislik, yukseklik);
            int renkk;

            for (y = 0; y < yukseklik; y++)
            {
                for (x = 0; x < genislik; x++)
                {
                    renkk = pixeller[y * genislik + x];                        // gri
                    resim.SetPixel(x, y, Color.FromArgb(renkk, renkk, renkk)); // Gri seviyeyi argb moduna dönüştürüp resme aktarıyoruz.
                }
            }

            otsu = (Bitmap)resim.Clone();
            Bitmap bmperosion;
            Bitmap bmpdilation;
            Bitmap bmpclosing;


            bmperosion = ExtBitmap.DilateAndErodeFilter(otsu, 3, akıllıgecissistemleri.ExtBitmap.MorphologyType.Erosion, true, true, true);
            Bitmap bmperosionn = (Bitmap)bmperosion.Clone();

            bmpdilation = ExtBitmap.DilateAndErodeFilter(bmperosionn, 7, akıllıgecissistemleri.ExtBitmap.MorphologyType.Dilation, true, true, true);
            Bitmap bmpdilationn = (Bitmap)bmpdilation.Clone();

            Bitmap         one     = (Bitmap)bmpdilationn.Clone();
            BlobsFiltering filter0 = new BlobsFiltering();

            // filtre ayarlaması
            filter0.CoupledSizeFiltering = true;
            filter0.MinWidth             = 70;
            filter0.MinHeight            = 40;
            // filtre uygula
            filter0.ApplyInPlace(one);


            Bitmap one2 = (Bitmap)one.Clone();

            bmpclosing = ExtBitmap.CloseMorphologyFilter(one2, 15, true, true, true);
            Bitmap bmperosio = (Bitmap)bmpclosing.Clone();

            Bitmap bmperosionson = ExtBitmap.DilateAndErodeFilter(bmperosio, 9, akıllıgecissistemleri.ExtBitmap.MorphologyType.Erosion, true, true, true);
            Bitmap blobson       = (Bitmap)bmperosionson.Clone();

            BlobsFiltering filterson = new BlobsFiltering();

            // filtre ayarla
            filterson.CoupledSizeFiltering = true;
            filterson.MinWidth             = 50;
            filterson.MinHeight            = 200;
            // filtre uygula

            filterson.ApplyInPlace(blobson);
            Bitmap rect = (Bitmap)blobson.Clone();

            Bitmap one1 = (Bitmap)rect.Clone();

            ConnectedComponentsLabeling filter = new ConnectedComponentsLabeling();
            // filtre uygula
            Bitmap newImage  = filter.Apply(one1);
            Bitmap newImage1 = (Bitmap)newImage.Clone();
            // obje sayısını kontrol et
            int objectCount = filter.ObjectCount;

            BlobCounter blobCounter = new BlobCounter();

            blobCounter.ProcessImage(rect);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            // Görüntüye çizmek için Graphic nesnesi ve bir kalem oluştur
            Graphics g       = Graphics.FromImage(rect);
            Pen      bluePen = new Pen(Color.Blue, 2);

            // her nesne kpntrol edilir ve etrafında daire çizilir.

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                /*
                 * x1=0
                 * x2=1
                 * y1=2
                 * y2=3
                 */
                List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List <IntPoint> corners    = PointsCloud.FindQuadrilateralCorners(edgePoints);
                int[]           sinirlar   = sinir(corners);
                sinirlar[0] = sinirlar[0] - 2;
                sinirlar[1] = sinirlar[1] + 2;
                sinirlar[2] = sinirlar[2] - 2;
                sinirlar[3] = sinirlar[3] + 2;
                int   en  = sinirlar[1] - sinirlar[0];
                int   boy = sinirlar[3] - sinirlar[2];
                float ort = (float)en / (float)boy;

                List <IntPoint> ucnoktalar = new List <IntPoint>();
                ucnoktalar.Add(new IntPoint(sinirlar[0], sinirlar[2]));
                ucnoktalar.Add(new IntPoint(sinirlar[1], sinirlar[2]));
                ucnoktalar.Add(new IntPoint(sinirlar[1], sinirlar[3]));
                ucnoktalar.Add(new IntPoint(sinirlar[0], sinirlar[3]));
                g.DrawPolygon(bluePen, ToPointsArray(ucnoktalar));
                g.DrawString("Plaka kordinatlari : (x,y): (" + sinirlar[0].ToString() + "," + sinirlar[2].ToString() + ")\n en, boy,ort: " + (sinirlar[1] - sinirlar[0]).ToString() + ", "
                             + (sinirlar[3] - sinirlar[2]).ToString() + "," + ort.ToString() + " blob sayisi:" + blobs.Length.ToString(), new Font("Arial", 8), Brushes.White, new System.Drawing.Point(sinirlar[0], sinirlar[3] + 4));
            }

            bluePen.Dispose();
            g.Dispose();


            Bitmap   rect1    = (Bitmap)pictureBox1.Image.Clone();
            Graphics g1       = Graphics.FromImage(rect1);
            Pen      bluePen2 = new Pen(Color.Red, 2);
            // her nesne kpntrol edilir ve etrafında daire çizilir.

            List <Blob> bloplar = new List <Blob>();

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                /*              x1,y1--------x2,y1
                 * x1=0           |            |
                 * x2=1           |            |
                 * y1=2         x1,y2--------x2,y2
                 * y2=3
                 */
                List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List <IntPoint> corners    = PointsCloud.FindQuadrilateralCorners(edgePoints);
                int[]           sinirlar   = sinir(corners);
                sinirlar[0] = sinirlar[0] - 5;
                sinirlar[1] = sinirlar[1];
                sinirlar[2] = sinirlar[2] - 5;
                sinirlar[3] = sinirlar[3] + 5;
                int   en  = sinirlar[1] - sinirlar[0];
                int   boy = sinirlar[3] - sinirlar[2];
                float ort = (float)en / (float)boy;
                if (ort >= 3 && ort <= 5.7)
                {
                    g1.DrawLines(bluePen2, new System.Drawing.Point[] { new System.Drawing.Point(sinirlar[0], sinirlar[2]),
                                                                        new System.Drawing.Point(sinirlar[1], sinirlar[2]), new System.Drawing.Point(sinirlar[1], sinirlar[3]),
                                                                        new System.Drawing.Point(sinirlar[0], sinirlar[3]), new System.Drawing.Point(sinirlar[0], sinirlar[2]) });

                    g1.DrawString("Plaka kordinatlari : (x,y): (" + sinirlar[0].ToString() + "," + sinirlar[2].ToString() + ")\n en, boy,ort: " + (sinirlar[1] - sinirlar[0]).ToString() + ", "
                                  + (sinirlar[3] - sinirlar[2]).ToString() + "," + ort.ToString() + " blob sayisi:" + blobs.Length.ToString(), new Font("Arial", 8), Brushes.White, new System.Drawing.Point(sinirlar[0], sinirlar[3] + 4));
                }
            }

            bluePen2.Dispose();
            g1.Dispose();


            Bitmap   bn       = null;
            Bitmap   kes1     = (Bitmap)rect1.Clone();
            Graphics g2       = Graphics.FromImage(kes1);
            Pen      bluePen3 = new Pen(Color.Red, 2);

            // her nesne kpntrol edilir ve etrafında daire çizilir.

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                /*              x1,y1--------x2,y1
                 * x1=0           |            |
                 * x2=1           |            |
                 * y1=2         x1,y2--------x2,y2
                 * y2=3
                 */
                List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List <IntPoint> corners    = PointsCloud.FindQuadrilateralCorners(edgePoints);
                int[]           sinirlar   = sinir(corners);
                sinirlar[0] = sinirlar[0] - 5;
                sinirlar[1] = sinirlar[1];
                sinirlar[2] = sinirlar[2] - 5;
                sinirlar[3] = sinirlar[3] + 5;

                int   en  = sinirlar[1] - sinirlar[0];
                int   boy = sinirlar[3] - sinirlar[2];
                float ort = en / boy;
                if (ort >= 3 && ort <= 5.7)
                {
                    g2.DrawLines(bluePen3, new System.Drawing.Point[] { new System.Drawing.Point(sinirlar[0], sinirlar[2]),
                                                                        new System.Drawing.Point(sinirlar[1], sinirlar[2]), new System.Drawing.Point(sinirlar[1], sinirlar[3]),
                                                                        new System.Drawing.Point(sinirlar[0], sinirlar[3]), new System.Drawing.Point(sinirlar[0], sinirlar[2]) });

                    for (int ii = 0; ii < kes1.Width; ii++)
                    {
                        for (int ji = 0; ji < kes1.Height; ji++)
                        {
                            if ((ii >= sinirlar[0] && ii <= sinirlar[1]) && (ji >= sinirlar[2]) && ji <= sinirlar[3])
                            {
                                continue;
                            }
                            else
                            {
                                kes1.SetPixel(ii, ji, Color.Black);
                            }
                        }
                    }
                    bn = new Bitmap(en, boy);
                    Graphics g3 = Graphics.FromImage(bn);
                    g3.DrawImage(kes1, -sinirlar[0], -sinirlar[2]);
                    pictureBox2.Image = bn;
                }
            }

            bluePen3.Dispose();
            g2.Dispose();



            //form(bmp, "Grayscala");
            //form(bmpmedian, "Median");
            //form(bmpsobe, "sobel");
            //form(otsu, "otsu");
            //form(bmperosion, "erosion");
            //form(bmpdilationn, "dilation");
            //form(one, "one");
            //form(bmpclosing, "closing");
            //form(bmperosionson, "son");
            //form(blobson, "blobson");
            //form(newImage, "one1");
            //form(rect, "rect");
            //form(rect1, "rect1");
            //form(kes1, "kes1");
            //form(bn, "bn");
        }
        private ImageSource ProcessImageSourceForBitmap(Bitmap bmp)
        {
            BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);

            EuclideanColorFiltering filter = new EuclideanColorFiltering();

            filter.CenterColor = new RGB(byte.Parse(redTextBox.Text), byte.Parse(greenTextBox.Text), byte.Parse(blueTextBox.Text));
            filter.Radius      = short.Parse(radiusTextBox.Text);
            filter.ApplyInPlace(bitmapData);

            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight   = 15;
            blobCounter.MinWidth    = 15;
            blobCounter.MaxHeight   = bitmapData.Width - 1;
            blobCounter.MaxWidth    = bitmapData.Width - 1;

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bmp.UnlockBits(bitmapData);

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            Graphics g = Graphics.FromImage(bmp);

            System.Drawing.Pen redPen    = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
            System.Drawing.Pen yellowPen = new System.Drawing.Pen(System.Drawing.Color.Yellow, 5);
            System.Drawing.Pen greenPen  = new System.Drawing.Pen(System.Drawing.Color.Green, 5);
            System.Drawing.Pen bluePen   = new System.Drawing.Pen(System.Drawing.Color.Blue, 5);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List <IntPoint> edgePoints =
                    blobCounter.GetBlobsEdgePoints(blobs[i]);

                AForge.Point center;
                float        radius;

                if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    g.DrawEllipse(yellowPen,
                                  (float)(center.X - radius), (float)(center.Y - radius),
                                  (float)(radius * 2), (float)(radius * 2));
                }
                else
                {
                    List <IntPoint> corners;

                    if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                    {
                        if (shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Rectangle)
                        {
                            g.DrawPolygon(greenPen, ToPointsArray(corners));
                        }
                        else
                        {
                            g.DrawPolygon(bluePen, ToPointsArray(corners));
                        }
                    }
                    else
                    {
                        corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
                        g.DrawPolygon(redPen, ToPointsArray(corners));
                    }
                }
            }

            redPen.Dispose();
            greenPen.Dispose();
            bluePen.Dispose();
            yellowPen.Dispose();
            g.Dispose();

            var handle = bmp.GetHbitmap();

            try
            {
                return(Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));
            }
            finally { DeleteObject(handle); }
        }
        /* Odświezanie okna z obrazem */
        void RefreshWindow(object sender, EventArgs arg)
        {
            //Pobieranie ramki
            image           = capture.QueryFrame();
            image           = image.Flip(FLIP.HORIZONTAL);
            imageBox1.Image = image;

            //YCbCr or Bgr(RGB)
            //Warto zwrócić uwagę na to że Ycc to Y,Cr,Cb a nie Y,Cb,Cr, oraz Bgr to Blue,Green,Red
            if (radioButton1.Checked)
            {
                imageGray = image.Resize((double)nupScale.Value, INTER.CV_INTER_CUBIC).Convert <Ycc, Byte>().
                            InRange(new Ycc((double)nudW1.Value, (double)nudW3.Value, (double)nudW2.Value), new Ycc((double)nudW4.Value, (double)nudW6.Value, (double)nudW5.Value));
            }
            else
            {
                imageGray = image.InRange(new Bgr((double)nudW3.Value, (double)nudW2.Value, (double)nudW1.Value), new Bgr((double)nudW6.Value, (double)nudW5.Value, (double)nudW4.Value));
            }

            if (medianCB.Checked)
            {
                imageGray = imageGray.SmoothMedian((int)nudMedian.Value);
            }

            //Image<Gray, Byte> sgm = new Image<Gray, Byte>(imageGray.Size);
            Bitmap bmp = imageGray.ToBitmap();

            bc.ProcessImage(bmp);

            Blob[] blob = bc.GetObjectsInformation();

            //one hand version
            //int iters = bc.ObjectsCount > 1 ? 1 : bc.ObjectsCount;
            int iters = bc.ObjectsCount > 2 ? 2 : bc.ObjectsCount;

            if (iters > 1)
            {
                //both hands version
                //lewa reka to ta z prawej strony obrazu (zwierciadlo), nie zakladamy ze user gestykuluje na krzyz, keep it simple
                blob = blob.Take(2).OrderByDescending(a => a.CenterOfGravity.X).ToArray <Blob>();
            }

            int centerOfGravityLHandX = 0, centerOfGravityLHandY = 0, centerOfGravityRHandX = 0, centerOfGravityRHandY = 0;

            string[] gestureLabel = new string[2];
            int      i = 0;

            for (; i < iters; ++i)
            {
                IntPoint minXY, maxXY;
                PointsCloud.GetBoundingRectangle(bc.GetBlobsEdgePoints(blob[i]), out minXY, out maxXY);
                Bitmap     clonimage = (Bitmap)bmp.Clone();
                BitmapData data      = bmp.LockBits(new Rectangle(0, 0, imageGray.Width, imageGray.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
                Drawing.Rectangle(data, blob[i].Rectangle, Color.White);
                bmp.UnlockBits(data);

                int X = maxXY.X, Y = maxXY.Y;
                int x = minXY.X, y = minXY.Y;

                observed[0, i] = blob[i].Fullness;

                /* malinowska kryjaka liczy obwod ze wzoru na prostokąt, nasza liczy piksele krawedziowe */
                //Malinowska(i) = (2*bb(3)+2*bb(4))/(2*sqrt(pi*S)) - 1;
                observed[2, i] = (double)(bc.GetBlobsEdgePoints(blob[i]).Count) / 2 / Math.Sqrt(Math.PI * blob[i].Area) - 1;
                //MalinowskaZ(i) = 2*sqrt(pi*S)/(2*bb(3)+2*bb(4));
                observed[3, i] = 2 * Math.Sqrt(Math.PI * blob[i].Area) / (double)(bc.GetBlobsEdgePoints(blob[i]).Count);

                int gx = (int)blob[i].CenterOfGravity.X, gy = (int)blob[i].CenterOfGravity.Y;

                //Sprawdzenie która ręka prawa, a która lewa
                if (gx > centerOfGravityRHandX)
                {
                    centerOfGravityLHandX = centerOfGravityRHandX;
                    centerOfGravityLHandY = centerOfGravityRHandY;
                    centerOfGravityRHandX = gx;
                    centerOfGravityRHandY = gy;
                }
                else
                {
                    centerOfGravityLHandX = gx;
                    centerOfGravityLHandY = gy;
                }

                double blairsum = 0;
                int    ftx = 0, ftxMax = 0;

                byte[, ,] dd = imageGray.Data;
                for (int j = y; j < Y; ++j)
                {
                    if (ftx > ftxMax)
                    {
                        ftxMax = ftx;
                    }
                    ftx = 0;//bo moze sie zdazyc ze zliczy wiecej linii naraz, patrz: idealny prostokat
                    for (int k = x; k < X; ++k)
                    {
                        if (dd[j, k, 0] != 0)
                        {
                            ++ftx;
                            blairsum += (k - gx) * (k - gx) + (j - gy) * (j - gy);//distance squared
                        }
                        else
                        {
                            if (ftx > ftxMax)
                            {
                                ftxMax = ftx;
                            }
                            ftx = 0;
                        }
                        dd[j, k, 0] = 255;
                    }
                }

                /*    aby policzyc ftyMax trzeba puscic jeszcze jedna petle tak aby wewnetrzna szla po y-kach
                 * ale mozna tez aproksymowac ftYmax przez boundingbox.Y, wtedy
                 * przewidywalem najwieksze rozbieznosci przy skosnych lub dziurawych obiektach;
                 * ale blad byl ponizej procenta, wiec szkoda tracic czas na kolejne O(n*n)
                 *
                 * int fty = 0, ftyMax = 0;
                 * for (int j = x; j < X; ++j) {
                 *  if (fty > ftyMax) ftyMax = fty;
                 *  fty = 0;
                 *  for (int i = y; i < Y; ++i)
                 *      if (dd[i, j, 0] != 0)
                 ++fty;
                 *      else {
                 *          if (fty > ftyMax) ftyMax = fty;
                 *          fty = 0;
                 *      }
                 * }
                 * feret = (double)ftxMax / ftyMax; */
                observed[4, i] = (double)ftxMax / (Y - y);                                   //feret
                observed[1, i] = (double)(blob[i].Area) / Math.Sqrt(2 * Math.PI * blairsum); //blair

                gestChance[GEST.SLAYER]    = dist(slayer, i);
                gestChance[GEST.THUMBLEFT] = dist(thumbleft, i);
                gestChance[GEST.THUMBUP]   = dist(thumbup, i);
                gestChance[GEST.SHAKA]     = dist(shaka, i);
                gestChance[GEST.FIST]      = dist(fist, i);
                gestChance[GEST.VICTORY]   = dist(victory, i);
                gestChance[GEST.VOPEN]     = dist(vopen, i);
                gestChance[GEST.HOPEN]     = dist(hopen, i);
                gestChance[GEST.FINGERS]   = dist(fingers, i);
                gestChance[GEST.SCISSORS]  = dist(scissors, i);

                //list fold - get key of minimal value
                KeyValuePair <GEST, double> elem = gestChance.Aggregate((l, r) => l.Value < r.Value ? l : r);
                found[i] = (elem.Value < TOLERANCE) ? elem.Key : GEST.BLANK;
                if (elem.Key == GEST.FIST && (double)(X - x) / (Y - y) < .6)
                {
                    found[i] = GEST.VOPEN;
                }
                gestureLabel[i] = labels[(int)found[i]];
            }

            g1value.Text = gestureLabel[1];
            g2value.Text = gestureLabel[0];

            compactnessLbl.Text = observed[0, 1].ToString(format);
            blairLbl.Text       = observed[1, 1].ToString(format);
            malinowskaLbl.Text  = observed[2, 1].ToString(format);
            malzmodLbl.Text     = observed[3, 1].ToString(format);
            feretLbl.Text       = observed[4, 1].ToString(format);

            comp2.Text  = observed[0, 0].ToString(format);
            blair2.Text = observed[1, 0].ToString(format);
            mal2.Text   = observed[2, 0].ToString(format);
            malz2.Text  = observed[3, 0].ToString(format);
            feret2.Text = observed[4, 0].ToString(format);

            /* for blobs not detected */
            for (; i < 2; ++i)
            {
                observed[0, i] = observed[1, i] = observed[2, i] = observed[3, i] = observed[4, i] = NOT_FOUND;
            }

            imageGray       = new Image <Gray, Byte>(bmp);
            imageGray       = imageGray.Erode((int)nudErode.Value);
            imageGray       = imageGray.Dilate((int)nudDilate.Value);
            imageBox2.Image = imageGray;

            //Zmiana pozycji myszki od środka ciężkości lewej ręki
            if (centerOfGravityLHandX * centerOfGravityLHandY != 0 && !blockMouseControl)
            {
                double smoothness   = (double)nudSmoothness.Value;
                double sensitivity  = (double)nudSensitivity.Value;
                int    newPositionX = screenWidth - (int)(centerOfGravityLHandX / (imageGray.Width * .2) * sensitivity * screenWidth); //- imageGray.Width*1/5
                int    newPositionY = (int)((centerOfGravityLHandY - imageGray.Height * .5) / (imageGray.Height * .25) * sensitivity * screenHeight);

                int diffX = Cursor.Position.X + newPositionX;
                int diffY = Cursor.Position.Y - newPositionY;

                newPositionX = Cursor.Position.X - (int)(diffX / smoothness);
                newPositionY = Cursor.Position.Y - (int)(diffY / smoothness);
                MouseSimulating.SetMousePosition(newPositionX, newPositionY);

                //Wyliczanie akcji do podjęcia
                if (found[1] == GEST.BLANK || prevGestureLeft != found[1])
                {
                    frameCounterLeft = 0;
                    prevGestureLeft  = found[1];
                }

                if (found[0] == GEST.BLANK || prevGestureRight != found[0])
                {
                    frameCounterRight = 0;
                    prevGestureRight  = found[0];
                }

                if (frameCounterLeft == 30) //ile klatek musi  - 30 kl/s
                {
                    if (prevGestureLeft == GEST.FIST)
                    {
                        MouseSimulating.PressLPM();
                    }
                    else if (prevGestureLeft == GEST.VOPEN)
                    {
                        MouseSimulating.ReleaseLPM();
                    }
                    frameCounterLeft = 0;
                }
                else
                {
                    frameCounterLeft++;
                }

                if (frameCounterRight == 30)
                {
                    if (prevGestureRight == GEST.FIST)
                    {
                        MouseSimulating.ClickLPM();
                    }
                    else if (prevGestureRight == GEST.SLAYER)
                    {
                        MouseSimulating.ScrollUP(200);
                    }
                    else if (prevGestureRight == GEST.VICTORY)
                    {
                        MouseSimulating.ScrollDOWN(200);
                    }
                    else if (prevGestureRight == GEST.FINGERS)
                    {
                        MouseSimulating.ClickPPM();
                    }
                    else if (prevGestureRight == GEST.THUMBUP)
                    {
                        KeyboardSimulating.SendCtrlC();
                    }
                    else if (prevGestureRight == GEST.THUMBLEFT)
                    {
                        KeyboardSimulating.SendCtrlV();
                    }
                    else if (prevGestureRight == GEST.SCISSORS)
                    {
                        KeyboardSimulating.SendCtrlX();
                    }
                    else if (prevGestureRight == GEST.HOPEN)
                    {
                        MouseSimulating.ClickLPM(); MouseSimulating.ClickLPM();
                    }
                    else if (prevGestureRight == GEST.SHAKA)
                    {
                        MouseSimulating.ClickMouseButton4();
                    }

                    frameCounterRight = 0;
                }
                else
                {
                    frameCounterRight++;
                }
            }
        }