Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            //! Create directories for output images
            if (!Directory.Exists(Settings.Images.Output))
            {
                Directory.CreateDirectory(Settings.Images.Output);
            }

            //! create list of images
            var listOfImages = Directory.GetFiles(Settings.Images.Source, "*.jpg")
                               .Where(x => x.Contains("940"))
                               .Where(x => x.Contains("_l_"))
                               // .Take (6) // take one palm to test
                               .ToList();

            //! variables for ROI
            double radius, a, xx, yy, predictX, predictY, angle;

            Point   centerOfPalm;
            Point2f centerOfImage;
            Rect    rect;

            //! variables for extracting file parameters
            PalmModel[] Palms = new PalmModel[listOfImages.Count];

            //! matherials
            Mat sourceHandle, thresholdHandle, roiHandle, skel, rotatedSource, eroded, thr, matrix = new Mat();
            Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, Settings.ElementSize);

            Mat[] RGB;

            for (int i = 0; i != listOfImages.Count; i++)
            {
                Palms[i]           = new PalmModel();
                Palms[i].Filename  = listOfImages[i].Remove(0, listOfImages[i].LastIndexOf('/') + 1).Replace(".jpg", "");
                Palms[i].Owner     = Palms[i].Filename.Substring(0, Palms[i].Filename.IndexOf('_'));
                Palms[i].Id        = Palms[i].Filename.Substring(Palms[i].Filename.LastIndexOf('_') + 2);
                Palms[i].Type      = (Palms[i].Filename.IndexOf('r') == -1 ? 'l' : 'r');
                Palms[i].Directory = $"{Settings.Images.Output}{Palms[i].Type}/{Palms[i].Owner}";
                Palms[i].Path      = $"{Settings.Images.Source}/{Palms[i].Filename}.jpg";

                if (Directory.Exists(Palms[i].Directory) && Directory.GetFiles(Palms[i].Directory).Length > 0)
                {
                    Directory.Delete(Palms[i].Directory, true); // recursive
                }
                Directory.CreateDirectory(Palms[i].Directory);
            }

            Console.WriteLine($"[{DateTime.Now}] Transform started");

            var workerTime = new Stopwatch();

            workerTime.Start();

            for (int i = 0; i != listOfImages.Count; i++)
            {
                if (i % 10 == 0)
                {
                    Console.WriteLine($"{i}.{listOfImages.Count}");
                }

                // Read sample image
                sourceHandle = Cv2.ImRead(Palms[i].Path, ImreadModes.AnyColor);

                // Get center of image
                centerOfImage = new Point2f(sourceHandle.Width / 2, sourceHandle.Height / 2);

                // Start loop by rotations
                for (int j = 0; j != 180; j++)
                {
                    // change rotation angle
                    angle = j * 2;

                    rotatedSource = new Mat();
                    // get and apply image rotation matrix by angle
                    matrix = Cv2.GetRotationMatrix2D(centerOfImage, angle, 1.0);
                    Cv2.WarpAffine(sourceHandle, rotatedSource, matrix, new Size(sourceHandle.Width, sourceHandle.Height));

                    // apply threshold
                    thresholdHandle = rotatedSource.Threshold(0, 255, ThresholdTypes.Otsu);

                    /*// apply transform distance and convert to cv_8u
                     * thresholdHandle.DistanceTransform (DistanceTypes.L2, DistanceMaskSize.Precise);
                     * thresholdHandle.ConvertTo (thresholdHandle, MatType.CV_8U);
                     *
                     * // get center of palm
                     * centerOfPalm = GetHandCenter (thresholdHandle, out radius);*/
                    double radius1;
                    Cv2.DistanceTransform(thresholdHandle, matrix, DistanceTypes.L2, DistanceMaskSize.Mask5);
                    matrix.ImWrite($"{Palms[i].Directory}/002_distance-transform.jpg");

                    int[] maxIdx = new int[2];
                    int[] minIdx = new int[2];
                    Cv2.MinMaxIdx(matrix, out radius1, out radius, minIdx, maxIdx, thresholdHandle);
                    centerOfPalm = new OpenCvSharp.Point(maxIdx[1], maxIdx[0]);

                    // calculate ROI
                    a = (2 * radius) / Math.Sqrt(2);

                    xx = centerOfPalm.X - radius * Math.Cos(45 * Math.PI / 180);
                    yy = centerOfPalm.Y - radius * Math.Sin(45 * Math.PI / 180);

                    if (xx < 0)
                    {
                        a += xx; // 200 + -2 -> 200 - 2 = 198
                        xx = 0;
                    }

                    if (yy < 0)
                    {
                        a += yy; // 120 + -10 -> 120 - 10 = 110
                        yy = 0;
                    }

                    predictX = xx + a;
                    predictY = yy + a;

                    if (predictX > rotatedSource.Width)       // if more
                    {
                        xx -= predictX - rotatedSource.Width; // (590 - 580) = 10
                    }

                    if (predictY > rotatedSource.Height)
                    {
                        yy -= predictY - rotatedSource.Height; // 800 - 640 = 160
                    }

                    /*
                     *  rect = new Rect(new Point(xx + 20, yy + 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx - 20, yy - 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx - 20, yy + 20), new Size(a, a));
                     *  rect = new Rect(new Point(xx + 20, yy - 20), new Size(a, a));
                     */

                    rect = new Rect(new Point(xx, yy), new Size(a, a));

                    roiHandle = new Mat(rotatedSource, rect)
                                .Resize(Const.ResizeValue);

                    //! apply filters
                    Cv2.MedianBlur(roiHandle, roiHandle, 5);

                    // Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY);
                    Cv2.FastNlMeansDenoising(roiHandle, roiHandle);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.GRAY2BGR);

                    //! Equalize hist
                    Cv2.MorphologyEx(roiHandle, roiHandle, MorphTypes.Open, element);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2YUV);

                    RGB    = Cv2.Split(roiHandle);
                    RGB[0] = RGB[0].EqualizeHist();
                    RGB[1] = RGB[1].EqualizeHist();
                    RGB[2] = RGB[2].EqualizeHist();

                    Cv2.Merge(RGB, roiHandle);
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.YUV2BGR);

                    //! Invert image
                    Cv2.BitwiseNot(roiHandle, roiHandle);

                    //! Erode image
                    Cv2.CvtColor(roiHandle, roiHandle, ColorConversionCodes.BGR2GRAY);
                    Cv2.Erode(roiHandle, roiHandle, element);

                    //! Skeletonize
                    skel          = new Mat(roiHandle.Size(), MatType.CV_8UC1, Const.ZeroScalar);
                    rotatedSource = new Mat();
                    eroded        = new Mat();
                    thr           = new Mat();

                    do
                    {
                        Cv2.MorphologyEx(roiHandle, eroded, MorphTypes.Erode, element);
                        Cv2.MorphologyEx(eroded, rotatedSource, MorphTypes.Dilate, element);
                        Cv2.Subtract(roiHandle, rotatedSource, rotatedSource);
                        Cv2.BitwiseOr(skel, rotatedSource, skel);
                        eroded.CopyTo(roiHandle);
                    } while (Cv2.CountNonZero(roiHandle) != 0);

                    //! Threshold skeletonized image
                    thr = skel.Threshold(0, 255, ThresholdTypes.Binary);

                    //! Remove contours
                    thr.Line(Const.Zero, new Point(0, thr.Height), Scalar.Black, 2);                       // rm left contour
                    thr.Line(Const.Zero, new Point(thr.Width, 0), Scalar.Black, 2);                        // rm top contour
                    thr.Line(new Point(thr.Width, thr.Height), new Point(thr.Width, 0), Scalar.Black, 2);  // rm right contour
                    thr.Line(new Point(thr.Width, thr.Height), new Point(0, thr.Height), Scalar.Black, 2); // rm bot contour

                    //! Partion lines
                    if (Const.MODE_TYPE)
                    {
                        Cv2.GaussianBlur(thr, thr, new Size(7, 7), sigmaX: 5);
                        Cv2.MorphologyEx(thr, thr, MorphTypes.Gradient, element);
                        Cv2.BitwiseNot(thr, thr);
                    }
                    thr.ImWrite($"{Palms[i].Directory}/{Palms[i].Id}-{angle}.jpg");
                }
            }
            workerTime.Stop();
            Console.WriteLine($"[{DateTime.Now}] Elapsed time: {workerTime.Elapsed}");
        }
