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); }
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); } } }
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); }