public Form1() { InitializeComponent(); Location = new Point(1920 - this.Size.Width, 0); keyboard = new Keyboard(); screen = new Screenshot(); cruiseSensor = new CruiseSensor(); cruiseSensor.screen = screen; cruiseSensor.debugWindow = pictureBox2; compassRecognizer = new CompassSensor(screen, pictureBox2); menuSensor = new MenuSensor(screen, pictureBox2); pilot = new PilotJumper(); pilot.keyboard = keyboard; pilot.compassRecognizer = compassRecognizer; pilot.screen = screen; pilot.cruiseSensor = cruiseSensor; relogger = new Relogger(); relogger.keyboard = keyboard; relogger.menuSensor = menuSensor; // If you want to run one of the experiments, call it here so it runs on startup //OpenCVExperiments.MatchSafDisengag2(); //OpenCVExperiments.MatchCorona(); //OpenCVExperiments.MatchImpact(); //OpenCVExperiments.MatchMenu(); //OpenCVExperiments.FindTargetsTest(); //OpenCVExperiments.FindCompasses(); //OpenCVExperiments.Subtarget(); //OpenCVExperiments.Kalman(); //OpenCVExperiments.CurrentLocationLocked(); //OpenCVExperiments.CheckDrop(); }
/// <summary> /// Search for a red-channel compass-sized circle in the image. /// </summary> /// <param name="image"></param> /// <returns></returns> private CircleSegment FindCircle(Bitmap image) { Mat source = BitmapConverter.ToMat(image); //Convert input images to gray Mat reds = CruiseSensor.IsolateYellow(source); // these parameters were tuned using the test functionality CircleSegment[] circles = Cv2.HoughCircles(reds, HoughMethods.Gradient, dp: 2f, // this was tuned by experimentation minDist: 500, // 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); if (circles.Length != 1) { pictureBox2.Image = image; if (circles.Length > 1) { throw new System.ArgumentException("More than one valid circle..."); } if (circles.Length < 1) { throw new System.ArgumentException("No valid circles"); } } return(circles[0]); }
/// <summary> /// Similar to match screen but matches by rough colour blob. Good for menu elements that scale in some ships (so the text is too hard to match directly). /// </summary> /// <returns></returns> public bool MatchMenuColour(Mat template) { Mat mscreenValue = CruiseSensor.IsolateYellow(BitmapConverter.ToMat(screen.bitmap)); Mat templateValue = CruiseSensor.IsolateYellow(template); Mat matches = mscreenValue.MatchTemplate(templateValue, TemplateMatchModes.CCorrNormed); double minVal, maxVal; matches.MinMaxLoc(out minVal, out maxVal); return maxVal > 0.9; }
internal static void Subtarget() { Mat source = new Mat("res3/subtarget-test.png"); Mat targettemplate = new Mat("res3/subtarget.png"); Mat redSource = CruiseSensor.IsolateRed(source); Mat redTarget = CruiseSensor.IsolateRed(targettemplate); Mat matchImage = new Mat(); Cv2.MatchTemplate(redSource, redTarget, matchImage, TemplateMatchModes.CCorrNormed); Window w0 = new Window(redSource); Window w1 = new Window(matchImage); Window w2 = new Window(matchImage.Threshold(0.7, 1.0, ThresholdTypes.Tozero)); }
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); }
private bool AlignTarget() { try { Mat screenCentre = screen.ScreenCentre(diameter: 300); Point2f offset = cruiseSensor.FindTriQuadrant(screenCentre) - cruiseSensor.FindShipPointer(CruiseSensor.IsolateYellow(screenCentre)); return(FineAlign(-offset)); } catch (Exception e) { status = e.Message; } AlignCompass(); return(false); // only fine align can confirm we are aligned to the target }