Ejemplo n.º 2
0
        private void Form1_Load(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter = "Image Files(*.PNG;*.JPG)|*.PNG;*.JPG|All Files(*.*)|*.*";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                inputImage        = new Mat(openFileDialog.FileName);
                pictureBox1.Image = BitmapConverter.ToBitmap(inputImage);
            }

            Cv2.CvtColor(inputImage, grayscaleImage, ColorConversionCodes.BGRA2GRAY);
            pictureBox2.Image = BitmapConverter.ToBitmap(grayscaleImage);

            Cv2.Sobel(grayscaleImage, gradientXImage, MatType.CV_16S, 1, 0);
            Cv2.Sobel(grayscaleImage, gradientYImage, MatType.CV_16S, 0, 1);

            Cv2.ConvertScaleAbs(gradientXImage, gradientXImage);
            Cv2.ConvertScaleAbs(gradientYImage, gradientYImage);

            Cv2.AddWeighted(gradientXImage, 1.0, gradientYImage, 1.0, 0, gradientImage);

            Cv2.Canny(grayscaleImage, cannyImage, 50, 200);
            pictureBox3.Image = BitmapConverter.ToBitmap(cannyImage);

            Cv2.DistanceTransform(1 - cannyImage, distance, DistanceTypes.L2, DistanceMaskSize.Mask3);

            Cv2.Normalize(distance, distance, 0, 1.0, NormTypes.MinMax);
            pictureBox4.Image = BitmapConverter.ToBitmap(distance);

            Cv2.Integral(inputImage, integrateImage, MatType.CV_32F);

            for (int i = 0; i < filterImage.Width; i++)
            {
                for (int j = 0; j < filterImage.Height; j++)
                {
                    float tets = distance.Get <float>(i, j);
                    int   size = (int)(10 * distance.Get <float>(i, j));
                    if (size >= 1)
                    {
                        int pixelsCount = ((Clamp(i + size, 0, integrateImage.Width - 1) - Clamp(i - size, 0, integrateImage.Width - 1)) *
                                           (Clamp(j + size, 0, integrateImage.Height - 1) - Clamp(j - size, 0, integrateImage.Height - 1)));

                        var p0 = new OpenCvSharp.Point(Clamp(i - size, 0, integrateImage.Width - 1), Clamp(j - size, 0, integrateImage.Height - 1));
                        var p1 = new OpenCvSharp.Point(Clamp(i + size, 0, integrateImage.Width - 1), Clamp(j + size, 0, integrateImage.Height - 1));
                        var p2 = new OpenCvSharp.Point(Clamp(i - size, 0, integrateImage.Width - 1), Clamp(j + size, 0, integrateImage.Height - 1));
                        var p3 = new OpenCvSharp.Point(Clamp(i + size, 0, integrateImage.Width - 1), Clamp(j - size, 0, integrateImage.Height - 1));

                        filterImage.Set <Vec3b>(i, j, new Vec3b((byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item0
                                                                        + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item0 - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item0
                                                                        - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item0) / pixelsCount),
                                                                (byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item1 + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item1
                                                                        - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item1 - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item1)
                                                                       / pixelsCount),
                                                                (byte)((integrateImage.Get <Vec3f>(p0.X, p0.Y).Item2 + integrateImage.Get <Vec3f>(p1.X, p1.Y).Item2
                                                                        - integrateImage.Get <Vec3f>(p2.X, p2.Y).Item2 - integrateImage.Get <Vec3f>(p3.X, p3.Y).Item2)
                                                                       / pixelsCount)));
                    }
                    else
                    {
                        filterImage.Set <Vec3b>(i, j, inputImage.Get <Vec3b>(i, j));
                    }
                }
            }
            pictureBox5.Image = BitmapConverter.ToBitmap(filterImage);
        }
