Пример #1
0
    public void ApplyFilter(Mat src)
    {
        CvInvoke.CvtColor(src, src, ColorConversion.Bgr2Hsv);

        Mat threshold = new Mat(src.Height, src.Width, src.Depth, src.NumberOfChannels);
        MCvScalar min = new MCvScalar(m_hmin, m_smin, m_vmin);
        MCvScalar max = new MCvScalar(m_hmax, m_smax, m_vmax);

        CvInvoke.InRange(src, new ScalarArray(min), new ScalarArray(max), threshold);

        Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3,3), Point.Empty);
        CvInvoke.Erode(threshold, threshold, element, Point.Empty, 1, BorderType.Constant, new MCvScalar(1.0f));
        CvInvoke.Canny(threshold, threshold, 100, 255);

        VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
        Mat hierarchy = new Mat();

         CvInvoke.FindContours(threshold, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple, Point.Empty);

        Mat draw = new Mat(src.Height, src.Width, src.Depth, 1);
        draw.SetTo(new MCvScalar(0.0));
        int i = 0;

        //Debug.Log("CONTOURS");

        var contoursArray = contours.ToArrayOfArray();
        foreach(Point[] contour in contoursArray)
        {
            CvInvoke.DrawContours(draw, contours, i, new MCvScalar(255.0), 1, LineType.EightConnected, null, int.MaxValue, Point.Empty);

         	double a = CvInvoke.ContourArea(new VectorOfPoint(contour));
            //Debug.Log("Contour: " + a);
            i++;
        }

        //Emgu.CV.UI.ImageViewer.Show(draw, "test");

        if(m_onFrame != null) m_onFrame.Invoke(draw);
    }
        public void Process(string imagePath)
        {
            var im = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Grayscale);
            Mat imx = new Mat(), th = new Mat();

            CvInvoke.MedianBlur(im, imx, 3);

            CvInvoke.Resize(imx, th, new Size(50, 50), 0, 0, Inter.Area);
            CvInvoke.GaussianBlur(th, im, new Size(7, 7), 0);
            CvInvoke.Resize(im, th, imx.Size, 0, 0, Inter.Linear);
            CvInvoke.Compare(imx, th, im, CmpType.GreaterThan);

            var imrgb = new Mat(im.Rows, im.Cols, DepthType.Cv8U, 3);

            CvInvoke.CvtColor(im, imrgb, ColorConversion.Gray2Bgr);

            var contours = new Emgu.CV.Util.VectorOfVectorOfPoint();

            CvInvoke.FindContours(im, contours, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
            var ca = contours.ToArrayOfArray();

            var           cells = new List <Cell>();
            List <double> ca_aa = new List <double>(ca.Length);

            for (int i = 0; i < ca.Length; i++)
            {
                var c = new Cell(ca[i]);
                cells.Add(c);
                ca_aa.Add(c.sarea);
            }
            ca_aa.Sort();

            double ca_max = 0, ca_min = 0;

            for (int i = 100; i >= 0 && ca_aa[i] / ca_aa[i + 1] < 1.01; i--)
            {
                ca_max = -ca_aa[i];
            }

            for (int i = 100; i < ca_aa.Count && ca_aa[i] / ca_aa[i + 1] < 1.01; i++)
            {
                ca_min = -ca_aa[i];
            }

            double side_avg = Math.Sqrt((ca_min + ca_max) / 2);

            List <Cell> gridCells = new List <Cell>();

            for (int i = 0; i < ca.Length; i++)
            {
                var col = colors[i % colors.Count];
                var c   = cells[i];
                if (c.area > ca_max || c.area < ca_min)
                {
                    continue;
                }

                c.FindCenter();
                double minR = c.sidelength / 2.25;
                //CvInvoke.Circle(imrgb, c.cp, (int)minR, col, 1);
                bool ok    = true;
                var  minR2 = minR * minR;
                for (int j = 0; j < c.ca.Length; j++)
                {
                    if (c.Dist2(c.ca[j]) < minR2)
                    {
                        ok = false;
                    }
                }

                //for (int j = 1; j < c.ca.Length; j++)
                //    CvInvoke.Line(imrgb, c.ca[j - 1], c.ca[j], col, ok ? 9 : 3);

                if (ok)
                {
                    gridCells.Add(c);
                }
            }


            double maxCentDist2 = 2 * side_avg * side_avg;

            for (int i = 0; i < gridCells.Count; i++)
            {
                var a = gridCells[i];
                for (int j = 0; j < gridCells.Count; j++)
                {
                    var b = gridCells[j];
                    if (i == j)
                    {
                        continue;
                    }
                    if (a.Dist2(b) < maxCentDist2)
                    {
                        var      d   = a.Diff(b);
                        bool     isX = Math.Abs(d.X) > Math.Abs(d.Y);
                        Cell.Dir dir = isX ? d.X < 0 ? Cell.Dir.Left : Cell.Dir.Right : d.Y < 0 ? Cell.Dir.Up : Cell.Dir.Down;
                        a.Link(b, dir);

                        //CvInvoke.Line(imrgb, a.cp, b.cp, new MCvScalar(0, 255, isX ? 255 : 0), 3);
                    }
                }
            }

            Queue <Cell> qc = new Queue <Cell>();

            gridCells[0].SetGridIndex(new Point()); // Arbitrary Origo
            qc.Enqueue(gridCells[0]);
            while (qc.Count > 0)
            {
                var c = qc.Dequeue();
                foreach (var nc in c.neighbours)
                {
                    if (nc != null && !nc.hasGridIndex)
                    {
                        qc.Enqueue(nc);
                    }
                }
                c.CalcNeighboursGridIndex();
            }

            int gixr = (from c in gridCells select c.gi.X).Min();
            int giyr = (from c in gridCells select c.gi.Y).Min();

            foreach (var c in cells)
            {
                c.gi = new Point(c.gi.X - gixr, c.gi.Y - giyr);
            }
            gixr = (from c in gridCells select c.gi.X).Max() + 1;
            giyr = (from c in gridCells select c.gi.Y).Max() + 1;

            var gridEst = new GridEstimator();

            foreach (var c in gridCells)
            {
                gridEst.Add(c.gi, c.cpf);
            }

            gridEst.Process();
            for (int Xi = 0; Xi < gixr; Xi++)
            {
                Point p1 = gridEst.GetP(Xi + 0.5f, 0.5f);
                Point p2 = gridEst.GetP(Xi + 0.5f, giyr - 0.5f);
                CvInvoke.Line(imrgb, p1, p2, new MCvScalar(0, 100, 255), 5);
            }
            for (int Yi = 0; Yi < giyr; Yi++)
            {
                Point p1 = gridEst.GetP(0.5f, Yi + 0.5f);
                Point p2 = gridEst.GetP(gixr - 0.5f, Yi + 0.5f);
                CvInvoke.Line(imrgb, p1, p2, new MCvScalar(0, 100, 255), 5);
            }


            Cell[,] cg = new Cell[gixr, giyr];
            foreach (var c in gridCells)
            {
                cg[c.gi.X, c.gi.Y] = c;
            }

            for (int xi = 0; xi < gixr; xi++)
            {
                for (int yi = 0; yi < giyr; yi++)
                {
                    var c = cg[xi, yi];
                    if (c == null)
                    {
                        continue;
                    }
                    var    col  = colors[(xi + yi) % colors.Count];
                    double minR = c.sidelength / 2.25;
                    //CvInvoke.Circle(imrgb, c.cp, (int)minR, col, 4);
                }
            }

            var sidesize = (int)(side_avg * 0.8);

            for (int xi = 0; xi < gixr; xi++)
            {
                for (int yi = 0; yi < giyr; yi++)
                {
                    var c = cg[xi, yi];
                    if (c == null)
                    {
                        continue;
                    }
                    c.image  = c.ExtractImage(imx, sidesize);
                    c.imMask = c.ExtractImage(im, sidesize);
                }
            }

            List <float> diffs = new List <float>();

            for (int xi = 0; xi < gixr; xi++)
            {
                for (int yi = 0; yi < giyr; yi++)
                {
                    var c = cg[xi, yi];
                    if (c == null)
                    {
                        continue;
                    }
                    var t = cg[10, 10];
                    var r = c.Match(t);

                    diffs.Add(r);
                }
            }

            float diffMax = diffs.Max();

            Mat gridImage = new Mat(sidesize * giyr, sidesize * gixr, DepthType.Cv8U, 3);

            gridImage.SetTo(new MCvScalar(128, 128, 128));
            Mat gridMatchImage = new Mat(sidesize * giyr, sidesize * gixr, DepthType.Cv8U, 3);

            gridMatchImage.SetTo(new MCvScalar(128, 128, 128));

            var templateCell = cg[10, 10];

            for (int xi = 0; xi < gixr; xi++)
            {
                for (int yi = 0; yi < giyr; yi++)
                {
                    var c = cg[xi, yi];
                    if (c == null)
                    {
                        continue;
                    }
                    var r = c.Match(templateCell);

                    var imrgb2 = new Mat();
                    CvInvoke.CvtColor(c.image, imrgb2, ColorConversion.Gray2Bgr);
                    Mat w = new Mat(gridImage, new Rectangle(new Point(xi * sidesize, yi * sidesize), c.image.Size));
                    imrgb2.CopyTo(w);

                    w = new Mat(gridMatchImage, new Rectangle(new Point(xi * sidesize, yi * sidesize), c.image.Size));
                    int rr = (int)(r / diffMax * 255);
                    w.SetTo(new MCvScalar(0, 255 - rr, rr));
                    imrgb2.CopyTo(w, c.imMask);
                }
            }

            new Emgu.CV.UI.ImageViewer(gridImage, "gridImage").Show(); // Allows zoom and pan
            //CvInvoke.Imshow("gridImage", gridImage);
            CvInvoke.Imshow("gridMatchImage", gridMatchImage);

            new Emgu.CV.UI.ImageViewer(imrgb, "work grid").Show(); // Allows zoom and pan
                                                                   //            CvInvoke.Imshow("work grid", imrgb);
            CvInvoke.Imwrite("work grid.png", imrgb);

            while (CvInvoke.WaitKey(100) == -1)
            {
                ;
            }
        }
