Beispiel #1
0
        private Bitmap CreateObjectMaskNew(Bitmap image, out Mat image_mask,
                                           out double mask_length, out double mask_area, out double mask_width, out double mask_height,
                                           out double mask_pvheight, double kThresh, double hThresh, double canny1, double canny2,
                                           out Mat image_mask_spc, out double mask2_area, int brightAreaThreshold = -1, int darkAreaThreshold = -1)
        {
            Bitmap dst = null;

            image_mask     = null;
            image_mask_spc = null;
            mask_length    = mask_area = mask_width = mask_height = mask_pvheight = mask2_area = 0;

            try
            {
                Mat src = BitmapConverter.ToMat(image);

                Mat src_kirsch = BitmapConverter.ToMat(image.KirschFilter());

                Mat kirsch_gray = new Mat();
                Cv2.CvtColor(src_kirsch, kirsch_gray, ColorConversionCodes.RGB2GRAY);

                Mat kirsch_threshold = new Mat();
                Cv2.Threshold(kirsch_gray, kirsch_threshold, kThresh, 255, ThresholdTypes.Binary);


                Mat[] contours;
                List <OpenCvSharp.Point> hierarchy;
                List <Mat> hulls;
                Mat        morph_element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(2, 2), new OpenCvSharp.Point(1, 1));

                #region morphology

                Mat kirsch_threshold_copy = new Mat();
                kirsch_threshold.CopyTo(kirsch_threshold_copy);

                int hullCount = 0, numLoops = 0;
                do
                {
                    numLoops++;

                    Mat kirsch_morph = kirsch_threshold_copy.MorphologyEx(MorphTypes.Gradient, morph_element);

                    hierarchy = new List <OpenCvSharp.Point>();
                    Cv2.FindContours(kirsch_morph, out contours, OutputArray.Create(hierarchy),
                                     RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                    hulls = new List <Mat>();
                    for (int j = 0; j < contours.Length; j++)
                    {
                        Mat hull = new Mat();
                        Cv2.ConvexHull(contours[j], hull);
                        hulls.Add(hull);
                    }

                    Mat drawing = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                    Cv2.DrawContours(drawing, hulls, -1, Scalar.White);

                    if (hulls.Count != hullCount && numLoops < 100)
                    {
                        hullCount             = hulls.Count;
                        kirsch_threshold_copy = drawing;
                    }
                    else
                    {
                        break;
                    }
                } while (true);

                #endregion

                if (numLoops >= 100)
                {
                    throw new Exception("Could not find hull");
                }

                #region bestHull
                //try and filter out dust near to stone

                double largestArea = hulls.Max(m => Cv2.ContourArea(m));
                var    bestHulls   = hulls.Where(m => Cv2.ContourArea(m) == largestArea).ToList();

                Mat hulls_mask = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                Cv2.DrawContours(hulls_mask, bestHulls, -1, Scalar.White, -1);

                //hulls_mask is the convex hull of outline, now look for clefts
                Cv2.Threshold(kirsch_gray, kirsch_threshold, hThresh, 255, ThresholdTypes.Binary);
                Mat kirsch_mask = Mat.Zeros(kirsch_threshold.Size(), kirsch_threshold.Type());
                kirsch_threshold.CopyTo(kirsch_mask, hulls_mask);

                Mat kirsch_mask_canny = new Mat();
                Cv2.Canny(kirsch_mask, kirsch_mask_canny, canny1, canny2, 3);

                morph_element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(2, 2));
                Mat kirsch_filled = new Mat();
                Cv2.Dilate(kirsch_mask_canny, kirsch_filled, morph_element);
                Cv2.Dilate(kirsch_filled, kirsch_filled, morph_element);
                Cv2.Erode(kirsch_filled, kirsch_filled, morph_element);
                Cv2.Erode(kirsch_filled, kirsch_filled, morph_element);

                hierarchy = new List <OpenCvSharp.Point>();;
                Cv2.FindContours(kirsch_filled, out contours, OutputArray.Create(hierarchy),
                                 RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                #endregion

                hulls_mask = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                Cv2.DrawContours(hulls_mask, contours, -1, Scalar.White, -1);

                Cv2.Erode(hulls_mask, hulls_mask, morph_element);
                Cv2.Erode(hulls_mask, hulls_mask, morph_element);

                image_mask = hulls_mask;

                //remove bright areas
                if ((brightAreaThreshold > -1) || (darkAreaThreshold > -1))
                {
                    Mat src_mask       = new Mat();
                    Mat hulls_mask_spc = hulls_mask.Clone();
                    src.CopyTo(src_mask, hulls_mask_spc);
                    Mat gray = new Mat();

                    Cv2.CvtColor(src_mask, gray, ColorConversionCodes.BGR2GRAY);
                    if (brightAreaThreshold > -1)
                    {
                        Mat bright = new Mat();
                        Cv2.Threshold(gray, bright, brightAreaThreshold, 255, ThresholdTypes.BinaryInv);
                        Cv2.ImWrite(@"C:\gColorFancy\Image\bright.jpg", bright);
                        Mat t = new Mat();
                        hulls_mask_spc.CopyTo(t, bright);
                        hulls_mask_spc = t.Clone();
                    }
                    if (darkAreaThreshold > -1)
                    {
                        Mat dark = new Mat();
                        Cv2.Threshold(gray, dark, darkAreaThreshold, 255, ThresholdTypes.Binary);
                        Cv2.ImWrite(@"C:\gColorFancy\Image\dark.jpg", dark);
                        Mat t = new Mat();
                        hulls_mask_spc.CopyTo(t, dark);
                        hulls_mask_spc = t.Clone();
                    }

                    image_mask_spc = hulls_mask_spc;

                    var hierarchy2 = new List <OpenCvSharp.Point>();;
                    Cv2.FindContours(hulls_mask_spc, out contours, OutputArray.Create(hierarchy2),
                                     RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                    largestArea = contours.Max(m => Cv2.ContourArea(m));
                    Mat finalHullSpc = contours.Where(m => Cv2.ContourArea(m) == largestArea).ToList()[0];

                    if (ConvexHullOnMask)
                    {
                        Mat hull = new Mat();
                        Cv2.ConvexHull(finalHullSpc, hull);
                        Mat polySpc = new Mat();
                        Cv2.ApproxPolyDP(hull, polySpc, 3, true);
                        mask2_area = Cv2.ContourArea(polySpc);
                    }
                    else
                    {
                        mask2_area = largestArea;
                    }
                }
                ///////////////////////////

                hierarchy = new List <OpenCvSharp.Point>();;
                Cv2.FindContours(hulls_mask, out contours, OutputArray.Create(hierarchy),
                                 RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                largestArea = contours.Max(m => Cv2.ContourArea(m));
                Mat finalHull = contours.Where(m => Cv2.ContourArea(m) == largestArea).ToList()[0];

                if (ConvexHullOnMask)
                {
                    var hull = new Mat();
                    Cv2.ConvexHull(finalHull, hull);
                    finalHull = hull;
                }
                List <Mat> finalHulls = new List <Mat>();
                finalHulls.Add(finalHull);
                Cv2.DrawContours(src, finalHulls, -1, new Scalar(128, 0, 128, 255), 3);

                #region bounding

                Mat poly = new Mat();
                Cv2.ApproxPolyDP(finalHull, poly, 3, true);
                Rect boundaryRect = Cv2.BoundingRect(poly);
                mask_width  = boundaryRect.Width;
                mask_height = boundaryRect.Height;
                if (ConvexHullOnMask)
                {
                    mask_area = Cv2.ContourArea(poly);
                }
                else
                {
                    mask_area = largestArea;
                }
                mask_length = Cv2.ArcLength(finalHull, true);

                List <OpenCvSharp.Point> finalPoints = new List <OpenCvSharp.Point>();
                int m1Count            = (finalHull.Rows % 2 > 0) ? finalHull.Rows + 1 : finalHull.Rows;
                OpenCvSharp.Point[] p1 = new OpenCvSharp.Point[m1Count];
                finalHull.GetArray(0, 0, p1);
                Array.Resize(ref p1, finalHull.Rows);
                finalPoints.AddRange(p1.ToList());

                double y_min   = boundaryRect.Bottom;
                double y_x_min = finalPoints.Where(p => p.X == boundaryRect.Left).ToList()[0].Y;
                double y_x_max = finalPoints.Where(p => p.X == boundaryRect.Right).ToList()[0].Y;

                mask_pvheight = ((double)y_x_max + (double)y_x_min) / 2 - (double)y_min;

                #endregion

                //dst = BitmapConverter.ToBitmap(src);
                using (var ms = src.ToMemoryStream())
                {
                    dst = (Bitmap)Image.FromStream(ms);
                }

                try
                {
                    if (saveMaskDataPath.Length > 0)
                    {
                        //StringBuilder sb = new StringBuilder();
                        //sb.AppendLine("mask_length,mask_area,mask_width,mask_height,mask_pvheight");
                        //sb.AppendLine(mask_length + "," + mask_area + "," + mask_width + "," + mask_height + "," + mask_pvheight);
                        image_mask.SaveImage(saveMaskDataPath + @"\image_mask.jpg");
                        if (image_mask_spc != null)
                        {
                            image_mask_spc.SaveImage(saveMaskDataPath + @"\image_mask_spc.jpg");
                        }
                        BitmapConverter.ToMat(image).SaveImage(saveMaskDataPath + @"\src.jpg");
                        //File.WriteAllText(saveMaskDataPath + @"\mask_vals.csv", sb.ToString());
                        //File.AppendAllText(saveMaskDataPath + @"\exception.txt", DateTime.Now + ":" + av.Message);
                        //File.AppendAllText(saveMaskDataPath + @"\exception.txt", DateTime.Now + ":" + av.StackTrace);
                        //File.AppendAllText(saveMaskDataPath + @"\exception.txt", DateTime.Now + ":" + av.Source);
                    }
                }
                catch
                {
                }
            }
            catch (Exception ex)
            {
                dst = null;
            }

            return(dst);
        }
Beispiel #2
0
        private void buttonSelectImage_Click2(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    List <OpenCvSharp.Point> rois = new List <OpenCvSharp.Point>(new OpenCvSharp.Point[] {
                        new OpenCvSharp.Point(35, 90), new OpenCvSharp.Point(400, 90), new OpenCvSharp.Point(850, 90), new OpenCvSharp.Point(1290, 90),
                        new OpenCvSharp.Point(35, 400), new OpenCvSharp.Point(400, 400), new OpenCvSharp.Point(850, 400), new OpenCvSharp.Point(1290, 400),
                        new OpenCvSharp.Point(35, 800), new OpenCvSharp.Point(400, 800), new OpenCvSharp.Point(850, 800), new OpenCvSharp.Point(1290, 800),
                        new OpenCvSharp.Point(35, 1230), new OpenCvSharp.Point(400, 1230), new OpenCvSharp.Point(850, 1230), new OpenCvSharp.Point(1290, 1230)
                    });
                    var files = Directory.GetFiles(Path.GetDirectoryName(openFileDialog1.FileName), "*.png").ToList();
                    if (files != null && files.Count > 0)
                    {
                        int index = files.IndexOf(openFileDialog1.FileName);
                        //using (var win = new Window())
                        //using (var win1 = new Window())
                        {
                            while (true)
                            {
                                Debug.WriteLine(files[index]);
                                Mat img = new Mat(files[index]);//load color image
                                Mat gray = new Mat(), laplacian = new Mat(), sobel = new Mat(), canny = new Mat();
                                Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
                                //Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(3, 3), 0);
                                Cv2.NamedWindow("img", WindowMode.Normal);
                                Cv2.ImShow("img", img);

                                foreach (var pt in rois)
                                {
                                    Rect roi      = new Rect(pt, new OpenCvSharp.Size(200, 200));
                                    Mat  original = img.Clone(roi);
                                    Mat  gray2    = gray.Clone(roi);
                                    Cv2.Canny(gray2, canny, 100, 300, 3);


                                    Mat[] contours1;
                                    var   hierarchy1 = new List <OpenCvSharp.Point>();
                                    Cv2.FindContours(canny, out contours1, OutputArray.Create(hierarchy1),
                                                     RetrievalModes.External,
                                                     ContourApproximationModes.ApproxSimple);

                                    var hulls1 = new List <Mat>();
                                    for (int j = 0; j < contours1.Length; j++)
                                    {
                                        Mat hull = new Mat();
                                        Cv2.ConvexHull(contours1[j], hull);
                                        if (hull.ContourArea() > 100)
                                        {
                                            hulls1.Add(hull);
                                        }
                                    }

                                    if (hulls1.Count > 0)
                                    {
                                        Mat drawing = Mat.Zeros(canny.Size(), MatType.CV_8UC1);
                                        Cv2.DrawContours(drawing, hulls1, -1, Scalar.White, -1);
                                        //Cv2.NamedWindow(pt.ToString() + " hulls", WindowMode.Normal);
                                        //Cv2.ImShow(pt.ToString() + " hulls", drawing);

                                        List <OpenCvSharp.Point> points = new List <OpenCvSharp.Point>();
                                        foreach (Mat hull in hulls1)
                                        {
                                            int m2Count            = (hull.Rows % 2 > 0) ? hull.Rows + 1 : hull.Rows;
                                            OpenCvSharp.Point[] p2 = new OpenCvSharp.Point[m2Count];
                                            hull.GetArray(0, 0, p2);
                                            Array.Resize(ref p2, hull.Rows);

                                            points.AddRange(p2.ToList());
                                        }
                                        Mat finalHull = new Mat();
                                        Cv2.ConvexHull(InputArray.Create(points), finalHull);

                                        if (finalHull.ContourArea() > 1000)
                                        {
                                            List <Mat> finalHulls = new List <Mat>();
                                            finalHulls.Add(finalHull);
                                            Mat mask = Mat.Zeros(drawing.Size(), MatType.CV_8UC1);
                                            Cv2.DrawContours(mask, finalHulls, -1, Scalar.White, -1);

                                            //Cv2.ImShow(pt.ToString() + " mask", mask);
                                            //Cv2.ImShow(pt.ToString() + " original", original);
                                            Mat masked = Mat.Zeros(original.Size(), original.Type());
                                            original.CopyTo(masked, mask);
                                            Cv2.ImShow(pt.ToString() + " masked", masked);
                                        }
                                    }
                                }



                                int c = Cv2.WaitKey(0);

                                if (c == 'n' && index < files.Count - 1)
                                {
                                    index++;
                                }
                                else if (c == 'p' && index > 0)
                                {
                                    index--;
                                }
                                else if (c == 27)
                                {
                                    break;
                                }
                                else
                                {
                                    index = 0;
                                }

                                Window.DestroyAllWindows();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }
Beispiel #3
0
        private Bitmap CreateObjectMaskMelee(Bitmap image, out Mat image_mask,
                                             out double mask_length, out double mask_area, out double mask_width, out double mask_height,
                                             out double mask_pvheight, bool useKthresholdLab = false)
        {
            Bitmap dst = null;

            image_mask  = null;
            mask_length = mask_area = mask_width = mask_height = mask_pvheight = 0;

            try
            {
                Mat src = BitmapConverter.ToMat(image);

                Mat src_kirsch = BitmapConverter.ToMat(image.KirschFilter());

                Mat kirsch_gray = new Mat();
                Cv2.CvtColor(src_kirsch, kirsch_gray, ColorConversionCodes.RGB2GRAY);

                Mat kirsch_threshold = new Mat();
                if (!useKthresholdLab)
                {
                    Cv2.Threshold(kirsch_gray, kirsch_threshold, kThreshold, 255, ThresholdTypes.Binary);
                }
                else
                {
                    Cv2.Threshold(kirsch_gray, kirsch_threshold, kThresholdLab, 255, ThresholdTypes.Binary);
                }

                Mat[] contours;
                List <OpenCvSharp.Point> hierarchy;
                List <Mat> hulls;
                Mat        morph_element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(2, 2), new OpenCvSharp.Point(1, 1));

                #region morphology

                Mat kirsch_threshold_copy = new Mat();
                kirsch_threshold.CopyTo(kirsch_threshold_copy);

                int hullCount = 0, numLoops = 0;
                do
                {
                    numLoops++;

                    Mat kirsch_morph = kirsch_threshold_copy.MorphologyEx(MorphTypes.Gradient, morph_element);

                    hierarchy = new List <OpenCvSharp.Point>();
                    Cv2.FindContours(kirsch_morph, out contours, OutputArray.Create(hierarchy),
                                     RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                    hulls = new List <Mat>();
                    for (int j = 0; j < contours.Length; j++)
                    {
                        Mat hull = new Mat();
                        Cv2.ConvexHull(contours[j], hull);
                        hulls.Add(hull);
                    }

                    Mat drawing = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                    Cv2.DrawContours(drawing, hulls, -1, Scalar.White);

                    if (hulls.Count != hullCount && numLoops < 100)
                    {
                        hullCount             = hulls.Count;
                        kirsch_threshold_copy = drawing;
                    }
                    else
                    {
                        break;
                    }
                } while (true);

                #endregion

                if (numLoops >= 100)
                {
                    throw new Exception("Could not find hull");
                }

                #region bestHull
                //try and filter out dust near to stone

                double largestArea = hulls.Max(m => Cv2.ContourArea(m));
                var    bestHulls   = hulls.Where(m => Cv2.ContourArea(m) == largestArea).ToList();

                Mat hulls_mask = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                Cv2.DrawContours(hulls_mask, bestHulls, -1, Scalar.White, -1);

                //hulls_mask is the convex hull of main outline excluding nearby dust
                Cv2.Threshold(kirsch_gray, kirsch_threshold, hullThreshold, 255, ThresholdTypes.Binary);
                Mat kirsch_mask = Mat.Zeros(kirsch_threshold.Size(), kirsch_threshold.Type());
                kirsch_threshold.CopyTo(kirsch_mask, hulls_mask);

                #endregion

                hierarchy = new List <OpenCvSharp.Point>();;
                Cv2.FindContours(kirsch_mask, out contours, OutputArray.Create(hierarchy),
                                 RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));

                List <OpenCvSharp.Point> points = new List <OpenCvSharp.Point>();
                foreach (Mat contour in contours)
                {
                    int m2Count            = (contour.Rows % 2 > 0) ? contour.Rows + 1 : contour.Rows;
                    OpenCvSharp.Point[] p2 = new OpenCvSharp.Point[m2Count];
                    contour.GetArray(0, 0, p2);
                    Array.Resize(ref p2, contour.Rows);

                    points.AddRange(p2.ToList());
                }
                Mat finalHull = new Mat();
                Cv2.ConvexHull(InputArray.Create(points), finalHull);


                List <Mat> finalHulls = new List <Mat>();
                finalHulls.Add(finalHull);
                Cv2.DrawContours(src, finalHulls, -1, new Scalar(128, 0, 128, 255), 2);

                hulls_mask = Mat.Zeros(src.Size(), MatType.CV_8UC1);
                Cv2.DrawContours(hulls_mask, finalHulls, -1, Scalar.White, -1);
                image_mask = hulls_mask;

                #region bounding

                Mat poly = new Mat();
                Cv2.ApproxPolyDP(finalHull, poly, 3, true);
                Rect boundaryRect = Cv2.BoundingRect(poly);
                mask_width  = boundaryRect.Width;
                mask_height = boundaryRect.Height;
                mask_area   = Cv2.ContourArea(poly);
                mask_length = Cv2.ArcLength(finalHull, true);

                List <OpenCvSharp.Point> finalPoints = new List <OpenCvSharp.Point>();
                int m1Count            = (finalHull.Rows % 2 > 0) ? finalHull.Rows + 1 : finalHull.Rows;
                OpenCvSharp.Point[] p1 = new OpenCvSharp.Point[m1Count];
                finalHull.GetArray(0, 0, p1);
                Array.Resize(ref p1, finalHull.Rows);
                finalPoints.AddRange(p1.ToList());

                double y_min   = boundaryRect.Bottom;
                double y_x_min = finalPoints.Where(p => p.X == boundaryRect.Left).ToList()[0].Y;
                double y_x_max = finalPoints.Where(p => p.X == boundaryRect.Right).ToList()[0].Y;

                mask_pvheight = ((double)y_x_max + (double)y_x_min) / 2 - (double)y_min;

                #endregion

                //dst = BitmapConverter.ToBitmap(src);
                using (var ms = src.ToMemoryStream())
                {
                    dst = (Bitmap)Image.FromStream(ms);
                }

                try
                {
                    if (saveMaskDataPath.Length > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("mask_length,mask_area,mask_width,mask_height,mask_pvheight");
                        sb.AppendLine(mask_length + "," + mask_area + "," + mask_width + "," + mask_height + "," + mask_pvheight);
                        image_mask.SaveImage(saveMaskDataPath + @"\image_mask.jpg");
                        File.WriteAllText(saveMaskDataPath + @"\mask_vals.csv", sb.ToString());
                    }
                }
                catch
                {
                }
            }
            catch
            {
                dst = null;
            }

            return(dst);
        }