Ejemplo n.º 3
0
        static void Main()
        {
            Mat mat    = new Mat("lenna.png");
            Mat result = mat.EmptyClone();

            Mat matGray = new Mat();

            Cv2.CvtColor(mat, matGray, ColorConversionCodes.BGRA2GRAY);

            Mat edges = new Mat();

            Mat gradX    = new Mat();
            Mat gradY    = new Mat();
            Mat absGradX = new Mat();
            Mat absGradY = new Mat();

            Cv2.Sobel(matGray, gradX, MatType.CV_16S, 1, 0);
            Cv2.Sobel(matGray, gradY, MatType.CV_16S, 0, 1);

            Cv2.ConvertScaleAbs(gradX, absGradX);
            Cv2.ConvertScaleAbs(gradY, absGradY);

            Mat grad = new Mat();

            Cv2.AddWeighted(absGradX, 1.0, absGradY, 1.0, 0, grad);

            Mat dist = new Mat();

            Cv2.Canny(matGray, edges, 50, 200);

            Cv2.DistanceTransform(1 - edges, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);

            Mat normDist = new Mat();

            Cv2.Normalize(dist, normDist, 0, 1.0, NormTypes.MinMax);

            Mat integralImage = new Mat();

            Cv2.Integral(mat, integralImage, MatType.CV_32F);

            for (int i = 0; i < result.Width; i++)
            {
                for (int j = 0; j < result.Height; j++)
                {
                    int size = (int)(10 * dist.Get <float>(i, j));
                    if (size >= 1)
                    {
                        int pixelsCount = ((Clamp(i + size, 0, integralImage.Width - 1) - Clamp(i - size, 0, integralImage.Width - 1)) *
                                           (Clamp(j + size, 0, integralImage.Height - 1) - Clamp(j - size, 0, integralImage.Height - 1)));

                        var p0 = new Point(Clamp(i - size, 0, integralImage.Width - 1), Clamp(j - size, 0, integralImage.Height - 1));
                        var p1 = new Point(Clamp(i + size, 0, integralImage.Width - 1), Clamp(j + size, 0, integralImage.Height - 1));
                        var p2 = new Point(Clamp(i - size, 0, integralImage.Width - 1), Clamp(j + size, 0, integralImage.Height - 1));
                        var p3 = new Point(Clamp(i + size, 0, integralImage.Width - 1), Clamp(j - size, 0, integralImage.Height - 1));

                        result.Set <Vec3b>(i, j, new Vec3b(
                                               (byte)((
                                                          integralImage.Get <Vec3f>(p0.X, p0.Y).Item0
                                                          + integralImage.Get <Vec3f>(p1.X, p1.Y).Item0
                                                          - integralImage.Get <Vec3f>(p2.X, p2.Y).Item0
                                                          - integralImage.Get <Vec3f>(p3.X, p3.Y).Item0
                                                          ) / pixelsCount),
                                               (byte)((
                                                          integralImage.Get <Vec3f>(p0.X, p0.Y).Item1
                                                          + integralImage.Get <Vec3f>(p1.X, p1.Y).Item1
                                                          - integralImage.Get <Vec3f>(p2.X, p2.Y).Item1
                                                          - integralImage.Get <Vec3f>(p3.X, p3.Y).Item1
                                                          ) / pixelsCount),
                                               (byte)((
                                                          integralImage.Get <Vec3f>(p0.X, p0.Y).Item2
                                                          + integralImage.Get <Vec3f>(p1.X, p1.Y).Item2
                                                          - integralImage.Get <Vec3f>(p2.X, p2.Y).Item2
                                                          - integralImage.Get <Vec3f>(p3.X, p3.Y).Item2
                                                          ) / pixelsCount)));
                    }
                    else
                    {
                        result.Set <Vec3b>(i, j, mat.Get <Vec3b>(i, j));
                    }
                }
            }
            using (new Window("src image", mat))
                using (new Window("matGray image", matGray))
                    using (new Window("grad image", grad))
                        using (new Window("edges image", edges))
                            using (new Window("normDist image", normDist))
                                using (new Window("result image", result))
                                {
                                    Cv2.WaitKey();
                                }
        }
    private void ProcessFrame(VideoFrame frame)
    {
        if (HasTextureConflict(frame))
        {
            if (texture != null)
            {
                Destroy(texture);
            }

            using (var p = frame.Profile)
            {
                bool linear = (QualitySettings.activeColorSpace != ColorSpace.Linear) ||
                              (p.Stream != Stream.Color && p.Stream != Stream.Infrared);
                texture = new Texture2D(frame.Width, frame.Height, Convert(p.Format), false, linear)
                {
                    wrapMode   = TextureWrapMode.Clamp,
                    filterMode = filterMode
                };
            }

            textureBinding.Invoke(texture);
        }


        texture.LoadRawTextureData(frame.Data, frame.Stride * frame.Height);

        //Mat mat = OpenCvSharp.Unity.TextureToMat(texture);

        //for (int yi = 0; yi < mat.Height; yi++)
        //{
        //    for (int xi = 0; xi < mat.Width; xi++)
        //    {
        //        Vec3b v = mat.At<Vec3b>(yi, xi);
        //        float gr = 0.2126f * v[2] + 0.7152f * v[1] + 0.0722f * v[0];
        //        v[0] = (byte)gr;
        //        v[1] = (byte)gr;
        //        v[2] = (byte)gr;

        //        mat.Set<Vec3b>(yi, xi, v);
        //    }
        //}
        //texture = OpenCvSharp.Unity.MatToTexture(mat);
        //Debug.Log(texture.GetPixels32()[0]);

        //
        //Gray Scalse
        //
        //Mat mat = OpenCvSharp.Unity.TextureToMat(texture);
        //Mat changedMat = new Mat();
        //Cv2.CvtColor(mat, changedMat, ColorConversionCodes.BGR2GRAY);

        //texture = OpenCvSharp.Unity.MatToTexture(changedMat);

        //Gray Scale
        Mat mat  = OpenCvSharp.Unity.TextureToMat(texture);
        Mat gray = new Mat();

        Cv2.CvtColor(mat, gray, ColorConversionCodes.BGR2GRAY);

        //Threshold
        Mat thresh  = new Mat();
        Mat bin_img = new Mat();

        Cv2.Threshold(gray, thresh, 0, 255, ThresholdTypes.Otsu);
        bin_img = thresh;

        //morphologyEx
        Mat morphology = new Mat();

        Cv2.MorphologyEx(bin_img, morphology, MorphTypes.Open, new InputArray(1), null, 2);

        //Dilate
        Mat dilate = new Mat();

        Cv2.Dilate(morphology, dilate, new InputArray(1), null, 2, BorderTypes.Constant);
        //thresh.Dilate(dilate, null, 1, BorderTypes.Constant, null);

        //Distance Transform
        Mat distance_transform = new Mat();

        Cv2.DistanceTransform(morphology, distance_transform, DistanceTypes.L2, DistanceMaskSize.Mask5);

        //sure foreground
        Mat sure_fg = new Mat();

        Cv2.Threshold(distance_transform, sure_fg, 11, 255, ThresholdTypes.Binary);


        //SubStract
        //Mat subtract = new Mat();
        //Cv2.Subtract(dilate, sure_fg, subtract);

        //Contours
        Point[][]        contours;
        HierarchyIndex[] h_index;
        Cv2.FindContours(dilate, out contours, out h_index, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS, null);


        //
        // draw max area
        //
        //double max_area = 0;
        //int max_area_contour = -1;
        //for (int j = 0; j < contours.Length; j++)
        //{
        //    double area = Cv2.ContourArea(contours[j]);
        //    if (max_area < area)
        //    {
        //        max_area = area;
        //        max_area_contour = j;
        //    }
        //}
        //int count = contours[max_area_contour].Length;
        //double x = 0;
        //double y = 0;
        //for (int k = 0; k < count; k++)
        //{
        //    x += contours[max_area_contour][k].X;
        //    y += contours[max_area_contour][k].Y;
        //}
        //x /= count;
        //y /= count;
        //Cv2.Circle(mat, (int)x, (int)y, 50, new Scalar(0, 0, 255), 3, LineTypes.Link4);


        /// draw segment
        Cv2.Polylines(mat, contours, true, new Scalar(0, 0, 255), 5);

        texture = OpenCvSharp.Unity.MatToTexture(mat);

        textureBinding.Invoke(texture);
        texture.Apply();

        //texture.Apply();
    }