Пример #3
0
        async Task BinaryImage(Mat gray, int number, Mat canny = null, Mat color = null)
        {
            var image = gray;
            var imageData = EdgePreservingSmoothingBW(gray, 5);

            using (Matrix<byte> edgeSmoothingImage = new Matrix<byte>(imageData))
            //using (Mat image2 = new Mat(@"IMG_0041-Gray.jpg", LoadImageType.Grayscale))
            using (Mat cannyImage = new Mat())
            {
                await Dispatcher.BeginInvoke(_addImageToTheList,
                    edgeSmoothingImage.Mat);

                edgeSmoothingImage.Save("edgeSmoothingImage" + number + ".jpg");

                await Dispatcher.BeginInvoke(_addImageToTheList,
                    image);
                //await Dispatcher.BeginInvoke(_addImageToTheList,
                //    image2);

                var increasedContrasstArray = ChangeContrast(image, 80);

                using (var changedContrastImg = new Image<Gray, byte>(increasedContrasstArray))
                {
                    await Dispatcher.BeginInvoke(_addImageToTheList,
                    changedContrastImg.Mat);

                    changedContrastImg.Save("changedContrastImg" + number + ".jpg");

                    //CvInvoke.Threshold(changedContrastImg, cannyImage, 200, 255, ThresholdType.Binary);

                    //using(Mat sobel = new Mat())
                    //{

                    //}

                    Matrix<byte> sobelMatrix = new Matrix<byte>(image.Size);

                    var sobelX = new Mat(changedContrastImg.Size, DepthType.Cv8U, 1);
                    var sobelY = new Mat(changedContrastImg.Size, DepthType.Cv8U, 1);

                    CvInvoke.Sobel(changedContrastImg, sobelX, DepthType.Cv8U, 1, 0);
                    CvInvoke.Sobel(changedContrastImg, sobelY, DepthType.Cv8U, 0, 1);



                    for (int rowIndex = 0; rowIndex < changedContrastImg.Rows; rowIndex++)
                    {
                        for (int columnIndex = 0; columnIndex < changedContrastImg.Cols; columnIndex++)
                        {
                            var rX = sobelX.GetData(rowIndex, columnIndex)[0];
                            var rY = sobelY.GetData(rowIndex, columnIndex)[0];
                            sobelMatrix[rowIndex, columnIndex] = ToByte(Math.Sqrt(rX * rX + rY * rY));
                        }
                    }

                    //CvInvoke.Threshold(sobelMatrix, sobelMatrix, 170, 255, ThresholdType.Binary);

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                            sobelMatrix.Mat);

                    sobelMatrix.Save("sobelMatrix" + number + ".bmp");

                    CvInvoke.Laplacian(image, sobelMatrix, DepthType.Cv8U, 3, 1, 0, BorderType.Default);

                    sobelMatrix.Save("laplacian" + number + ".bmp");

                    //CvInvoke.Threshold(sobelMatrix, sobelMatrix, 170, 255, ThresholdType.Binary);//170-190
                    //CvInvoke.AdaptiveThreshold(sobelMatrix, sobelMatrix, 255, AdaptiveThresholdType.MeanC, ThresholdType.Binary, 11, 2);

                    var edgeSmoothBWAray = EdgePreservingSmoothingBW(sobelMatrix.Mat, 5);

                    var edgeMatrix = new Matrix<byte>(edgeSmoothBWAray);

                    edgeMatrix.Save("laplacian-edgeMatrix" + number + ".bmp");

                    var thresholdEdge = CustomThreshold(edgeMatrix, 13);



                    Matrix<byte> thresholdEdgeMatrix = new Matrix<byte>(thresholdEdge);

                    thresholdEdgeMatrix.Save("laplacian-threshold-2-" + number + ".bmp");

                    sobelMatrix.Save("laplacian-threshold" + number + ".bmp");

                    CvInvoke.Canny(changedContrastImg, cannyImage, 150, 224, 3, false);
                    await Dispatcher.BeginInvoke(_addImageToTheList,
                        cannyImage);


                    Matrix<byte> mask = new Matrix<byte>(image.Size);

                    int dilSize = 2;
                    Mat se1 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new System.Drawing.Size(2 * dilSize + 1, 2 * dilSize + 1), new System.Drawing.Point(dilSize, dilSize));
                    dilSize = 1;
                    Mat se2 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, new System.Drawing.Size(2 * dilSize + 1, 2 * dilSize + 1), new System.Drawing.Point(dilSize, dilSize));
                    //CvInvoke.MorphologyEx(sobelMatrix, mask, MorphOp.Close, se1, new System.Drawing.Point(0, 0), 1, BorderType.Default, new MCvScalar(255, 0, 0, 255));

                    //await Dispatcher.BeginInvoke(_addImageToTheList,
                    //            mask.Mat);


                    CvInvoke.MorphologyEx(sobelMatrix, mask, MorphOp.Open, se2, new System.Drawing.Point(0, 0), 1, BorderType.Default, new MCvScalar(255, 0, 0, 255));
                    //CvInvoke.Erode(sobelMatrix, sobelMatrix, se1, new System.Drawing.Point(0, 0), 1, BorderType.Default, new MCvScalar(255, 0, 0, 255));
                    //await Dispatcher.BeginInvoke(_addImageToTheList,
                    //                mask.Mat);

                    var maskedSobel = new Matrix<byte>(image.Size);

                    for (int rowIndex = 0; rowIndex < image.Rows; rowIndex++)
                    {
                        for (int columnIndex = 0; columnIndex < image.Cols; columnIndex++)
                        {
                            maskedSobel[rowIndex, columnIndex] = ToByte(thresholdEdgeMatrix[rowIndex, columnIndex] * (mask[rowIndex, columnIndex] / 255));
                        }
                    }
                    //CvInvoke.Threshold(sobelMatrix, sobelMatrix, 160, 255, ThresholdType.Binary);

                    //await Dispatcher.BeginInvoke(_addImageToTheList,
                    //        maskedSobel.Mat);


                    //CvInvoke.Erode(sobelMatrix, sobelMatrix, aaa, new System.Drawing.Point(0, 0), 1, BorderType.Default, new MCvScalar(255, 0, 0, 255));

                    //await Dispatcher.BeginInvoke(_addImageToTheList,
                    //        sobelMatrix.Mat);

                    cannyImage.Save("canny" + number + ".bmp");

                    Matrix<byte> imageMatrix = new Matrix<byte>(image.Size);
                    image.CopyTo(imageMatrix);

                    Matrix<byte> cannyMatrix = new Matrix<byte>(cannyImage.Size);

                    //CvInvoke.Threshold(sobelMatrix, sobelMatrix, 80, 255, ThresholdType.Binary);

                    if (canny == null)
                    {
                        thresholdEdgeMatrix.CopyTo(cannyMatrix);
                    }
                    else
                    {
                        thresholdEdgeMatrix.CopyTo(cannyMatrix);
                    }




                    var skeletonMatrix = new Matrix<double>(image.Size);
                    var skeletonMatrixByte = new Matrix<byte>(image.Size);
                    //imageMatrix.Mul(cannyMatrix);

                    for (int rowIndex = 0; rowIndex < image.Rows; rowIndex++)
                    {
                        cannyMatrix[rowIndex, 0] = 255;
                        cannyMatrix[rowIndex, image.Cols - 1] = 255;
                    }

                    for (int columnIndex = 0; columnIndex < image.Cols; columnIndex++)
                    {
                        cannyMatrix[0, columnIndex] = 255;
                        cannyMatrix[image.Rows - 1, columnIndex] = 255;
                    }

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                                    cannyMatrix.Mat);

                    for (int rowIndex = 0; rowIndex < image.Rows; rowIndex++)
                    {
                        for (int columnIndex = 0; columnIndex < image.Cols; columnIndex++)
                        {
                            var skeletonvalue = imageMatrix[rowIndex, columnIndex] * (cannyMatrix[rowIndex, columnIndex] / 255);
                            skeletonMatrix[rowIndex, columnIndex] = skeletonvalue;
                            skeletonMatrixByte[rowIndex, columnIndex] = ToByte(skeletonvalue);
                        }
                    }

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                                skeletonMatrixByte.Mat);

                    skeletonMatrixByte.Save("skeletonMatrixByte" + number + ".bmp");

                    using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                    {
                        CvInvoke.FindContours(sobelMatrix, contours, null, RetrType.List, ChainApproxMethod.ChainApproxNone);

                        foreach (var contour in contours.ToArrayOfArray())
                        {
                            int meanColor = 0;

                            foreach (var point in contour)
                            {
                                meanColor += image.GetData(point.Y, point.X)[0];
                            }

                            meanColor = meanColor / contour.Length;

                            foreach (var point in contour)
                            {
                                skeletonMatrix[point.Y, point.X] = meanColor;
                                skeletonMatrixByte[point.Y, point.X] = ToByte(meanColor);
                            }
                        }
                        //CvInvoke.DrawContours(smoothImage.Mat, contours, -1, new MCvScalar(255, 0, 0), -1, LineType.EightConnected, null, 200);

                    }

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                                    skeletonMatrixByte.Mat);

                    skeletonMatrixByte.Save("skeletonMatrixByte-norm" + number + ".bmp");



                    var intersectionSurfaceMatrix = CreateIntersectionSurfaceMatrix(cannyMatrix, skeletonMatrixByte, skeletonMatrix);

                    var intersectionMatrixByte = new Matrix<byte>(intersectionSurfaceMatrix.Size);

                    for (int rowIndex = 0; rowIndex < image.Rows; rowIndex++)
                    {
                        for (int columnIndex = 0; columnIndex < image.Cols; columnIndex++)
                        {
                            intersectionMatrixByte[rowIndex, columnIndex] = ToByte(intersectionSurfaceMatrix[rowIndex, columnIndex]);
                        }
                    }

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                            intersectionMatrixByte.Mat);
                    intersectionMatrixByte.Save("intersectionMatrixByte" + number + ".bmp");

                    var doubleImageMatrix = imageMatrix.Convert<double>();
                    var differenceMatrix = intersectionSurfaceMatrix - doubleImageMatrix;

                    var binary1Matrix = new Matrix<byte>(image.Size);
                    var binary2Matrix = new Matrix<byte>(image.Size);

                    double pt = 15;
                    double nt = 15;

                    for (int rowIndex = 0; rowIndex < image.Rows; rowIndex++)
                    {
                        for (int columnIndex = 0; columnIndex < image.Cols; columnIndex++)
                        {
                            var diffValue = differenceMatrix[rowIndex, columnIndex];
                            if (diffValue > pt
                                || cannyMatrix[rowIndex, columnIndex] == 255)
                            {
                                binary1Matrix[rowIndex, columnIndex] = 255;
                            }
                            else
                            {
                                binary1Matrix[rowIndex, columnIndex] = 0;
                            }

                            if (diffValue < -nt
                                || cannyMatrix[rowIndex, columnIndex] == 255)
                            {
                                binary2Matrix[rowIndex, columnIndex] = 255;
                            }
                            else
                            {
                                binary2Matrix[rowIndex, columnIndex] = 0;
                            }
                        }
                    }

                    VectorOfVectorOfPoint contoursVector = new VectorOfVectorOfPoint();
                    //var connectedComponents = FindBlobs(binary1Matrix.Mat, number);
                    CvInvoke.FindContours(binary1Matrix.Mat.Clone(), contoursVector, null, RetrType.List, ChainApproxMethod.ChainApproxNone);

                    var minWidth = 0.045 * gray.Width;
                    var maxWidth = 0.25 * gray.Width;

                    var minHeight = 0.045 * gray.Height;
                    var maxHeight = 0.25 * gray.Height;

                    Mat detectedDigits = new Mat();
                    //(gray.Size, DepthType.Cv32S, 3);

                    //color.ConvertTo(colorComponents, DepthType.Cv32S);

                    

                    gray.ConvertTo(detectedDigits, DepthType.Cv32S);
     

                    for (int compIndex = 0; compIndex < contoursVector.Size; compIndex++)
                    {
                        var component = contoursVector[compIndex];

                        var subSampleData = await SubSampling(color, component);
                        
                        byte[,,] colorComponents = new byte[color.Rows, color.Cols, 3];
                        for(int row = 0; row < subSampleData.GetLength(0); row++)
                        {
                            for(int column = 0; column < subSampleData.GetLength(1); column++)
                            {
                                var r = subSampleData[row, column, 2];
                                var g = subSampleData[row, column, 1];
                                var b = subSampleData[row, column, 0];

                                if(r > 0)
                                {
                                    colorComponents[row, column, 2] = color.GetData(row, column)[2];
                                    colorComponents[row, column, 1] = color.GetData(row, column)[1];
                                    colorComponents[row, column, 0] = color.GetData(row, column)[0];
                                }
                            }
                        }

                        var compRectangle = CvInvoke.BoundingRectangle(component);

                        var ratio = (double)compRectangle.Width / compRectangle.Height;
                        var inversedRatio = (double) 1 / ratio;

                        using (var colorImage = new Image<Bgr, byte>(subSampleData))
                        {
                            colorImage.Save("colorComponents-" + number + "-" + compIndex + ".bmp");
                        }

                        using (var colorImage = new Image<Bgr, byte>(colorComponents))
                        {
                            colorImage.Save("colorComponents-def-" + number + "-" + compIndex + ".bmp");
                            var data = EdgePreservingSmoothing(colorImage.Mat, component, 12);

                            using (var colorImage2 = new Image<Bgr, byte>(data))
                            {
                                
                                colorImage2.Save("colorComponents-edge-smooth-" + number + "-" + compIndex + ".bmp");

                                var subSampleData2 = await SubSampling(colorImage2.Mat, component);
                                using (var colorImage3 = new Image<Bgr, byte>(subSampleData2))
                                {
                                    colorImage3.Save("colorComponents-edge-smooth-sub" + number + "-" + compIndex + ".bmp");
                                }
                            }
                        }

                        if(compRectangle.Width >= minWidth
                            && compRectangle.Width <= maxWidth
                            && compRectangle.Height >= minHeight
                            && compRectangle.Height <= maxHeight
                            && (ratio <= 0.9
                            && inversedRatio <= 1.5))
                        {
                            
                            CvInvoke.Rectangle(detectedDigits, compRectangle, new MCvScalar(100, 100, 100));
                        }
                    }

                    detectedDigits.Save("detectedDigits" + number + ".bmp");

                        await Dispatcher.BeginInvoke(_addImageToTheList,
                            binary1Matrix.Mat);

                    binary1Matrix.Save("binary1Matrix" + number + ".bmp");

                    await Dispatcher.BeginInvoke(_addImageToTheList,
                        binary2Matrix.Mat);

                    binary2Matrix.Save("binary2Matrix" + number + ".bmp");
                }


                //CvInvoke.BilateralFilter(image, cannyImage, 4, 4, 4);
                //CvInvoke.Laplacian(image, cannyImage, DepthType.Cv8U);
                //CvInvoke.Threshold(cannyImage, cannyImage, 40, 255, ThresholdType.Binary);
                //await Dispatcher.BeginInvoke(_addImageToTheList,
                //    cannyImage);


                //using(Mat skeletonMat  = new Mat())
                //{
                //    skeletonMat =
                //}
            }
        }