public void wykrywanie_konturow(int t1, int t2) { Thread.Sleep(50); try { Image <Gray, byte> img = imgInPuzzle.Convert <Gray, byte>(); Image <Gray, byte> img1 = img; Mat graymat = new Mat(); Mat mask = new Mat(); graymat = img1.Mat; CvInvoke.AdaptiveThreshold(graymat, mask, 255, AdaptiveThresholdType.MeanC, ThresholdType.BinaryInv, t1 * 10 - 1, t2); contours = new Emgu.CV.Util.VectorOfVectorOfPoint(); con = new Emgu.CV.Util.VectorOfVectorOfPoint(); Mat hier = new Mat(mask.Rows, mask.Cols, DepthType.Cv8U, 0); CvInvoke.FindContours(mask, contours, hier, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); for (int i = 0; i < contours.Size; i++) { double a = CvInvoke.ContourArea(contours[i], false); if (a > 600 && a < ((mask.Cols * mask.Rows) / 2)) { con.Push(contours[i]); } } CvInvoke.DrawContours(mask, con, -1, new MCvScalar(255, 255, 255), 1); ilosc_konturow.Text = "Liczba konturów: " + con.Size.ToString(); zdj.Source = ToBitmapSource(mask); } catch (System.NullReferenceException) { System.Windows.MessageBox.Show("Wczytaj zdjęcia", "Podpowiadarka do puzzli - Błąd", MessageBoxButton.OK, MessageBoxImage.Error); } }
public void PerformShapeDetection() { if (fileNameTextBox.Text != String.Empty) { Stopwatch watch = Stopwatch.StartNew(); watch.Start(); StringBuilder msgBuilder = new StringBuilder("Performance: "); #region get image img = new Image<Bgr, byte>(fileNameTextBox.Text); img = img.Resize(0.5, Inter.Linear).SmoothMedian(5); #endregion #region HSV magic //min.Hue = MinHueTB.Value; min.Satuation = MinSatTB.Value; min.Value = MinValTB.Value; //max.Hue = MaxHueTB.Value; max.Satuation = MaxSatTB.Value; max.Value = MaxValTB.Value; HsvMagic(img, maskHsvBlack, maskHsvBlue); circleImageBox.Image = maskHsvBlack; originalImageBox.Image = img; img.ToBitmap().Save("C:\\Emgu\\Dump\\Img.png",System.Drawing.Imaging.ImageFormat.Png); maskHsvBlack.ToBitmap().Save("C:\\Emgu\\Dump\\maskHsvBlack.png", System.Drawing.Imaging.ImageFormat.Png); maskHsvBlue.ToBitmap().Save("C:\\Emgu\\Dump\\maskHsvBlue.png", System.Drawing.Imaging.ImageFormat.Png); #endregion #region Canny and edge detection double cannyThreshold = 1.0; double cannyThresholdLinking = 500.0; Image<Gray, Byte> cannyBlue = maskHsvBlue.Canny(cannyThreshold, cannyThresholdLinking); Image<Gray, Byte> cannyBlack = maskHsvBlack.Canny(cannyThreshold, cannyThresholdLinking); watch.Stop(); msgBuilder.Append(String.Format("Hsv and Canny - {0} ms; ", watch.ElapsedMilliseconds)); #endregion cannyBlue.ToBitmap().Save("C:\\Emgu\\Dump\\cannyBlue.png", System.Drawing.Imaging.ImageFormat.Png); cannyBlack.ToBitmap().Save("C:\\Emgu\\Dump\\cannyBlack.png", System.Drawing.Imaging.ImageFormat.Png); #region Find rectangles #region detect black borders VectorOfVectorOfPoint blackborders = new VectorOfVectorOfPoint();//list of black borders List<RotatedRect> Black_boxList = new List<RotatedRect>(); //a box is a rotated rectangle VectorOfVectorOfPoint othercontours_black = new VectorOfVectorOfPoint(); getBlackContours(cannyBlack, blackborders, Black_boxList, othercontours_black); resultImg = cannyBlack.Convert<Bgr, Byte>(); #endregion #region blue borders VectorOfVectorOfPoint blueborders = new VectorOfVectorOfPoint();//list of blue borders List<RotatedRect> Blue_boxList = new List<RotatedRect>(); //a box is a rotated rectangle VectorOfVectorOfPoint othercontours_blue = new VectorOfVectorOfPoint(); getBlueContours(cannyBlue, blueborders, Blue_boxList, othercontours_blue); #endregion #region clear duplicate boxes List<RotatedRect> fltrBlue_boxList = new List<RotatedRect>(); SizeF TMP_SizeF = new SizeF(0,0); PointF TMP_PointF = new PointF(0, 0); float TMP_Angle = 0; if (Blue_boxList.Count >= 2) { for (int i = 1; i < Blue_boxList.Count; i++) { if (Blue_boxList[i - 1].Size.Width * Blue_boxList[i - 1].Size.Height > 750) { if (Math.Abs(Blue_boxList[i - 1].Angle - Blue_boxList[i].Angle) < 1) { if (Math.Abs(Blue_boxList[i - 1].Center.X - Blue_boxList[i].Center.X) < 1 && Math.Abs(Blue_boxList[i - 1].Center.Y - Blue_boxList[i].Center.Y) < 1) if (Math.Abs(Blue_boxList[i - 1].Size.Width - Blue_boxList[i].Size.Width) < 1 && Math.Abs(Blue_boxList[i - 1].Size.Height - Blue_boxList[i].Size.Height) < 1) { TMP_PointF.X = (float)(0.5 * (Blue_boxList[i - 1].Center.X + Blue_boxList[i].Center.X)); TMP_PointF.Y = (float)(0.5 * (Blue_boxList[i - 1].Center.Y + Blue_boxList[i].Center.Y)); TMP_SizeF.Width = (float)(0.5 * (Blue_boxList[i - 1].Size.Width + Blue_boxList[i].Size.Width)); TMP_SizeF.Height = (float)(0.5 * (Blue_boxList[i - 1].Size.Height + Blue_boxList[i].Size.Height)); TMP_Angle = (float)(0.5 * (Blue_boxList[i - 1].Angle + Blue_boxList[i].Angle)); fltrBlue_boxList.Add(new RotatedRect(TMP_PointF, TMP_SizeF, TMP_Angle)); } } else fltrBlue_boxList.Add(Blue_boxList[i]); } } } else { fltrBlue_boxList = Blue_boxList; } //Blue_boxList.Clear(); } List<RotatedRect> fltrBlack_boxList = new List<RotatedRect>(); VectorOfVectorOfPoint fltr_blackborders = new VectorOfVectorOfPoint(); TMP_SizeF.Width = 0; TMP_SizeF.Height = 0; TMP_PointF.X = 0; TMP_PointF.Y = 0; TMP_Angle = 0; if (Black_boxList.Count >= 2) { for (int i = 1; i < Black_boxList.Count; i++) { if (Black_boxList[i - 1].Size.Width * Black_boxList[i - 1].Size.Height > 10) { if (Math.Abs(Black_boxList[i - 1].Angle - Black_boxList[i].Angle) < 1) { if (Math.Abs(Black_boxList[i - 1].Center.X - Black_boxList[i].Center.X) < 1 && Math.Abs(Black_boxList[i - 1].Center.Y - Black_boxList[i].Center.Y) < 1) if (Math.Abs(Black_boxList[i - 1].Size.Width - Black_boxList[i].Size.Width) < 1 && Math.Abs(Black_boxList[i - 1].Size.Height - Black_boxList[i].Size.Height) < 1) { TMP_PointF.X = (float)(0.5 * (Black_boxList[i - 1].Center.X + Black_boxList[i].Center.X)); TMP_PointF.Y = (float)(0.5 * (Black_boxList[i - 1].Center.Y + Black_boxList[i].Center.Y)); TMP_SizeF.Width = (float)(0.5 * (Black_boxList[i - 1].Size.Width + Black_boxList[i].Size.Width)); TMP_SizeF.Height = (float)(0.5 * (Black_boxList[i - 1].Size.Height + Black_boxList[i].Size.Height)); TMP_Angle = (float)(0.5 * (Black_boxList[i - 1].Angle + Black_boxList[i].Angle)); fltrBlack_boxList.Add(new RotatedRect(TMP_PointF, TMP_SizeF, TMP_Angle)); //fltr_blackborders.Push(); } } else fltrBlack_boxList.Add(Black_boxList[i]); } } } else { fltrBlack_boxList = Black_boxList; }//Black_boxList.Clear(); } #endregion ////////// circleImageBox.Image = maskHsvBlack; //////////// CvInvoke.DrawContours(resultImg, blackborders, -1, new Bgr(Color.Green).MCvScalar); CvInvoke.DrawContours(resultImg, othercontours_black, -1, new Bgr(Color.Red).MCvScalar); CvInvoke.DrawContours(resultImg, blueborders, -1, new Bgr(Color.Blue).MCvScalar); foreach (RotatedRect box in fltrBlack_boxList) { CvInvoke.Polylines(resultImg, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Aqua).MCvScalar, 1); } foreach (RotatedRect box in Black_boxList) { CvInvoke.Polylines(img, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Pink).MCvScalar, 1); } foreach (RotatedRect box in Blue_boxList) { CvInvoke.Polylines(img, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.DarkViolet).MCvScalar, 1); } foreach (RotatedRect box in fltrBlue_boxList) { CvInvoke.Polylines(resultImg, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Yellow).MCvScalar, 1); } triangleRectangleImageBox.Image = resultImg; originalImageBox.Image = img; #region save to files Image<Bgr, Byte> TMPImageforSaving = new Image<Bgr, byte>(maskHsvBlack.Width, maskHsvBlack.Height, new Bgr(Color.Black)); CvInvoke.DrawContours(TMPImageforSaving, blackborders, -1, new Bgr(Color.Green).MCvScalar); CvInvoke.DrawContours(TMPImageforSaving, othercontours_black, -1, new Bgr(Color.Red).MCvScalar); foreach (RotatedRect box in Black_boxList) { CvInvoke.Polylines(TMPImageforSaving, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Pink).MCvScalar, 1); } TMPImageforSaving.ToBitmap().Save("C:\\Emgu\\Dump\\NonFltrBlack.png", System.Drawing.Imaging.ImageFormat.Png); TMPImageforSaving = new Image<Bgr, byte>(TMPImageforSaving.Width, TMPImageforSaving.Height, new Bgr(Color.Black)); CvInvoke.DrawContours(TMPImageforSaving, blackborders, -1, new Bgr(Color.Green).MCvScalar); CvInvoke.DrawContours(TMPImageforSaving, othercontours_black, -1, new Bgr(Color.Red).MCvScalar); foreach (RotatedRect box in Blue_boxList) { CvInvoke.Polylines(TMPImageforSaving, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.DarkViolet).MCvScalar, 1); } TMPImageforSaving.ToBitmap().Save("C:\\Emgu\\Dump\\NonFltrBlue.png", System.Drawing.Imaging.ImageFormat.Png); TMPImageforSaving = new Image<Bgr, byte>(maskHsvBlack.Width, maskHsvBlack.Height, new Bgr(Color.Black)); CvInvoke.DrawContours(TMPImageforSaving, blackborders, -1, new Bgr(Color.Green).MCvScalar); CvInvoke.DrawContours(TMPImageforSaving, othercontours_black, -1, new Bgr(Color.Red).MCvScalar); foreach (RotatedRect box in fltrBlack_boxList) { CvInvoke.Polylines(TMPImageforSaving, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Aqua).MCvScalar, 1); } TMPImageforSaving.ToBitmap().Save("C:\\Emgu\\Dump\\FltrBlack.png", System.Drawing.Imaging.ImageFormat.Png); TMPImageforSaving = new Image<Bgr, byte>(TMPImageforSaving.Width, TMPImageforSaving.Height, new Bgr(Color.Black)); CvInvoke.DrawContours(TMPImageforSaving, blackborders, -1, new Bgr(Color.Green).MCvScalar); CvInvoke.DrawContours(TMPImageforSaving, othercontours_black, -1, new Bgr(Color.Red).MCvScalar); foreach (RotatedRect box in fltrBlue_boxList) { CvInvoke.Polylines(TMPImageforSaving, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.Yellow).MCvScalar, 1); } TMPImageforSaving.ToBitmap().Save("C:\\Emgu\\Dump\\FltrBlue.png", System.Drawing.Imaging.ImageFormat.Png); #endregion /* List<VectorOfPoint> contours_for_work = new List<VectorOfPoint>(); using (VectorOfVectorOfPoint contours = blackborders) { for (int i = 0; i < contours.Size; i++) { contours_for_work.Add(contours[i]); } } contours_for_work.Sort((VectorOfPoint cont1, VectorOfPoint cont2) => (bool) (CvInvoke.ContourArea(cont1) > CvInvoke.ContourArea(cont1)) ); */ VectorOfVectorOfPoint Big = new VectorOfVectorOfPoint(); bool ready = false; using (VectorOfVectorOfPoint contours = blackborders) { for (int i = 0; i < contours.Size && !ready; i++) { VectorOfPoint contourI = contours[i]; for (int j = i + 1; j < contours.Size && !ready; j++) { if (0.38 * CvInvoke.ContourArea(contours[j]) > CvInvoke.ContourArea(contourI) && 0.26 * CvInvoke.ContourArea(contours[j]) < CvInvoke.ContourArea(contourI)) { Big.Push(contours[j]); Big.Push(contours[i]); ready = !ready; } } } } TMPImageforSaving = new Image<Bgr, Byte>(resultImg.Width, resultImg.Height, new Bgr(Color.Black)); CvInvoke.DrawContours(TMPImageforSaving, Big, -1, new Bgr(Color.White).MCvScalar); TMPImageforSaving.ToBitmap().Save("C:\\Emgu\\Dump\\DetectedContours.png", System.Drawing.Imaging.ImageFormat.Png); imgHsv[0].ToBitmap().Save("C:\\Emgu\\Dump\\ImgHsv - Hue.png", System.Drawing.Imaging.ImageFormat.Png); imgHsv[1].ToBitmap().Save("C:\\Emgu\\Dump\\ImgHsv - Sat.png", System.Drawing.Imaging.ImageFormat.Png); imgHsv[2].ToBitmap().Save("C:\\Emgu\\Dump\\ImgHsv - Val.png", System.Drawing.Imaging.ImageFormat.Png); Image<Hls, byte> HlsImg = img.Convert<Hls, Byte>(); HlsImg[0].ToBitmap().Save("C:\\Emgu\\Dump\\Img HLS - Hue.png", System.Drawing.Imaging.ImageFormat.Png); HlsImg[1].ToBitmap().Save("C:\\Emgu\\Dump\\Img HLS - Light.png", System.Drawing.Imaging.ImageFormat.Png); HlsImg[2].ToBitmap().Save("C:\\Emgu\\Dump\\Img HLS - Sat.png", System.Drawing.Imaging.ImageFormat.Png); lineImageBox.Image = TMPImageforSaving; watch.Stop(); msgBuilder.Append(String.Format("Triangles & Rectangles - {0} ms; ", watch.ElapsedMilliseconds)); #endregion /* lineImageBox.Image = resultImg; originalImageBox.Image = img; this.Text = msgBuilder.ToString(); #region draw and rectangles Mat triangleRectangleImage = new Mat(img.Size, DepthType.Cv8U, 3); triangleRectangleImage.SetTo(new MCvScalar(0)); foreach (RotatedRect box in boxList) { CvInvoke.Polylines(triangleRectangleImage, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.DarkOrange).MCvScalar, 2); } triangleRectangleImageBox.Image = triangleRectangleImage; #endregion #region draw lines /*Mat lineImage = new Mat(img.Size, DepthType.Cv8U, 3); lineImage.SetTo(new MCvScalar(0)); foreach (LineSegment2D line in lines) CvInvoke.Line(lineImage, line.P1, line.P2, new Bgr(Color.Green).MCvScalar, 2); lineImageBox.Image = lineImage; #endregion } } #region draw //foreach (LineSegment2D line in lines) //CvInvoke.Line(lineImage, line.P1, line.P2, new Bgr(Color.Green).MCvScalar, 2); #endregion * */ } }
public void getBlueContours(Image<Gray, Byte> src, VectorOfVectorOfPoint blueborders, List<RotatedRect> Blue_boxList, VectorOfVectorOfPoint othercontours_blue) { //blueborders = new VectorOfVectorOfPoint();//list of blue borders //Blue_boxList = new List<RotatedRect>(); //a box is a rotated rectangle //othercontours_blue = new VectorOfVectorOfPoint(); using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(src, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); for (int i = 0; i < contours.Size; i++) { using (VectorOfPoint contour = contours[i]) using (VectorOfPoint approxContour = new VectorOfPoint()) { CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 250 && CvInvoke.BoundingRectangle(approxContour).Width * CvInvoke.BoundingRectangle(approxContour).Height > 1000) //only consider contours with area greater than 250 { if (approxContour.Size == 4) { Blue_boxList.Add(CvInvoke.MinAreaRect(approxContour)); blueborders.Push(contour); } else { othercontours_blue.Push(contour); //Point[] pts = approxContour.ToArray(); //other.Add(PointCollection.PolyLine(pts, true)); } } } } } }
public void getBlackContours(Image<Gray, Byte> src, VectorOfVectorOfPoint blackborders, List<RotatedRect> Black_boxList, VectorOfVectorOfPoint othercontours_black) { //blackborders = new VectorOfVectorOfPoint();//list of black borders //Black_boxList = new List<RotatedRect>(); //a box is a rotated rectangle //othercontours_black = new VectorOfVectorOfPoint(); Bitmap TMPGood = new Bitmap(src.ToBitmap() , src.Width, src.Height); Bitmap TMPBad = new Bitmap(src.ToBitmap(), src.Width, src.Height); Graphics gGood = Graphics.FromImage(TMPGood); Graphics gBad = Graphics.FromImage(TMPBad); //Pen RedPen = new Pen(Color.Red); //Pen GreenPen = new Pen(Color.Green); Brush RedBrush = new SolidBrush(Color.Red); Brush GreenBrush = new SolidBrush(Color.Green); using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(src, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); for (int i = 0; i < contours.Size; i++) { using (VectorOfPoint contour = contours[i]) using (VectorOfPoint approxContour = new VectorOfPoint()) { Point[] ptsContour = contour.ToArray(); for (int k = 0; k < ptsContour.Length; k++) { gBad.FillEllipse(RedBrush, ptsContour[k].X, ptsContour[k].Y, 6, 6); } CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250 { Point[] ptsApprox = approxContour.ToArray(); //TMP.Draw(pts, new Bgr(Color.DarkOrange), 5); //!!!!!!!!!!!!!!! for (int k = 0; k < ptsApprox.Length; k++) { gGood.FillEllipse(GreenBrush, ptsApprox[k].X, ptsApprox[k].Y, 6, 6); } if (CvInvoke.ContourArea(approxContour, false) > 250 && approxContour.Size == 4) { Black_boxList.Add(CvInvoke.MinAreaRect(approxContour)); blackborders.Push(contour); } else { othercontours_black.Push(contour); //Point[] pts = approxContour.ToArray(); //other.Add(PointCollection.PolyLine(pts, true)); } } } } } TMPGood.Save("C:\\Emgu\\Dump\\Black contour corners GOOD.png", System.Drawing.Imaging.ImageFormat.Png); TMPBad.Save("C:\\Emgu\\Dump\\Black contour corners BAD.png", System.Drawing.Imaging.ImageFormat.Png); }
VectorOfVectorOfPoint FindBlobs(Mat binary, int index) { VectorOfVectorOfPoint blobs = new VectorOfVectorOfPoint(); // Fill the label_image with the blobs // 0 - background // 1 - unlabelled foreground // 2+ - labelled foreground Mat label_image = new Mat(); binary.ConvertTo(label_image, DepthType.Cv8U); int label_count = 2; // starts at 2 because 0,1 are used already for (int y = 0; y < label_image.Rows; y++) { for (int x = 0; x < label_image.Cols; x++) { var val = label_image.GetData(y, x)[0]; if (val != 255) { continue; } System.Drawing.Rectangle rect; CvInvoke.FloodFill(label_image, new Mat(), new System.Drawing.Point(x, y), new MCvScalar(label_count), out rect, new MCvScalar(0), new MCvScalar(0), Connectivity.FourConnected, FloodFillType.Default); //cv::floodFill(label_image, cv::Point(x,y), label_count, &rect, 0, 0, 4); VectorOfPoint blob = new VectorOfPoint(); for (int i = rect.Y; i < (rect.Y + rect.Height); i++) { for (int j = rect.X; j < (rect.X + rect.Width); j++) { var val2 = label_image.GetData(y, x)[0]; if (val2 != label_count) { continue; } blob.Push(new System.Drawing.Point[] { new System.Drawing.Point(j, i) }); } } blobs.Push(blob); label_count++; } } label_image.Save("labeled" + index + ".bmp"); return blobs; }