Ejemplo n.º 5
0
        public static void CalculoMatrizBinariaYRelleno(Mat imagen, out Mat imagenBinaria, out Mat imagenAberturaRelleno)
        {
            imagenBinaria         = new Mat();
            imagenAberturaRelleno = new Mat();
            imagenBinaria         = 255 - imagen;
            Mat imagenBinariaProc = new Mat();

            imagenBinaria.CopyTo(imagenBinariaProc);
            Mat kernelMorfologicoElipse = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3));
            Mat kernelMorfologicoCruz   = Cv2.GetStructuringElement(MorphShapes.Cross, new Size(3, 3));

            Cv2.Erode(imagenBinariaProc, imagenBinariaProc, kernelMorfologicoElipse, iterations: 3);
            Cv2.Dilate(imagenBinariaProc, imagenBinariaProc, kernelMorfologicoCruz, iterations: 2);
            imagenBinariaProc = 255 - imagenBinariaProc;
            Mat imagenTransfDistancia        = new Mat();
            Mat imagenTransfDistanciaBinaria = new Mat();

            Cv2.DistanceTransform(imagenBinariaProc, imagenTransfDistancia, DistanceTypes.C, DistanceMaskSize.Mask5);
            imagenTransfDistancia.ConvertTo(imagenTransfDistancia, MatType.CV_8U);
            imagenTransfDistancia.CopyTo(imagenTransfDistanciaBinaria);
            double maxDist, minDist, rangoDist;

            imagenTransfDistanciaBinaria.MinMaxIdx(out minDist, out maxDist);
            rangoDist = maxDist - minDist;
            var indexadorImgDistancia = imagenTransfDistanciaBinaria.GetGenericIndexer <byte>();

            for (int i = 0; i < imagenTransfDistancia.Rows; i++)
            {
                for (int j = 0; j < imagenTransfDistancia.Cols; j++)
                {
                    if (indexadorImgDistancia[i, j] >= maxDist - rangoDist * 0.35 ||
                        indexadorImgDistancia[i, j] <= minDist + rangoDist * 0.15)
                    {
                        indexadorImgDistancia[i, j] = (byte)255;
                    }
                    else
                    {
                        indexadorImgDistancia[i, j] = (byte)0;
                    }
                }
            }
            Mat marcadores    = new Mat();
            int numMarcadores = Cv2.ConnectedComponents(imagenTransfDistanciaBinaria, marcadores, PixelConnectivity.Connectivity8, MatType.CV_16UC1);
            Dictionary <int, int> cantidadMarcador = new Dictionary <int, int>();

            for (int i = 0; i < marcadores.Rows; i++)
            {
                for (int j = 0; j < marcadores.Cols; j++)
                {
                    int areaMarcador = 0;
                    int m            = marcadores.At <int>(i, j);
                    cantidadMarcador.TryGetValue(m, out areaMarcador);
                    if (areaMarcador > 0)
                    {
                        cantidadMarcador[m] += 1;
                    }
                    else
                    {
                        cantidadMarcador[m] = 1;
                    }
                    //try
                    //{
                    //    cantidadMarcador[m] += 1;
                    //}
                    //catch
                    //{
                    //    cantidadMarcador[m] = 1;
                    //}
                }
            }

            int indiceMarcadorMax = cantidadMarcador.Select(v => new Tuple <int, int>(v.Key, v.Value))
                                    .OrderByDescending(x => x.Item1).First().Item2;
            Mat fondoMarcadores = new Mat();

            marcadores.CopyTo(fondoMarcadores);
            var indexador = fondoMarcadores.GetGenericIndexer <int>();

            for (int i = 0; i < fondoMarcadores.Rows; i++)
            {
                for (int j = 0; j < fondoMarcadores.Cols; j++)
                {
                    indexador[i, j] = (indexador[i, j] == indiceMarcadorMax) ? 255 : 0;
                }
            }
            fondoMarcadores.ConvertTo(fondoMarcadores, imagenBinaria.Type());
            Mat imagenBinariaSinFondo = new Mat();
            Mat imagenRellenoHuecos   = new Mat();

            Cv2.Subtract(imagenBinaria, fondoMarcadores, imagenBinariaSinFondo);
            Cv2.Add(imagenBinaria, imagenBinariaSinFondo, imagenRellenoHuecos);

            Mat kernelMorfologicoApertura = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));

            Cv2.MorphologyEx(imagenRellenoHuecos, imagenAberturaRelleno, MorphTypes.Open, kernelMorfologicoApertura, iterations: 2);

            /* liberar memoria */
            imagenBinariaProc.Release();
            imagenBinariaSinFondo.Release();
            imagenRellenoHuecos.Release();
            kernelMorfologicoElipse.Release();
            kernelMorfologicoCruz.Release();
            kernelMorfologicoApertura.Release();
        }
