internal static void DrawHintPoints(Mat sourceImage, List <Point> pts) { sourceImage.Circle(pts[0], 15, Scalar.Yellow, 3, LineTypes.AntiAlias, 0); //yellow sourceImage.Circle(pts[1], 15, Scalar.Green, 3, LineTypes.AntiAlias, 0); //green sourceImage.Circle(pts[2], 15, Scalar.Red, 3, LineTypes.AntiAlias, 0); //red sourceImage.Circle(pts[3], 15, Scalar.Blue, 3, LineTypes.AntiAlias, 0); //blue }
public Point2d IntersectionPoint(FuncApproximation F1, FuncApproximation F2, Point2d PtA, Point2d PtB, bool DispB = false) { this.F1 = F1; this.F2 = F2; Point Pt0 = (Point)((PtA + PtB) * 0.5); RegFuncUtilitySub FS1 = new RegFuncUtilitySub(F1, PtA, PtB); RegFuncUtilitySub FS2 = new RegFuncUtilitySub(F2, PtA, PtB); Point2d PtAns = new Point2d(); Mat resImg = null; try{ if (DispB) { resImg = ImgCheck.CvtColor(ColorConversionCodes.GRAY2BGR); //Gray->Color変換 for (int x = 0; x < ImgCheck.Width; x += 20) { Point P1 = new Point(x, F1.RegXY.Estimate(x)); Point P2 = P1 + (new Point(4, 4)); resImg.Rectangle(P1, P2, Scalar.Orange, 3); } for (int y = 0; y < ImgCheck.Height; y += 20) { Point P1 = new Point(F2.RegXY.Estimate(y), y); Point P2 = P1 + (new Point(4, 4)); resImg.Rectangle(P1, P2, Scalar.Blue, 3); } resImg.Circle(Pt0, 10, Scalar.Red, 5); using (new Window("IntersectionPoint", WindowMode.KeepRatio, resImg)){ Cv2.WaitKey(0); } } Point2d PtAns2 = F2.EstimatePt2Pt(Pt0), PtAns1 = Pt0; int loop = 5; while (--loop > 0) { double vAns1 = FS1.__Solve(PtAns2, ref PtAns1); if (DispB) { resImg.Circle((Point)PtAns2, 5, Scalar.Blue, 3); resImg.Circle((Point)PtAns1, 5, Scalar.Red, loop * 2); using (new Window("IntersectionPoint", WindowMode.KeepRatio, resImg)){ Cv2.WaitKey(0); } } double vAns2 = FS2.__Solve(PtAns1, ref PtAns2); if (DispB) { resImg.Circle((Point)PtAns2, 5, Scalar.Red, 3); resImg.Circle((Point)PtAns1, 5, Scalar.Blue, loop * 2); using (new Window("IntersectionPoint", WindowMode.KeepRatio, resImg)){ Cv2.WaitKey(0); } } if (vAns1 < 0.01 && vAns2 < 0.01) { break; } FS1.SetRange(PtA, PtB); FS2.SetRange(PtA, PtB); } PtAns = FS1.Estimate(PtAns2); } catch (Exception e) { WriteLine(e.Message + "\r" + e.StackTrace); } return(PtAns); }
public void Run() { Mat src = new Mat(FilePath.Image.Girl, ImreadModes.Color); Mat dst = new Mat(FilePath.Image.Lenna, ImreadModes.Color); Mat src0 = src.Resize(dst.Size(), 0, 0, InterpolationFlags.Lanczos4); Mat mask = Mat.Zeros(src0.Size(), MatType.CV_8UC3); mask.Circle(200, 200, 100, Scalar.White, -1); Mat blend1 = new Mat(); Mat blend2 = new Mat(); Mat blend3 = new Mat(); Cv2.SeamlessClone( src0, dst, mask, new Point(260, 270), blend1, SeamlessCloneMethods.NormalClone); Cv2.SeamlessClone( src0, dst, mask, new Point(260, 270), blend2, SeamlessCloneMethods.MonochromeTransfer); Cv2.SeamlessClone( src0, dst, mask, new Point(260, 270), blend3, SeamlessCloneMethods.MixedClone); using (new Window("src", src0)) using (new Window("dst", dst)) using (new Window("mask", mask)) using (new Window("blend NormalClone", blend1)) using (new Window("blend MonochromeTransfer", blend2)) using (new Window("blend MixedClone", blend3)) { Cv2.WaitKey(); } }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private void CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); Point[][] contours; Rect[] bboxes; mser.DetectRegions(gray, out contours, out bboxes); foreach (Point[] pts in contours) { Scalar color = Scalar.RandomColor(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } //Cv2.Rectangle(dst, bboxes, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); foreach (var item in bboxes) { Cv2.Rectangle(dst, item, Scalar.Red); } }
public static void FindCompasses() { Mat source = new Mat("res3/compass_tests.png"); Window w0 = new Window(source); //Convert input images to gray Mat reds = Levels(source, channel: 2); reds = IsolateYellow(source); Window w239048 = new Window(reds); // these parameters were tuned using the test functionality CircleSegment[] circles = Cv2.HoughCircles(reds, HoughMethods.Gradient, dp: 2f, // this was tuned by experimentation minDist: 20, // this is huge so we only find the best one param1: 200, // this was tuned by experimentation param2: 30, // this is quite low so we usually find something minRadius: 22, maxRadius: 28); foreach (CircleSegment c in circles) { source.Circle(c.Center, (int)c.Radius, new Scalar(0, 255, 0)); } Window w1 = new Window(source); }
private Mat GetCircleMasked(Mat frame) { Mat bin = frame.ConvertScaleAbs(255); if (DebugMode) { Cv2.ImShow("CircleBin", bin); //bin.SaveImage("CircleBin.png"); } CircleSegment[] cs = Cv2.HoughCircles(bin, HoughMethods.Gradient, 1.1f, 5, 20, 20, 5, 100); Mat mask = new Mat(frame.Size(), MatType.CV_8UC1, Scalar.Black); foreach (CircleSegment c in cs) { mask.Circle(c.Center, (int)c.Radius, Scalar.White, -1); } if (DebugMode) { Cv2.ImShow("CircleMask", mask); } Mat masked = new Mat(); frame.CopyTo(masked, mask); if (DebugMode) { Cv2.ImShow("CircleMasked", masked); } return(masked); }
// Update is called once per frame private void Update() { var m = new Mat(_bodyManager.BodyIndexrHeight, _bodyManager.BodyIndexWidth, MatType.CV_8UC4, _bodyManager.RawData); using (cameraFeed = m) { var grayScaleMat = new Mat(); Cv2.CvtColor(cameraFeed, grayScaleMat, ColorConversionCodes.BGR2GRAY); Cv2.GaussianBlur(grayScaleMat, grayScaleMat, new Size(9, 9), 0); var circles = Cv2.HoughCircles(grayScaleMat, HoughMethods.Gradient, _dp, _minDist, _param1, _param2, _minRadius, _maxRadius); if (useMorphOps) { MorphOps(grayScaleMat); } CircleSegment?definitiveCircle = null; var height = 0f; foreach (var circle in circles) { var ballCenter = circle.Center.X / grayScaleMat.Width; var leftElbow = Camera.main.WorldToScreenPoint(new Vector3(_inputData.ElbowLeftPosition.x / 2, _inputData.ElbowLeftPosition.y / 2, _inputData.ElbowLeftPosition.z)).x / Camera.main.pixelWidth; var rightElbow = Camera.main.WorldToScreenPoint(new Vector3(_inputData.ElbowRightPosition.x / 2, _inputData.ElbowRightPosition.y / 2, _inputData.ElbowRightPosition.z)).x / Camera.main.pixelWidth; /*cameraFeed.Circle((int)(leftElbow * grayScaleMat.Width), * grayScaleMat.Height / 2, 15, Scalar.AliceBlue, -1);*/ //if (leftElbow < ballCenter && rightElbow > ballCenter) continue; height = (grayScaleMat.Height - circle.Center.Y) / grayScaleMat.Height * _multiplyHeight; height -= _offsetHeight; //transform.position = new Vector3( (circle.Center.X-grayScaleMat.Width/2f )/grayScaleMat.Width* _multiplyWidth + _offsetWidth, // height , transform.position.z ); if (definitiveCircle == null || circle.Radius > definitiveCircle.Value.Radius) { definitiveCircle = circle; } } if (definitiveCircle != null) { _rb.MovePosition(new Vector3((definitiveCircle.Value.Center.X - grayScaleMat.Width / 2f) / grayScaleMat.Width * _multiplyWidth + _offsetWidth, height, transform.position.z)); cameraFeed.Circle(definitiveCircle.Value.Center, (int)definitiveCircle.Value.Radius, Scalar.AliceBlue, -1); } //show frames if (_showFrame) { Cv2.ImShow(windowName2, grayScaleMat); Cv2.ImShow(windowName, cameraFeed); } //Cv2.ImShow(windowName, cameraFeed); //delay 30ms so that screen can refresh. //image will not appear without this waitKey() command Cv2.WaitKey(30); } }
public Mat drawPoints(Mat image, Point[] points, Scalar color) { foreach (Point p in points) { image.Circle(p, 10, color, thickness: 4); } return(image); }
public static Mat drawKeypoints(Mat mat1, KeypointsDetectionInfo[] detections, float visTresh) { Mat mat = mat1.Clone(); for (int i = 0; i < detections.Length; i++) { for (int j = 0; j < detections[i].Points.Length; j++) { mat.Circle((int)detections[i].Points[j].X, (int)detections[i].Points[j].Y, 5, Scalar.AliceBlue, 1); } List <Scalar> clrs = new List <Scalar>(); clrs.Add(Scalar.Red); clrs.Add(Scalar.Yellow); clrs.Add(Scalar.Green); clrs.Add(Scalar.Blue); clrs.Add(Scalar.Black); clrs.Add(Scalar.White); clrs.Add(Scalar.LightGray); clrs.Add(Scalar.LightBlue); clrs.Add(Scalar.MediumVioletRed); clrs.Add(Scalar.Violet); clrs.Add(Scalar.BlueViolet); clrs.Add(Scalar.OrangeRed); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); clrs.Add(Scalar.Orange); for (int j = 0; j < DrawKeypointsPostProcessor.Edges.Length; j += 2) { var i0 = DrawKeypointsPostProcessor.Edges[j]; var i1 = DrawKeypointsPostProcessor.Edges[j + 1]; var p0 = detections[i].Points[i0]; var p1 = detections[i].Points[i1]; mat.Line(new OpenCvSharp.Point(p0.X, p0.Y), new OpenCvSharp.Point(p1.X, p1.Y), clrs[j / 2], 2); } /* if (detections[i].Conf < visTresh) continue; * mat.Rectangle(detections[i].Rect, new OpenCvSharp.Scalar(255, 0, 0), 2); * * var text = Math.Round(detections[i].Conf, 4).ToString(); * if (detections[i].Class != null) * { * int cls = detections[i].Class.Value; * text += $"(cls: {cls} {detections[i].Label})"; * } * var cx = detections[i].Rect.X; * var cy = detections[i].Rect.Y + 12; * mat.Rectangle(new OpenCvSharp.Point(cx, cy + 5), new OpenCvSharp.Point(cx + 250, cy - 15), new Scalar(0, 0, 0), -1); * mat.PutText(text, new OpenCvSharp.Point(cx, cy), * HersheyFonts.HersheyDuplex, 0.5, new Scalar(255, 255, 255));*/ } return(mat); }
/// <summary> /// Try to match (part of) a large green circle on the screen. /// </summary> public CircleSegment FindCorona() { // see the Experiments for how this works Bitmap cropped = CompassSensor.Crop(screen.bitmap, screen.bitmap.Width * 1 / 3, screen.bitmap.Height * 1 / 3, screen.bitmap.Width * 2 / 3, screen.bitmap.Height * 2 / 3); Mat screenwhole = BitmapConverter.ToMat(cropped); Point2f ShipPointerOffset = new Point2f(0, 0); try { ShipPointerOffset = FindShipPointer(IsolateYellow(screenwhole)); } catch (Exception) { // If we can't find the ship pointer (it's hard to see it against the sun) then use the middle of the screen. } // erase the vivid areas, otherwise the blur subtraction turns yellow near red to green Mat brightHSV = screenwhole.CvtColor(ColorConversionCodes.BGR2HSV); Mat darkAreasMask = brightHSV.InRange(InputArray.Create(new int[] { 0, 0, 0 }), InputArray.Create(new int[] { 180, 255, 180 })); Mat darkAreas = new Mat(); screenwhole.CopyTo(darkAreas, darkAreasMask); Mat screenblur = darkAreas - darkAreas.Blur(new OpenCvSharp.Size(10, 10)); Mat sourceHSV = screenblur.CvtColor(ColorConversionCodes.BGR2HSV); Mat mask = sourceHSV.InRange(InputArray.Create(new int[] { 35, 204, 20 }), InputArray.Create(new int[] { 90, 255, 255 })); Mat sourceHSVFiltered = new Mat(); sourceHSV.CopyTo(sourceHSVFiltered, mask); Mat sourceGrey = sourceHSVFiltered.Split()[2].InRange(32, 256); LineSegmentPoint[] result = sourceGrey.HoughLinesP(1, 3.1415 / 180, 5, 10, 2); List <Point2d> points = new List <Point2d>(); foreach (var line in result) { points.Add(line.P1); points.Add(line.P2); } if (points.Count < 8) { throw new ArgumentException("Not enough points in corona circle"); } CircleSegment c = ComputeCircle(points); sourceGrey.Line(c.Center, ShipPointerOffset, 255); c.Center -= ShipPointerOffset; // adjust for camera movement by taking ship pointer offset sourceGrey.Circle(c.Center, (int)c.Radius, 255); debugWindow.Image = BitmapConverter.ToBitmap(sourceGrey); return(c); }
static public void RenderKeyPoints(string wndName, Mat mat, KeyPoint[] keypoints) { Mat view = mat.Clone(); foreach (KeyPoint kp in keypoints) { view.Circle(kp.Pt, 3, Scalar.Red, -1, LineTypes.AntiAlias, 0); } Cv2.ImShow(wndName, view); }
public void Run() { const int Size = 600; // Creates random point list var rand = new Random(); var points = Enumerable.Range(0, 100).Select(_ => new Point2f(rand.Next(0, Size), rand.Next(0, Size))).ToArray(); Mat img = Mat.Zeros(Size, Size, MatType.CV_8UC3); foreach (var p in points) { img.Circle(p, 4, Scalar.Red, -1); } // Initializes Subdiv2D var subdiv = new Subdiv2D(); subdiv.InitDelaunay(new Rect(0, 0, Size, Size)); subdiv.Insert(points); // Draws voronoi diagram Point2f[][] facetList; Point2f[] facetCenters; subdiv.GetVoronoiFacetList(null, out facetList, out facetCenters); var vonoroi = img.Clone(); foreach (var list in facetList) { var before = list.Last(); foreach (var p in list) { vonoroi.Line(before, p, new Scalar(64, 255, 128), 1); before = p; } } // Draws delaunay diagram Vec4f[] edgeList = subdiv.GetEdgeList(); var delaunay = img.Clone(); foreach (var edge in edgeList) { var p1 = new Point(edge.Item0, edge.Item1); var p2 = new Point(edge.Item2, edge.Item3); delaunay.Line(p1, p2, new Scalar(64, 255, 128), 1); } Cv2.ImShow("voronoi", vonoroi); Cv2.ImShow("delaunay", delaunay); Cv2.WaitKey(); Cv2.DestroyAllWindows(); }
public bool Calibration(Mat frame) { List <BallProperty> moList = GetBallPropties(frame); //大きな物体の重心の重い方から4個 if (moList.Count < 4) { return(false); } List <Point2f> coners = new List <Point2f>(); for (int i = 0; i < 4; i++) { Point2f center = moList[i].GetCenter(); frame.Circle(center, 3, Scalar.Blue); coners.Add(center); } //4つの角の確定 coners.Sort((a, b) => (int)(a.X - b.X)); List <Point2f> left = new List <Point2f>(); List <Point2f> right = new List <Point2f>(); left.Add(coners[0]); left.Add(coners[1]); right.Add(coners[2]); right.Add(coners[3]); left.Sort((a, b) => (int)(a.Y - b.Y)); right.Sort((a, b) => (int)(a.Y - b.Y)); List <Point2f> order = new List <Point2f>(); order.Add(left[0]); order.Add(left[1]); order.Add(right[1]); order.Add(right[0]); List <Point2f> realConer = new List <Point2f>(); realConer.Add(mLU); realConer.Add(mLD); realConer.Add(mRD); realConer.Add(mRU); PL.SetConers(order, realConer); if (DebugMode) { Cv2.ImShow("Moments", frame); } return(true); }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private void CppStyleMSER(Mat gray, Mat dst) { MSER mser = new MSER(); Point[][] contours = mser.Run(gray, null); // operator() foreach (Point[] pts in contours) { CvColor color = CvColor.Random(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } }
/// <summary> /// Extracts MSER by C++-style code (cv::MSER) /// </summary> /// <param name="gray"></param> /// <param name="dst"></param> private void CppStyleMSER(Mat gray, Mat dst) { MSER mser = MSER.Create(); mser.DetectRegions(gray, out Point[][] contours, out _); foreach (Point[] pts in contours) { Scalar color = Scalar.RandomColor(); foreach (Point p in pts) { dst.Circle(p, 1, color); } } }
public static void MatchCorona() { Bitmap screen = new Bitmap("Screenshot_0028.bmp"); Bitmap cropped = CompassSensor.Crop(screen, screen.Width * 1 / 3, screen.Height * 1 / 3, screen.Width * 2 / 3, screen.Height * 2 / 3); Mat screenwhole = BitmapConverter.ToMat(cropped); // erase the vivid areas, otherwise the blur subtraction turns yellow near red to green Mat brightHSV = screenwhole.CvtColor(ColorConversionCodes.BGR2HSV); Mat darkAreasMask = brightHSV.InRange(InputArray.Create(new int[] { 0, 0, 0 }), InputArray.Create(new int[] { 180, 255, 180 })); Mat darkAreas = new Mat(); screenwhole.CopyTo(darkAreas, darkAreasMask); Mat screenblur = darkAreas - darkAreas.Blur(new OpenCvSharp.Size(10, 10)); Window w3 = new Window(screenblur); //screenblur.SaveImage("sharplines.png"); Mat sourceHSV = screenblur.CvtColor(ColorConversionCodes.BGR2HSV); /* Paint.Net uses HSV [0..360], [0..100], [0..100]. * OpenCV uses H: 0 - 180, S: 0 - 255, V: 0 - 255 * Paint.NET colors: * 73 100 18 brightest part of green edge * 72 98 9 very dark green * suggested range [70..180], [80..100], [8..100] (paint.net) * suggested range [35..90], [204..255], [20..255] (openCV) * */ Mat mask = sourceHSV.InRange(InputArray.Create(new int[] { 35, 204, 20 }), InputArray.Create(new int[] { 90, 255, 255 })); Mat sourceHSVFiltered = new Mat(); sourceHSV.CopyTo(sourceHSVFiltered, mask); Window w5 = new Window("yellowfilter", sourceHSVFiltered.CvtColor(ColorConversionCodes.HSV2BGR)); Mat sourceGrey = sourceHSVFiltered.Split()[2].InRange(32, 256); // Value channel is pretty good as a greyscale conversion Window w6 = new Window("yellowFilterValue", sourceGrey); LineSegmentPoint[] result = sourceGrey.HoughLinesP(1, 3.1415 / 180, 5, 10, 2); List <Point2d> points = new List <Point2d>(); foreach (var line in result) { points.Add(line.P1); points.Add(line.P2); darkAreas.Line(line.P1, line.P2, new Scalar(255, 0, 255)); } CircleSegment c = CruiseSensor.ComputeCircle(points); darkAreas.Circle(c.Center, (int)c.Radius, new Scalar(255, 255, 0)); Window w9 = new Window("final", darkAreas); }
void CamUpdate() { CvUtil.GetWebCamMat(webCamTexture, ref mat); Cv2.CvtColor(mat, gray, ColorConversionCodes.RGBA2GRAY); KeyPoint[] keypoints = Cv2.FAST(gray, 50, true); foreach (KeyPoint kp in keypoints) { mat.Circle(kp.Pt, 3, new Scalar(255, 0, 0, 255), -1, LineTypes.AntiAlias, 0); } CvConvert.MatToTexture2D(mat, ref tex); rawImage.texture = tex; }
private void timer1_Tick(object sender, EventArgs e) { Mat image = new Mat(); capture.Read(image); // same as cvQueryFrame frameCount++; if (frameCount >= capture.FrameCount) { timer1.Stop(); trackBar1.Value = capture.FrameCount; return; } if (checkBox1.Checked) { goodPoints = Cv2.GoodFeaturesToTrack(image.CvtColor(ColorConversion.RgbaToGray), 25, 0.01, 100, image.CvtColor(ColorConversion.RgbaToGray), 3, false, 0.04); Console.WriteLine(goodPoints.Length); for (int i = 0; i < goodPoints.Length; i++) { image.Circle(goodPoints[i], 5, new Scalar(0, 255, 255), 5); //MessageBox.Show(goodPoints[i].ToString()); } } // Cv2.ImShow("temp", image); label3.Text = "Frame #" + frameCount; Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image); System.Drawing.Size newSize = new System.Drawing.Size(pictureBox1.Width, image.Height * pictureBox1.Width / image.Width); Bitmap newImage = new Bitmap((Image)bitmap, newSize); image.Dispose(); bitmap.Dispose(); pictureBox1.Width = newImage.Width; pictureBox1.Height = newImage.Height; pictureBox1.Image = newImage; pictureBox1.Refresh(); pictureBox1_MouseMove(null, null); pictureBox2.Refresh(); trackBar1.Value = frameCount; }
public void Run() { using var srcImg = Cv2.ImRead(FilePath.Image.Lenna, ImreadModes.AnyDepth | ImreadModes.AnyColor); using var markers = new Mat(srcImg.Size(), MatType.CV_32SC1, Scalar.All(0)); using (var window = new Window("image", srcImg)) { using var dspImg = srcImg.Clone(); // Mouse event int seedNum = 0; window.SetMouseCallback((MouseEventTypes ev, int x, int y, MouseEventFlags flags, IntPtr userdata) => { if (ev == MouseEventTypes.LButtonDown) { seedNum++; var pt = new Point(x, y); markers.Circle(pt, 10, Scalar.All(seedNum), Cv2.FILLED, LineTypes.Link8); dspImg.Circle(pt, 10, Scalar.White, 3, LineTypes.Link8); window.Image = dspImg; } }); Window.WaitKey(); } Cv2.Watershed(srcImg, markers); // draws watershed using var dstImg = srcImg.Clone(); for (int y = 0; y < markers.Height; y++) { for (int x = 0; x < markers.Width; x++) { int idx = markers.Get <int>(y, x); if (idx == -1) { dstImg.Rectangle(new Rect(x, y, 2, 2), Scalar.Red, -1); } } } using (new Window("watershed transform", dstImg)) { Window.WaitKey(); } }
public override void RunTest() { using Mat imgSrc = new Mat(ImagePath.Lenna, ImreadModes.Color); using Mat imgGray = new Mat(); using Mat imgDst = imgSrc.Clone(); Cv2.CvtColor(imgSrc, imgGray, ColorConversionCodes.BGR2GRAY, 0); KeyPoint[] keypoints = Cv2.FAST(imgGray, 50, true); foreach (KeyPoint kp in keypoints) { imgDst.Circle((Point)kp.Pt, 3, Scalar.Red, -1, LineTypes.AntiAlias, 0); } Cv2.ImShow("FAST", imgDst); Cv2.WaitKey(0); Cv2.DestroyAllWindows(); }
void DrawPoints(Mat Mat, ReportCollection Reports) { int w = Mat.Width - GridMargin.Left - GridMargin.Right; int h = Mat.Height - GridMargin.Top - GridMargin.Bottom; float winterval = (float)w / (HorizontalPoints + 1); float hinterval = (float)h / (VerticalPoints + 1); const int Range = 7; Reports.CornerReport corner = Reports.Select <Reports.CornerReport>(); for (int i = 1; HorizontalPoints >= i; i++) { for (int j = 1; VerticalPoints >= j; j++) { float xpos = GridMargin.Left + (winterval * i); float ypos = GridMargin.Top + (hinterval * j); Scalar Color = Scalar.White; if (InRange(xpos - Range, xpos + Range, MouseLocation.X, true) && InRange(ypos - Range, ypos + Range, MouseLocation.Y, true)) { Color = Scalar.Blue; } else { foreach (Point2f p in corner.Corners) { if (InRange(xpos - Range, xpos + Range, p.X, true) && InRange(ypos - Range, ypos + Range, p.Y, true)) { Color = Scalar.Red; } } } Mat.Circle(new Point(xpos, ypos), 3, Color, PointThickness, LineTypes.Filled); } } }
public static void Fast(string path) { using (Mat imgSrc = new Mat(path, LoadMode.Color)) using (Mat imgGray = new Mat()) using (Mat imgDst = imgSrc.Clone()) { Cv2.CvtColor(imgSrc, imgGray, ColorConversion.BgrToGray, 0); KeyPoint[] keypoints; Cv2.FAST(imgGray, out keypoints, 50, true); foreach (KeyPoint kp in keypoints) { imgDst.Circle(kp.Pt, 3, CvColor.Red, -1, LineType.AntiAlias, 0); } Cv2.ImShow("FAST", imgDst); Cv2.WaitKey(0); Cv2.DestroyAllWindows(); } }
public Point2f FindTriQuadrant(Mat screen) { // todo: detect the dotted circle that means the target is obscured. // See the Experiments for how this works. Mat yellowValue = IsolateYellow(screen); CircleSegment[] circles = yellowValue.HoughCircles( HoughMethods.Gradient, dp: 1f, /* resolution scaling factor? full resolution seems to work better */ minDist: 100, /* set this high so that we only find one (also seems to improve accuracy) */ param1: 100, /* default was fine after experimentation */ param2: 13, /* required quality factor. 9 finds too many, 14 finds too few */ minRadius: 40, maxRadius: 47); Point2f shipPointer = FindShipPointer(yellowValue); // draw some debug stuff for display: found circles, line to shippointer. foreach (CircleSegment circle in circles) { yellowValue.Circle(circle.Center, (int)circle.Radius, 128); } if (circles.Length == 1) { yellowValue.Line(circles[0].Center, shipPointer, 255); } debugWindow.Image = BitmapConverter.ToBitmap(yellowValue); if (circles.Length > 1) { throw new Exception("Too many possible triquadrants."); } if (circles.Length < 1) { throw new Exception("No possible triquadrants."); } return(circles[0].Center); }
public static void Main(string[] args) { Mat src = new Mat("TestImages/2013-12-27-09G37_TRB.jpg", LoadMode.Color); src = src.Resize (new Size (420, 625)); Mat srcGrey = src.CvtColor(ColorConversion.BgrToGray); Mat dst = new Mat (); Point[][] contours; Mat invertColour = new Mat (src.Rows, src.Cols, src.Type(), new Scalar(255, 255, 255) ); HiearchyIndex[] hierarchy; Mat contoursLines = new Mat(src.Rows, src.Cols, src.Type()); // InputArray element = Cv2.GetStructuringElement (StructuringElementShape.Ellipse, new Size (16, 16)); // Mat thresh = srcGrey.Threshold (230, 255, ThresholdType.Binary).Dilate(element); Mat thresh = srcGrey.Threshold (230, 255, ThresholdType.Binary); Cv2.FindContours (thresh, out contours, out hierarchy, ContourRetrieval.Tree, ContourChain.ApproxSimple); // Find center of mass in contour Moments center = Cv2.Moments (contours [0]); // Convert moment matrix to X/Y coords int x = (int) (center.M10 / center.M00); int y = (int) (center.M01 / center.M00); src.Circle (new Point (x, y), 5, CvColor.CornflowerBlue, 2); src.DrawContours (contours, 1, CvColor.Green, 2); bool intersect = IsIntersecting (selector[0], selector[1], contours[1][0], contours[1][1]); using (var orig = new Window ("src image", src)) { orig.OnMouseCallback += new CvMouseCallback(MouseMove); Cv2.WaitKey(); } }
/// <summary> /// Classical Multidimensional Scaling /// </summary> public void Run() { // creates distance matrix int size = CityDistance.GetLength(0); Mat t = new Mat(size, size, MatType.CV_64FC1, CityDistance); // adds Torgerson's additive constant to t double torgarson = Torgerson(t); t += torgarson; // squares all elements of t t = t.Mul(t); // centering matrix G Mat g = CenteringMatrix(size); // calculates inner product matrix B Mat b = g * t * g.T() * -0.5; // calculates eigenvalues and eigenvectors of B Mat values = new Mat(); Mat vectors = new Mat(); Cv2.Eigen(b, values, vectors); for (int r = 0; r < values.Rows; r++) { if (values.Get <double>(r) < 0) { values.Set <double>(r, 0); } } //Console.WriteLine(values.Dump()); // multiplies sqrt(eigenvalue) by eigenvector Mat result = vectors.RowRange(0, 2); { var at = result.GetGenericIndexer <double>(); for (int r = 0; r < result.Rows; r++) { for (int c = 0; c < result.Cols; c++) { at[r, c] *= Math.Sqrt(values.Get <double>(r)); } } } // scaling Cv2.Normalize(result, result, 0, 800, NormTypes.MinMax); // opens a window using (Mat img = Mat.Zeros(600, 800, MatType.CV_8UC3)) using (Window window = new Window("City Location Estimation")) { var at = result.GetGenericIndexer <double>(); for (int c = 0; c < size; c++) { double x = at[0, c]; double y = at[1, c]; x = x * 0.7 + img.Width * 0.1; y = y * 0.7 + img.Height * 0.1; img.Circle((int)x, (int)y, 5, Scalar.Red, -1); Point textPos = new Point(x + 5, y + 10); img.PutText(CityNames[c], textPos, HersheyFonts.HersheySimplex, 0.5, Scalar.White); } window.Image = img; Cv2.WaitKey(); } }
static Mat DetectBallView(Mat s, Mat h) { //Console.WriteLine(mat); //Console.WriteLine("{0}:{1}", mat.Width, mat.Height); //Console.WriteLine("{0}, {1}, {2}", mat.Step(0), mat.Step(), mat.Step(1)); //return; const int ballWidth = 36; var balls = DetectBalls(s, h, ballWidth); var detectM = QuickDetectBalls_Field(s.Threshold(20, 255, ThresholdType.Binary), ballWidth); if (true) { var debugMat = new Mat(); Cv2.CvtColor(s, debugMat, ColorConversion.GrayToRgb); const int ballWidth_3 = ballWidth / 3; var detectCount = 0; var allDetectCount = 0; for (var y = 0; y < detectM.GetLength(1); ++y) for (var x = 0; x < detectM.GetLength(0); ++x) { if (detectM[x, y] > 0.8 * ballWidth_3 * ballWidth_3) { debugMat.Circle(x * ballWidth_3 + ballWidth_3 / 2, y * ballWidth_3 + ballWidth_3 / 2, 2, Color.LightGreen.ToScalar(), -1); detectCount++; } allDetectCount++; } foreach (var ball in balls) { debugMat.Circle(ball.Point.X, ball.Point.Y, ballWidth / 2, Color.Orange.ToScalar(), thickness: 1); debugMat.PutText(ball.H.ToString(), new OpenCvSharp.CPlusPlus.Point(ball.Point.X - ballWidth / 4, ball.Point.Y), FontFace.HersheySimplex, 0.5, Color.Red.ToScalar()); } if (true) { var p = new Point(400, 150); var center = new Point(400, 300); var resPoint = RotatePointAroundCenter(p, center, 90); var resPoint2 = RotatePointAroundCenter(p, center, 45); var resPoint3 = RotatePointAroundCenter(p, center, 135); debugMat.Circle(resPoint.X, resPoint.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(resPoint2.X, resPoint2.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(resPoint3.X, resPoint3.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(center.X, center.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(p.X, p.Y, 3, Color.LightBlue.ToScalar(), -1); } Console.WriteLine("detect count: {0}%", 100 * detectCount / allDetectCount); debugMat.ImWrite("q.bmp"); return debugMat; } }
public void Run() { // Training data var points = new CvPoint2D32f[500]; var responses = new int[points.Length]; var rand = new Random(); for (int i = 0; i < responses.Length; i++) { double x = rand.Next(0, 300); double y = rand.Next(0, 300); points[i] = new CvPoint2D32f(x, y); responses[i] = (y > f(x)) ? 1 : 2; } // Show training data and f(x) using (Mat pointsPlot = Mat.Zeros(300, 300, MatType.CV_8UC3)) { for (int i = 0; i < points.Length; i++) { int x = (int)points[i].X; int y = (int)(300 - points[i].Y); int res = responses[i]; Scalar color = (res == 1) ? Scalar.Red : Scalar.GreenYellow; pointsPlot.Circle(x, y, 2, color, -1); } // f(x) for (int x = 1; x < 300; x++) { int y1 = (int)(300 - f(x - 1)); int y2 = (int)(300 - f(x)); pointsPlot.Line(x - 1, y1, x, y2, Scalar.LightBlue, 1); } Window.ShowImages(pointsPlot); } // Train var dataMat = new Mat(points.Length, 2, MatType.CV_32FC1, points); var resMat = new Mat(responses.Length, 1, MatType.CV_32SC1, responses); using (var svm = new CvSVM()) { // normalize data dataMat /= 300.0; var criteria = TermCriteria.Both(1000, 0.000001); var param = new CvSVMParams( SVMType.CSvc, SVMKernelType.Rbf, 100.0, // degree 100.0, // gamma 1.0, // coeff0 1.0, // c 0.5, // nu 0.1, // p null, criteria); svm.Train(dataMat, resMat, null, null, param); // Predict for each 300x300 pixel using (Mat retPlot = Mat.Zeros(300, 300, MatType.CV_8UC3)) { for (int x = 0; x < 300; x++) { for (int y = 0; y < 300; y++) { float[] sample = { x / 300f, y / 300f }; var sampleMat = new CvMat(1, 2, MatrixType.F32C1, sample); int ret = (int)svm.Predict(sampleMat); var plotRect = new CvRect(x, 300 - y, 1, 1); if (ret == 1) { retPlot.Rectangle(plotRect, Scalar.Red); } else if (ret == 2) { retPlot.Rectangle(plotRect, Scalar.GreenYellow); } } } Window.ShowImages(retPlot); } } }
public static bool SetImageOrientation(ref Mat img) { int MinDist = 250; int CanieTresh = 100; int DownSample = 1; //img.SaveImage("grayBEFOREConverted.png"); var gray = img.CvtColor(ColorConversionCodes.BGR2GRAY); gray.SaveImage("grayConverted.png"); //gray = gray.GaussianBlur(new Size(9, 9), 2, 2); //gray.SaveImage("grayBlurr.png"); //gray.ConvertTo(gray, MatType.CV_8UC1); //gray.SaveImage("gray8uc1.png"); var orientCircles = gray.HoughCircles(HoughMethods.Gradient, DownSample, MinDist, CanieTresh, 20, 0, CONSTS.FRAME_THICKNESS * 2); if (orientCircles.Length < 3) { return(false); } Mat print4Test = gray.Clone(); foreach (var c in orientCircles) { print4Test.Circle((int)c.Center.X, (int)c.Center.Y, (int)c.Radius, Scalar.Red, 2); } print4Test.SaveImage("gray.png"); Point[] orientationPoints = new Point[4] { new Point(img.Width - img.Width / 4, 0), //top right new Point(img.Width - img.Width / 4, img.Height - img.Height / 4), //bottom right new Point(0, img.Height - img.Height / 4), //bottom left new Point(0, 0), //top left }; bool[] pointInPos = new bool[4]; for (int i = 0; i < orientationPoints.Length; i++) { Mat piece = gray.SubMat(new Rect(orientationPoints[i], new Size(img.Width / 4, img.Height / 4))); var c = piece.HoughCircles(HoughMethods.Gradient, DownSample, MinDist, CanieTresh, 20, 0, CONSTS.FRAME_THICKNESS * 2); piece.SaveImage(string.Format("rightCornerPiece{0}.png", i)); Console.WriteLine("piece: " + i + " found circles: " + c.Length); pointInPos[i] = c.Length == 0;//true if empty } if (pointInPos.Where(x => x == true).Count() > 1) // atleast 3 orientation circles { return(false); } for (int i = 0; i < 4; i++) { img.SaveImage(string.Format("img{0}.png", i)); if (pointInPos[i] == true) { return(true); } img = img.Transpose().Flip(FlipMode.X);//rotate ccw } return(false); }
/// <summary> /// 对外函数,用于识别一个图片 detect one frame /// </summary> /// <param name="frame">一个彩色图片; a RGB picture</param> /// <returns>一个ArrayList,包含结果;results of detections</returns> public ArrayList detect(Mat frame) { Mat gray = new Mat(); Cv2.CvtColor(frame, gray, ColorConversionCodes.RGB2GRAY); Mat dst = new Mat(); Mat gauss = new Mat(); Cv2.GaussianBlur(gray, gauss, new Size(3, 3), this.sigma); switch (this.threshold) { case "canny": Cv2.Canny(gauss, dst, 150, 400, 3); break; case "adaptive": Cv2.AdaptiveThreshold(gauss, dst, 255, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.BinaryInv, 9, 5); break; default: Cv2.Canny(gauss, dst, 150, 400, 3); break; } Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(dst, out contours, out hierarchy, OpenCvSharp.RetrievalModes.CComp, ContourApproximationModes.ApproxSimple, null); if (this.debug == true) { Mat copyimg = new Mat(); frame.CopyTo(copyimg); copyimg.DrawContours(contours, -1, new Scalar(0, 255, 0)); using (new Window("contours image", copyimg)) { Cv2.WaitKey(); } } ArrayList hulls = new ArrayList(); ArrayList quads = new ArrayList(); for (int i = 0; i < contours.Length; i++) { var contour = contours[i];//取出多边形 get polygon if (contour.Length >= 4 && hierarchy[i].Previous < 0) { var area = Cv2.ContourArea(contour); //求多边形面积 get contour`s area if (area > this.minarea) { var hull = Cv2.ConvexHull(contour); //求出凸包 get hull if ((area / Cv2.ContourArea(hull)) > 0.8) { hulls.Add(hull); var quad = Cv2.ApproxPolyDP(hull, 9, true); //根据凸包计算出四边形 get quad if (quad.Length == 4) { var areaqued = Cv2.ContourArea(quad); var areahull = Cv2.ContourArea(hull); if (areaqued / areahull > 0.8 && areahull >= areaqued) { quads.Add(quad); } } } } } } if (this.debug == true) { Mat copyimg = new Mat(); frame.CopyTo(copyimg); foreach (Point[] item in quads) { Point[][] temp = new Point[1][]; temp[0] = item; copyimg.DrawContours(temp, -1, new Scalar(0, 255, 0)); } using (new Window("contours image", copyimg)) { Cv2.WaitKey(); } Console.WriteLine("quads count" + quads.Count); } ArrayList detections = new ArrayList(); ArrayList points = new ArrayList(); ArrayList whitepoints = new ArrayList(); //进行点quad点的提取 foreach (Point[] quad in quads) { int dd = this.tagfamily.getBlackBorder() * 2 + this.tagfamily.getEdge(); ArrayList blackvalue = new ArrayList(); ArrayList whitevalue = new ArrayList(); for (int iy = 0; iy < dd; iy++) { for (int ix = 0; ix < dd; ix++) { double x = (ix + 0.5) / (dd * 1.0); double y = (iy + 0.5) / (dd * 1.0); var polatepoint = _interpolate(quad, new Point2d(x, y)); points.Add(polatepoint); var value = gray.At <byte> (polatepoint.X, polatepoint.Y); if ((iy == 0 || iy == dd - 1) || (ix == 0 || ix == dd - 1)) { blackvalue.Add(value); } else if ((iy == 1 || iy == dd - 2) || (ix == 1 || ix == dd - 2)) { whitevalue.Add(value); } else { continue; } } } long tagcode = 0; var threshold = 0.5 * (_average(blackvalue) + _average(whitevalue)); for (int iy = 0; iy < dd; iy++) { for (int ix = 0; ix < dd; ix++) { if ((iy == 0 || iy == dd - 1) || (ix == 0 || ix == dd - 1)) { continue; } double newx = (ix + 0.5) / dd * 1.0; double newy = (iy + 0.5) / dd * 1.0; Point point = _interpolate(quad, new Point2d(newx, newy)); int grayvalue = gray.At <byte> (point.X, point.Y); tagcode = tagcode << 1; if (grayvalue > threshold) { tagcode |= 1; whitepoints.Add(point); } } } TagDetection decoderesult = this.tagfamily._decode(tagcode); if (decoderesult.good == true) { decoderesult.addPoint(quad); detections.Add(decoderesult); } } if (this.debug == true) { Mat copyimg = new Mat(); frame.CopyTo(copyimg); foreach (Point item in points) { Point tpoint = new Point(item.Y, item.X); copyimg.Circle(tpoint, 1, new Scalar(0, 0, 255)); } using (new Window("quad", copyimg)) { Cv2.WaitKey(); } Mat copyimg2 = new Mat(); frame.CopyTo(copyimg2); foreach (Point item in whitepoints) { Point tpoint = new Point(item.Y, item.X); copyimg2.Circle(tpoint, 1, new Scalar(0, 0, 255)); } using (new Window("quad", copyimg2)) { Cv2.WaitKey(); } } return(detections); }
public override void RunTest() { // Training data var points = new Point2f[500]; var responses = new int[points.Length]; var rand = new Random(); for (int i = 0; i < responses.Length; i++) { float x = rand.Next(0, 300); float y = rand.Next(0, 300); points[i] = new Point2f(x, y); responses[i] = (y > Function(x)) ? 1 : 2; } // Show training data and f(x) using (Mat pointsPlot = Mat.Zeros(300, 300, MatType.CV_8UC3)) { for (int i = 0; i < points.Length; i++) { int x = (int)points[i].X; int y = (int)(300 - points[i].Y); int res = responses[i]; Scalar color = (res == 1) ? Scalar.Red : Scalar.GreenYellow; pointsPlot.Circle(x, y, 2, color, -1); } // f(x) for (int x = 1; x < 300; x++) { int y1 = (int)(300 - Function(x - 1)); int y2 = (int)(300 - Function(x)); pointsPlot.Line(x - 1, y1, x, y2, Scalar.LightBlue, 1); } Window.ShowImages(pointsPlot); } // Train var dataMat = new Mat(points.Length, 2, MatType.CV_32FC1, points); var resMat = new Mat(responses.Length, 1, MatType.CV_32SC1, responses); using var svm = SVM.Create(); // normalize data dataMat /= 300.0; // SVM parameters svm.Type = SVM.Types.CSvc; svm.KernelType = SVM.KernelTypes.Rbf; svm.TermCriteria = TermCriteria.Both(1000, 0.000001); svm.Degree = 100.0; svm.Gamma = 100.0; svm.Coef0 = 1.0; svm.C = 1.0; svm.Nu = 0.5; svm.P = 0.1; svm.Train(dataMat, SampleTypes.RowSample, resMat); // Predict for each 300x300 pixel using Mat retPlot = Mat.Zeros(300, 300, MatType.CV_8UC3); for (int x = 0; x < 300; x++) { for (int y = 0; y < 300; y++) { float[] sample = { x / 300f, y / 300f }; var sampleMat = new Mat(1, 2, MatType.CV_32FC1, sample); int ret = (int)svm.Predict(sampleMat); var plotRect = new Rect(x, 300 - y, 1, 1); if (ret == 1) { retPlot.Rectangle(plotRect, Scalar.Red); } else if (ret == 2) { retPlot.Rectangle(plotRect, Scalar.GreenYellow); } } } Window.ShowImages(retPlot); }
async Task <Bitmap> DetectRect() { StringBuilder log = new StringBuilder(); Bitmap bitmap = await GetBitmap(); try { await Task.Run(() => { Mat mat = bitmap.ToMat(); log.AppendLine($"RawSize: {mat.Width}x{mat.Height}"); // 下ごしらえ var resize = RegistDest("resize", mat.Resize(new OpenCvSharp.Size(480, 480f / mat.Width *mat.Height))); var gray = RegistDest("gray", resize.CvtColor(ColorConversionCodes.RGBA2GRAY)); var negative = RegistDest("negative", ~gray); var binary = RegistDest("binary", negative.Threshold(230, 255, ThresholdTypes.Binary)); var open = RegistDest("open", binary.MorphologyEx(MorphTypes.Open, new Mat(), iterations: 2)); var close = RegistDest("close", open.MorphologyEx(MorphTypes.Close, new Mat(), iterations: 2)); var blured = RegistDest("blured", close.GaussianBlur(new OpenCvSharp.Size(33, 33), 10, 10)); var binary2 = RegistDest("binary2", blured.Threshold(blured.GetMedium(), 255, ThresholdTypes.Binary)); var sobel = RegistDest("sobel", binary2.Laplacian(MatType.CV_8U, ksize: 5)); var dilate = RegistDest("dilate", binary2.Dilate(new Mat(), iterations: 5)); var touches = dilate.GetTouchWallEdges().ToArray(); log.AppendLine($"touch: {touches.Length}"); var linesSet = sobel.SearchHouhLines(4 - touches.Length); // 重複と斜めを消して評価 var filted = linesSet .Select(ls => ls.DistinctSimmiler(sobel.Width / 3, 20).IgnoreDiagonally(10)) .ToArray(); var goodLines = filted.FirstOrDefault(ls => ls.Count >= 4 - touches.Length); var okLiness = filted.OrderBy(ls => ls.Count).FirstOrDefault(ls => ls.Count > 4 - touches.Length); var badLines = filted.OrderByDescending(ls => ls.Count).First(); var lines = goodLines ?? okLiness ?? badLines; var fixedLines = lines .Select(CvUtility.To2Point) .Concat(touches.Select(r => ((double)r.Left, (double)r.Top, (double)r.Right, (double)r.Bottom))); log.AppendLine($"{nameof(goodLines)}: {goodLines?.Count}"); log.AppendLine($"{nameof(okLiness)}: {okLiness?.Count}"); log.AppendLine($"{nameof(badLines)}: {badLines?.Count}"); log.AppendLine($"{nameof(fixedLines)}:\n {fixedLines.ToStringJoin("\n ")}"); Mat lined = null; { lined = resize.CvtColor(ColorConversionCodes.RGBA2RGB); foreach ((double x1, double y1, double x2, double y2) in fixedLines) { lined.Line((int)x1, (int)y1, (int)x2, (int)y2, Scalar.Green); } } // 単純組み合わせを列挙して交点を求めコーナーを検出 var linesCombi = fixedLines.GetCombination(); var crosses = linesCombi.GetCross().Select(CvUtility.To2f).ToArray(); var corners = CvUtility.Filter4Corner(crosses, resize.Size()); log.AppendLine($"Crosses:\n {crosses.ToStringJoin("\n ")}"); log.AppendLine($"Corners:\n {corners.ToStringJoin("\n ")}"); { foreach (var p in corners) { lined.Circle(new Point(p.X, p.Y), 5, Scalar.Aqua); } RegistDest("lined", lined); } var unscaledRectPoints = corners.Select(p => p * (mat.Width / (float)resize.Width)).ToArray(); log.AppendLine($"UnscaledCrosses:\n {unscaledRectPoints.ToStringJoin("\n ")}"); { var unscaledLined = mat.CvtColor(ColorConversionCodes.RGBA2RGB); foreach (var p in unscaledRectPoints) { unscaledLined.Circle(new Point(p.X, p.Y), 10, Scalar.Aqua, thickness: 20); } RegistDest("unscaledLined", unscaledLined); } Mat parspective = mat.TrimAndFitBy4Cross(unscaledRectPoints); RegistDest("parspective", parspective); }); } finally { displayText.Text = log.ToString(); } return(null); }
static Mat DetectBallView(Mat s, Mat h) { //Console.WriteLine(mat); //Console.WriteLine("{0}:{1}", mat.Width, mat.Height); //Console.WriteLine("{0}, {1}, {2}", mat.Step(0), mat.Step(), mat.Step(1)); //return; const int ballWidth = 36; var balls = DetectBalls(s, h, ballWidth); var detectM = QuickDetectBalls_Field(s.Threshold(20, 255, ThresholdType.Binary), ballWidth); if (true) { var debugMat = new Mat(); Cv2.CvtColor(s, debugMat, ColorConversion.GrayToRgb); const int ballWidth_3 = ballWidth / 3; var detectCount = 0; var allDetectCount = 0; for (var y = 0; y < detectM.GetLength(1); ++y) { for (var x = 0; x < detectM.GetLength(0); ++x) { if (detectM[x, y] > 0.8 * ballWidth_3 * ballWidth_3) { debugMat.Circle(x * ballWidth_3 + ballWidth_3 / 2, y * ballWidth_3 + ballWidth_3 / 2, 2, Color.LightGreen.ToScalar(), -1); detectCount++; } allDetectCount++; } } foreach (var ball in balls) { debugMat.Circle(ball.Point.X, ball.Point.Y, ballWidth / 2, Color.Orange.ToScalar(), thickness: 1); debugMat.PutText(ball.H.ToString(), new OpenCvSharp.CPlusPlus.Point(ball.Point.X - ballWidth / 4, ball.Point.Y), FontFace.HersheySimplex, 0.5, Color.Red.ToScalar()); } if (true) { var p = new Point(400, 150); var center = new Point(400, 300); var resPoint = RotatePointAroundCenter(p, center, 90); var resPoint2 = RotatePointAroundCenter(p, center, 45); var resPoint3 = RotatePointAroundCenter(p, center, 135); debugMat.Circle(resPoint.X, resPoint.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(resPoint2.X, resPoint2.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(resPoint3.X, resPoint3.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(center.X, center.Y, 3, Color.LightBlue.ToScalar(), -1); debugMat.Circle(p.X, p.Y, 3, Color.LightBlue.ToScalar(), -1); } Console.WriteLine("detect count: {0}%", 100 * detectCount / allDetectCount); debugMat.ImWrite("q.bmp"); return(debugMat); } }