Ejemplo n.º 6
0
        static void Main(string[] args)
        {
            //Thread capturaVideoThread = new Thread(new ThreadStart(Program.CapturarVideo));
            //capturaVideoThread.Start();

            VideoCapture captura = new VideoCapture("D:\\Dictuc\\out1.avi");
            VideoWriter  salida  = new VideoWriter("D:\\Dictuc\\outSegmentado.avi", FourCC.XVID, 10.0, new Size(captura.FrameWidth, captura.FrameHeight), true);

            Mat imagenProcesada = new Mat();
            int numImg          = 0;

            while (true)
            {
                //captura.Read(imagen);
                imagen = Cv2.ImRead("D:\\uvas2.jpg");
                mutex.WaitOne();
                imagen.CopyTo(imagenProcesada);
                mutex.ReleaseMutex();
                Mat          imagenRuidoFiltrado     = FiltradoRuido(imagenProcesada);
                Mat          imagenGrisContraste     = EscalaGrisesEqualizada(imagenRuidoFiltrado);
                Mat          imagenGrisFrecAltasProc = FrecuenciasAltasPotenciadasContraste(imagenGrisContraste);
                EdgeDetector edgeDetector            = new EdgeDetector()
                {
                    Threshold           = (byte)18,
                    SparseDistance      = 3,
                    WeightPreviousPoint = (float)2.0,
                    WeightCurrentPoint  = (float)1.0,
                    WeightAfterPoint    = (float)2.0,
                };

                EdgeDetector edgeDetector2 = new EdgeDetector()
                {
                    Threshold           = (byte)20,
                    SparseDistance      = 5,
                    WeightPreviousPoint = (float)0.5,
                    WeightCurrentPoint  = (float)1.0,
                    WeightAfterPoint    = (float)0.5,
                };

                Mat imagenBordes = edgeDetector.EdgeImage(imagenGrisContraste);
                Mat imagenBordes2 = edgeDetector2.EdgeImage(imagenGrisContraste);
                Mat imagenBinaria, imagenAberturaRelleno;
                CalculoMatrizBinariaYRelleno(imagenBordes2, out imagenBinaria, out imagenAberturaRelleno);

                Mat mascaraInv = 255 - imagenAberturaRelleno;

                Mat DistSureFg  = new Mat();
                Mat AreasSureFg = new Mat();
                Mat Unknown     = new Mat();
                AreasSureFg += 1;
                Cv2.DistanceTransform(imagenAberturaRelleno, DistSureFg, DistanceTypes.L1, DistanceMaskSize.Mask5);
                int numAreas = Cv2.ConnectedComponents(imagenAberturaRelleno, AreasSureFg, PixelConnectivity.Connectivity8);

                float[,] distValues = new float[DistSureFg.Rows, DistSureFg.Cols];

                for (int i = 0; i < DistSureFg.Rows; i++)
                {
                    for (int j = 0; j < DistSureFg.Cols; j++)
                    {
                        distValues[i, j] = DistSureFg.At <float>(i, j);
                    }
                }

                Segment[] segments = new Segment[numAreas];

                for (int i = 0; i < AreasSureFg.Rows; i++)
                {
                    for (int j = 0; j < AreasSureFg.Cols; j++)
                    {
                        int   m = AreasSureFg.At <Int32>(i, j);
                        byte  pixelSurrounding = 0;
                        float distance         = (float)0;

                        //if (i >= 1)
                        //{
                        //    distance = distValues[i - 1, j];
                        //    if (distance == 2)
                        //    {
                        //        pixelSurrounding |= Segment.PIXEL_SURROUNDED_LEFT;
                        //    }
                        //}
                        //if (i < AreasSureFg.Rows - 1)
                        //{
                        //    distance = distValues[i + 1, j];
                        //    if (distance == 2)
                        //    {
                        //        pixelSurrounding |= Segment.PIXEL_SURROUNDED_RIGHT;
                        //    }
                        //}
                        //if (j >= 1)
                        //{
                        //    distance = distValues[i, j - 1];
                        //    if (distance == 2)
                        //    {
                        //        pixelSurrounding |= Segment.PIXEL_SURROUNDED_DOWN;
                        //    }
                        //}
                        //if (j < AreasSureFg.Cols - 1)
                        //{
                        //    distance = distValues[i, j + 1];
                        //    if (distance == 2)
                        //    {
                        //        pixelSurrounding |= Segment.PIXEL_SURROUNDED_UP;
                        //    }
                        //}

                        SegmentPixelData newPixel = new SegmentPixelData()
                        {
                            Distance          = distValues[i, j],
                            CoordsXY          = new int[] { i, j },
                            Concave           = 0,
                            Indexes           = new int[] { -1, -1 },
                            PixelsSurrounding = pixelSurrounding,
                            SubsegmentLabel   = 0,
                        };

                        if (segments[m] == null)
                        {
                            segments[m] = new Segment()
                            {
                                SegmentId = m,
                                PixelData = new List <SegmentPixelData>(),
                            };
                        }
                        else
                        {
                            segments[m].MaxDistance = (segments[m].MaxDistance > newPixel.Distance) ? (int)segments[m].MaxDistance : (int)newPixel.Distance;
                            segments[m].PixelData.Add(newPixel);
                        }
                    }
                }

                Mat Centroides = new Mat();
                imagenAberturaRelleno.CopyTo(Centroides);
                var indexadorCentroides = Centroides.GetGenericIndexer <byte>();
                var indexadorFiguras    = AreasSureFg.GetGenericIndexer <Int32>();

                foreach (var s in segments.Where(s => s.Circularity <= 0.9))
                {
                    int distancia = 0;
                    if (s.Circularity > 0.7)
                    {
                        distancia = 5;
                    }
                    else if (s.Circularity > 0.5)
                    {
                        distancia = 5;
                    }
                    else if (s.Circularity > 0.25)
                    {
                        distancia = 6;
                    }
                    else
                    {
                        distancia = 6;
                    }

                    distancia = (distancia < s.MaxDistance) ? distancia : s.MaxDistance - 1;

                    foreach (var p in s.PixelData.Where(p => p.Distance <= distancia))
                    {
                        if (imagenAberturaRelleno.At <byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0)
                        {
                            indexadorCentroides[p.CoordsXY[0], p.CoordsXY[1]] = 0;
                        }
                    }
                }

                Cv2.Subtract(imagenAberturaRelleno + 255, Centroides, Unknown);

                #region segmentStuff
                //List<int> indexConcavos = segments.Where(s => s.Circularity > 1).Select(s => s.SegmentId).ToList();


                //foreach (var s in segments.Where(s => s.Circularity < 1.1 && s.Circularity > 0.9))
                //{
                //    foreach (var p in s.PixelData/*.Where(p => p.Distance == 1)*/)
                //    {
                //        if (imagenAberturaRelleno.At<byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0)
                //        {
                //            indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255;
                //        }
                //    }
                //}

                //foreach (var s in segments.Where(s => s.Circularity >= 1.1))
                //{
                //    foreach (var p in s.PixelData/*.Where(p => p.Distance == 1)*/)
                //    {
                //        if (imagenAberturaRelleno.At<byte>(p.CoordsXY[0], p.CoordsXY[1]) != (byte)0)
                //        {
                //            indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255;
                //        }
                //    }
                //}

                //foreach (var s in segments)
                //{
                //    s.SetPixelConcavity();
                //    s.Segmentation();
                //    foreach (var p in s.PixelData.Where(p => p.Distance == 1))
                //    {
                //        if (p.Concave == 1)
                //        {
                //            indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255;
                //        }
                //        if (p.Concave == -1)
                //        {
                //            indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 255;
                //        }
                //    }
                //}

                //foreach (var s in segments)
                //{
                //    //s.SetPixelConcavity();
                //    //s.Segmentation();
                //    foreach (var p in s.PixelData.Where(p => p.Distance == 2))
                //    {
                //        indexadorFiguras[p.CoordsXY[0], p.CoordsXY[1]] = 230;
                //    }
                //}

                //imagenAberturaRelleno.CopyTo(SureFg);
                #endregion

                Mat colormap   = new Mat();
                Mat Marcadores = new Mat();
                Cv2.ConnectedComponents(Centroides, Marcadores);
                Marcadores = Marcadores + 1;
                var indexador2 = Marcadores.GetGenericIndexer <Int32>();
                for (int i = 0; i < Unknown.Rows; i++)
                {
                    for (int j = 0; j < Unknown.Cols; j++)
                    {
                        if (Unknown.At <byte>(i, j) == 255)
                        {
                            indexador2[i, j] = 0;
                        }
                    }
                }

                Marcadores.CopyTo(colormap);
                colormap.ConvertTo(colormap, MatType.CV_8UC3);
                Cv2.ApplyColorMap(colormap, colormap, ColormapTypes.Rainbow);
                Cv2.ImWrite("D:\\Dictuc\\marcadores.png", Marcadores);

                //Mat img1 = new Mat();
                //imagen.CopyTo(img1);
                Mat DistColor = new Mat();
                //imagenGrisContraste = 255 - imagenGrisContraste;
                Cv2.CvtColor(imagenAberturaRelleno, DistColor, ColorConversionCodes.GRAY2BGR);
                DistColor.ConvertTo(DistColor, MatType.CV_8U);

                Cv2.Watershed(DistColor, Marcadores);


                Cv2.ImWrite("D:\\Dictuc\\watersheedIn.png", DistColor);

                var indexador4 = imagen.GetGenericIndexer <Vec3i>();
                //for (int i = 0; i < imagen.Rows; i++)
                //{
                //    for (int j = 0; j < imagen.Cols; j++)
                //    {
                //        //if (Centroides.At<byte>(i, j) > 0)
                //        //    indexador4[i, j] = new Vec3i(0, 0, 255);
                //        if (Marcadores.At<Int32>(i, j) == -1)
                //            indexador4[i, j] = new Vec3i(255, 20, 20);
                //    }
                //}


                for (int i = 0; i < imagen.Rows; i++)
                {
                    for (int j = 0; j < imagen.Cols; j++)
                    {
                        //if (Centroides.At<byte>(i, j) > 0)
                        //    indexador4[i, j] = new Vec3i(0, 0, 255);
                        if (imagenBordes.At <char>(i, j) > 0)
                        {
                            indexador4[i, j] = new Vec3i(255, 20, 20);
                        }
                    }
                }

                Mat seg = new Mat();
                Marcadores.CopyTo(seg);
                var indexador5 = seg.GetGenericIndexer <int>();
                for (int i = 0; i < Marcadores.Rows; i++)
                {
                    for (int j = 0; j < Marcadores.Cols; j++)
                    {
                        indexador5[i, j] = (Math.Abs(indexador5[i, j]) > 1) ? 255 : 0;
                    }
                }
                Mat kE1 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 1));
                Cv2.Erode(seg, seg, kE1, iterations: 3);
                int thrs1 = 1500;
                int thrs2 = 1800;
                Mat edge1 = new Mat();
                seg.ConvertTo(seg, MatType.CV_8U);
                Cv2.Canny(seg, edge1, thrs1, thrs2, apertureSize: 5);

                SimpleBlobDetector.Params params1 = new SimpleBlobDetector.Params()
                {
                    MinThreshold        = 0,
                    MaxThreshold        = 255,
                    FilterByArea        = true,
                    MinArea             = 15,
                    FilterByCircularity = false,
                    MinCircularity      = (float)0.01,
                    FilterByConvexity   = false,
                    MinConvexity        = (float)0.1,
                    FilterByInertia     = false,
                    MinInertiaRatio     = (float)0.01,
                };
                SimpleBlobDetector detectorBlobs = SimpleBlobDetector.Create(params1);
                KeyPoint[]         segmentosBlob = detectorBlobs.Detect(edge1);

                Mat segmentosBlobMat = new Mat(1, segmentosBlob.Count(), MatType.CV_32FC1);
                var indexador6       = segmentosBlobMat.GetGenericIndexer <float>();
                for (int i = 0; i < segmentosBlob.Count(); i++)
                {
                    indexador6[0, i] = segmentosBlob[i].Size;
                }

                Mat      hist   = new Mat();
                Rangef[] ranges = { new Rangef(0, (float)segmentosBlob.Max(x => x.Size)) };
                Cv2.CalcHist(new Mat[] { segmentosBlobMat }, new int[] { 0 }, null, hist, 1, new int[] { 100 }, ranges, uniform: true, accumulate: true);
                float[] histAcumulado           = new float[hist.Rows];
                float[] histAcumuladoPorcentaje = new float[11];

                histAcumulado[0] = hist.At <float>(0, 0);

                for (int i = 1; i < hist.Rows; i++)
                {
                    histAcumulado[i] = hist.At <float>(i, 0) + histAcumulado[i - 1];
                }

                int k = 1;
                for (int i = 1; i < histAcumuladoPorcentaje.Count(); i++)
                {
                    for (; k < hist.Rows; k++)
                    {
                        float porcentajeActual    = histAcumulado[k] / segmentosBlob.Count() * 100;
                        float porcentajeAnterior  = histAcumulado[k - 1] / segmentosBlob.Count() * 100;
                        float porcentajeRequerido = (float)((i < 10) ? i * 10 : 99.3);
                        if (porcentajeRequerido <= porcentajeActual)
                        {
                            float tamañoPorcentajeActual        = (float)(k * (float)segmentosBlob.Max(x => x.Size) / 100.0);
                            float tamañoPorcentajeAnterior      = (float)((k - 1) * (float)segmentosBlob.Max(x => x.Size) / 100.0);
                            float tasaVariacionTamañoPorcentaje = (tamañoPorcentajeActual - tamañoPorcentajeAnterior) / (porcentajeActual - porcentajeAnterior);
                            histAcumuladoPorcentaje[i] = tamañoPorcentajeAnterior + tasaVariacionTamañoPorcentaje * (i * 10 - porcentajeAnterior);
                            break;
                        }
                    }
                }

                for (int i = 0; i < histAcumuladoPorcentaje.Count(); i++)
                {
                    Console.Write(histAcumuladoPorcentaje[i] + ",");
                }
                Console.WriteLine("");

                //            data1 = [];

                //              for i in range(0, len(keypoints1)):

                //                data1.append(keypoints1[i].size * coefTamano)
                //                #tamano.write(str(i)+'\t'+str(keypoints1[i].size*2*0.3)+'\n')
                //  cv2.line(im_with_keypoints1, (int(float(keypoints1[i].pt[0] - keypoints1[i].size)), int(float(keypoints1[i].pt[1]))), (int(float(keypoints1[i].pt[0] + keypoints1[i].size)), int(float(keypoints1[i].pt[1]))), (255, 0, 0), 1)

                //                cv2.line(im_with_keypoints1, (int(float(keypoints1[i].pt[0])), int(float(keypoints1[i].pt[1] - keypoints1[i].size))), (int(float(keypoints1[i].pt[0])), int(float(keypoints1[i].pt[1] + keypoints1[i].size))), (255, 0, 0), 1)


                //# print(data1)
                //n1, bins1, patches1 = hist(data1, 200,[0, max(data1)], normed = 100, cumulative = True, bottom = True, histtype = 'stepfilled', align = 'mid', orientation = 'vertical', rwidth = 1, log = False, color = "r")

                //              tamano = open(temp + "instancia_" + instancia + ".txt", "w")


                //              x = np.array(bins1)

                //              y = np.append([0], n1)

                //                  xnew = [x[1], x[21], x[36], x[45], x[53], x[60], x[69], x[78], x[88], x[97], x[200]]
                //ynew = [y[1], y[21], y[36], y[45], y[53], y[60], y[69], y[78], y[88], y[97], y[200]]

                //tamano.write('INSERT INTO [dbo].[Granulometria](Cod_Instancia,Fecha,P_10,P_20,P_30,P_40,P_50,P_60,P_70,P_80,P_90,P_100, Filename) values (')
                //tamano.write(instancia + ",CONVERT(datetime, '" + sys.argv[1][0:4] + "-" + sys.argv[1][4:6] + "-" + sys.argv[1][6:8] + ' ' + sys.argv[1][9:11] + ':' + sys.argv[1][11:13] + ':' + sys.argv[1][13:15] + "', 120)")

                //for j in range(1, len(xnew)):
                //  #tamano.write (str(j)+'\t'+str(round(xnew[j],1))+'\t'+str(round(ynew[j]*100,2))+'\n')
                //  tamano.write(',' + str(round(xnew[j], 1)))

                //tamano.write(",'" + sys.argv[1] + " - Resultado.jpg'")
                //tamano.write(')')

                //CvXImgProc.Thinning(mascaraInv, mascaraInv, ThinningTypes.ZHANGSUEN);

                Mat imWithKeypoints1 = new Mat();
                Cv2.DrawKeypoints(imagen, segmentosBlob, imWithKeypoints1, new Scalar(0, 0, 255), DrawMatchesFlags.DrawRichKeypoints);


                var dataTamaños = segmentosBlob.Select(s => s.Size).ToArray();


                Cv2.ImWrite("D:\\Dictuc\\output0" + numImg + ".png", imagen);
                Cv2.ImWrite("D:\\Dictuc\\output1" + numImg++ + ".png", imWithKeypoints1);

                Cv2.ImShow("Segmentado", imagen);
                Cv2.ImShow("GrisContraste", imagenGrisContraste);
                Cv2.ImShow("bordes90", imagenBordes);
                Cv2.ImShow("bordes50", imagenBordes2);

                salida.Write(imagen);

                //System.Threading.Thread.Sleep(10);
                Cv2.WaitKey(10);

                imagenRuidoFiltrado.Release();
                imagenGrisContraste.Release();
                imagenGrisFrecAltasProc.Release();
                imagenBordes.Release();
                imagenBinaria.Release();
                imagenAberturaRelleno.Release();
            }
        }
        public override object Find()
        {
            initialize();
            CircleSegment[] circles = null;

            Point[][] points = Cv2.FindContoursAsArray(gray, RetrievalModes.List, ContourApproximationModes.ApproxTC89L1);
            for (int i = 0; i < points.Length; i++)
            {
                Mat black = new Mat(gray.Rows, gray.Cols, gray.Type(), new Scalar(0));
                Cv2.DrawContours(black, points, i, new Scalar(255), Cv2.FILLED);
                Cv2.ImShow("contour", black);

                //for more info https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=houghcircles
                circles = Cv2.HoughCircles(black, HoughMethods.Gradient, dp, minDist, cannyThreshold, param2, minRadius, maxRadius);

                // draw the circle detected
                foreach (CircleSegment element in circles)
                {
                    Point center = new Point(Math.Round(element.Center.X), Math.Round(element.Center.Y));
                    Cv2.Circle(outputimg, center, 3, new Scalar(0, 255, 255), 1);
                    Cv2.Circle(outputimg, center, (int)element.Radius, new Scalar(0, 0, 255), 1);
                }

                //compute distance transorm
                Mat dt = new Mat();
                Cv2.Canny(black, canny, cannyThreshold, cannyThreshold / 2);
                Mat wh = new Mat(canny.Rows, canny.Cols, MatType.CV_8UC1, new Scalar(255));
                Cv2.DistanceTransform(wh - canny.GreaterThan(0.0), dt, DistanceTypes.L2, DistanceMaskSize.Mask3);
                //Cv2.ImShow("dt", wh - canny.GreaterThan(0.0));
                //Cv2.WaitKey(0);
                //test for semi-circle
                foreach (CircleSegment element in circles)
                {
                    //test inlier percentage
                    //sample the circle and check for distance to next edge
                    uint counter = 0;
                    uint inlier  = 0;

                    //maximal distance of inlier might depend on the size of the circle
                    //the more close edge the lower distance transform value
                    double maxInlierDist = element.Radius / maxInlierDistRatio;
                    if (maxInlierDist < minInlierDist)
                    {
                        maxInlierDist = minInlierDist;
                    }
                    MatOfFloat mf      = new MatOfFloat(dt);
                    var        indexer = mf.GetIndexer();
                    //TODO maybe parameter incrementation might depend on circle size
                    for (float t = 0; t < 2 * Math.PI; t += 0.1f)
                    {
                        counter++;
                        int cx = (int)(element.Radius * Math.Cos(t) + element.Center.X);
                        int cy = (int)(element.Radius * Math.Sin(t) + element.Center.Y);
                        if (cx < 0 || cy < 0 || cx > dt.Cols || cy >= dt.Rows)
                        {
                            continue;
                        }
                        if (indexer[cy, cx] < maxInlierDist) //carefor the image coordinate
                        {
                            inlier++;
                            Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 255, 255));
                        }
                        else
                        {
                            Cv2.Circle(outputimg, cx, cy, 3, new Scalar(255, 0, 0));
                        }
                    }
                    Console.WriteLine("{0}% of a circle with radius {1} detected",
                                      100 * inlier / counter, element.Radius);
                }
            }
            return(circles);
        }