const int restRingWidth = 160; // to jest suma czyli 2x80 #endregion pierscienie public static ProcessFrameResult ProcessFrame(AditionaCapturelData acd) { PointF[] srcVertices; ProcessFrameResult result = new ProcessFrameResult(); result.Target = new TargetDetails(); int kwadratWidth; srcVertices = acd.MainTargetDetails.TargetRect; if (srcVertices == null) { return(null); } kwadratWidth = Convert.ToInt32(srcVertices[2].X - srcVertices[3].X); switch (acd.CurrentState) { case BidaSiusState.Start: return(null); break; case BidaSiusState.SetTargetBoundries: SetTargetBoundries(srcVertices, kwadratWidth, result, acd); break; case BidaSiusState.SetTargetSizeNPosition: SetTargetSizeNPosition(srcVertices, kwadratWidth, result, acd); break; case BidaSiusState.Play: FuseThisTarget(srcVertices, kwadratWidth, result, acd); break; default: throw new ArgumentOutOfRangeException(); } return(result); }
public static ProcessFrameResult ProcessFromFile(Mat frame, int firstCannyThresh = 100, int secondCannyThresh = 60, int firstCannyThresh1 = 120, int secondCannyThresh1 = 50, TargetDetails useThisTarget = null) { ProcessFrameResult result = new ProcessFrameResult(); result.Target = new TargetDetails(); result.Target.BlackCenter = useThisTarget.BlackCenter; result.Target.BlackR = useThisTarget.BlackR; var pix = Pix(useThisTarget.BlackR); int zapasSize = 5; //zapas z jakim ma wykrywać przestrzeline - to wywalić do jakiegoś txtbox czy coś int czteryIpolmmR_int = Convert.ToInt32(FourNHalfR(pix)); Mat circleImage = frame; #region hocki klocki przepierdalanie obrazu var inputImage = frame.ToImage <Bgr, byte>(); // inputImage._EqualizeHist(); inputImage._GammaCorrect(0.4d); result.GrSmootWarped = inputImage.Mat; #region blur gray canny samej tarczy Mat canny_output12 = new Mat(); //As for your answer to number two, blur the image, convert to greyscale, then threshold to eliminate lighting differences is the usual solution Mat smallGrayFrame12 = new Mat(); Mat smoothedGrayFrame12 = new Mat(); CvInvoke.PyrDown(inputImage.Mat, smallGrayFrame12); CvInvoke.PyrUp(smallGrayFrame12, smoothedGrayFrame12); CvInvoke.CvtColor(smoothedGrayFrame12, smoothedGrayFrame12, ColorConversion.Bgr2Gray); // CvInvoke.GaussianBlur(smoothedGrayFrame12, smoothedGrayFrame12, new Size(9, 9), 1, 1); result.SmoothedOryginal = smoothedGrayFrame12; #region test //#######test // double otsu_thresh_val12 = CvInvoke.Threshold(smoothedGrayFrame12, fake12, firstCannyThresh, secondCannyThresh, ThresholdType.Binary & ThresholdType.Otsu); //CvInvoke.AdaptiveThreshold(smoothedGrayFrame12, fake12, 255, AdaptiveThresholdType.GaussianC, ThresholdType.BinaryInv, 3, 2); //1CvInvoke.GaussianBlur(fake12, fake12, new Size(9, 9), 1, 1); // CvInvoke.GaussianBlur(fake12, fake12, new Size(9, 9), 1, 1); // C1111vInvoke.GaussianBlur(fake12, fake12, new Size(9, 9), 1, 1); // We don't need the _img. We are interested in only the otsu_thresh_val but unfortunately, currently there is no method in OpenCV which allows you to compute only the threshold value. //Use the Otsu's threshold value as higher threshold and half of the same as the lower threshold for Canny's algorithm. //double high_thresh_val1 = otsu_thresh_val1, // lower_thresh_val1 = otsu_thresh_val1 * 0.5; //CvInvoke.GaussianBlur(warped, fake12, new Size(9, 9), 1, 1); CvInvoke.Canny(smoothedGrayFrame12, canny_output12, firstCannyThresh, secondCannyThresh); // CvInvoke.Canny(smoothedGrayFrame12, canny_output12, 120, 50); // CvInvoke.GaussianBlur(canny_output12, canny_output12, new Size(11, 11), 1, 1); // CvInvoke.GaussianBlur(canny_output12, canny_output12, new Size(7, 7), 1, 1); // result.WarpedTargetCanny = canny_output12;//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //#######test #endregion test #endregion blur gray canny samej tarczy // result.SmOryCanny = smoothedGrayFrame12; #endregion hocki klocki przepierdalanie obrazu //odpal manualne pozycjonowanie ManualShotPositioning msp = new ManualShotPositioning(); msp.SetTargetAndShot(circleImage, czteryIpolmmR_int, useThisTarget); DialogResult dr = msp.ShowDialog(); CvInvoke.Circle(circleImage, Point.Round(msp.SelectedPoint), czteryIpolmmR_int, new Bgr(Color.DeepPink).MCvScalar, 1, LineType.AntiAlias, 0); result.Shot = WyliczWartoscPrzestrzeliny(msp.SelectedPoint, useThisTarget); DrawCircles(circleImage, pix, useThisTarget.BlackCenter); result.TargetScanWithResult = circleImage;//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ return(result); }
private static void FuseThisTarget(PointF[] src_vertices, int kwadratWidth, ProcessFrameResult result, AditionaCapturelData acd) { result.Target.BlackCenter = acd.MainTargetDetails.BlackCenter; result.Target.BlackR = acd.MainTargetDetails.BlackR; #region wyznaczenie prostokatow i kwadratow do transformacji perspektywy PointF[] dstVertices = new PointF[] { new PointF(0, 0), //tl topleft new PointF(kwadratWidth, 0), //tr new PointF(kwadratWidth, kwadratWidth), //br new PointF(0, kwadratWidth) }; //bl //kwadrat z lewym dolnym rogiem w tym samym miejscu co znaleziony - tylko po to żeby zobrazować //PointF[] dst_vertices_kwadrat_lewydol = new PointF[] { // new PointF(bo_ord[3].X , bo_ord[3].Y - kwadratWidth), // new PointF(bo_ord[3].X + kwadratWidth, bo_ord[3].Y - kwadratWidth), // new PointF(bo_ord[3].X + kwadratWidth, bo_ord[3].Y), // bo_ord[3]}; #endregion wyznaczenie prostokatow i kwadratow do transformacji perspektywy using (Mat warped = new Mat()) { #region tranformacja perspektywy Mat warpMatrix = CvInvoke.GetPerspectiveTransform(src_vertices, dstVertices); Size size = new Size(kwadratWidth, kwadratWidth); CvInvoke.WarpPerspective(acd.Frame, warped, warpMatrix, size, Inter.Linear, Warp.Default); #endregion tranformacja perspektywy #region rysowanie pierscieni //Mat circleImage = warped.Clone(); var pix = Pix(acd.MainTargetDetails.BlackR); //DrawCircles(circleImage, pix, useThisTarget.BlackCenter); #endregion rysowanie pierscieni #region blur gray canny samej tarczy Mat canny_output12 = new Mat(); Mat smallGrayFrame12 = new Mat(); Mat smoothedGrayFrame12 = new Mat(); CvInvoke.PyrDown(warped, smallGrayFrame12); CvInvoke.PyrUp(smallGrayFrame12, smoothedGrayFrame12); CvInvoke.CvtColor(smoothedGrayFrame12, smoothedGrayFrame12, ColorConversion.Bgr2Gray); // CvInvoke.GaussianBlur(smoothedGrayFrame12, smoothedGrayFrame12, new Size(9, 9), 1, 1); result.SmoothedOryginal = smoothedGrayFrame12;//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ #region test CvInvoke.Canny(smoothedGrayFrame12, canny_output12, acd.FirstCannyThresh, acd.secondCannyThresh); #endregion test #endregion blur gray canny samej tarczy #region rozpoznawanie strzału int czteryIpolmmRInt = Convert.ToInt32(FourNHalfR(pix)); int zapasSizeMax = 5; int zapasSizeMin = 1; CircleF[] przestrzeliny = CvInvoke.HoughCircles(smoothedGrayFrame12, HoughType.Gradient, 1, 400, acd.firstCannyThresh1, acd.secondCannyThresh1, czteryIpolmmRInt - zapasSizeMin, czteryIpolmmRInt + zapasSizeMax); result.Warped = warped.Clone();//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ foreach (CircleF shot in przestrzeliny) { CvInvoke.Circle(warped, Point.Round(shot.Center), czteryIpolmmRInt, new Bgr(Color.Blue).MCvScalar, 1, LineType.AntiAlias, 0); CvInvoke.Circle(warped, Point.Round(shot.Center), czteryIpolmmRInt - zapasSizeMin, new Bgr(Color.BlueViolet).MCvScalar, 1, LineType.AntiAlias, 0); CvInvoke.Circle(warped, Point.Round(shot.Center), czteryIpolmmRInt + zapasSizeMax, new Bgr(Color.Chartreuse).MCvScalar, 1, LineType.AntiAlias, 0); result.Shot = WyliczWartoscPrzestrzeliny(shot.Center, acd.MainTargetDetails); if (acd.MainTargetDetails.CameraFlipped) { result.TargetScanWithResult = Rotate180(warped.Clone());//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ } else { result.TargetScanWithResult = warped.Clone();//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ } break; } #endregion } }
private static void SetTargetSizeNPosition(PointF[] src_vertices, int kwadratWidth, ProcessFrameResult result, AditionaCapturelData acd) { #region wyznaczenie prostokatow i kwadratow do transformacji perspektywy PointF[] dstVertices = new PointF[] { new PointF(0, 0), //tl topleft new PointF(kwadratWidth, 0), //tr new PointF(kwadratWidth, kwadratWidth), //br new PointF(0, kwadratWidth) }; //bl #endregion wyznaczenie prostokatow i kwadratow do transformacji perspektywy #region tranformacja perspektywy Mat warpMatrix = CvInvoke.GetPerspectiveTransform(src_vertices, dstVertices); Size size = new Size(kwadratWidth, kwadratWidth); using (Mat warped = new Mat()) { CvInvoke.WarpPerspective(acd.Frame, warped, warpMatrix, size, Inter.Linear, Warp.Default); #endregion tranformacja perspektywy #region rysowanie pierscieni var pix = Pix(acd.MainTargetDetails.BlackR); DrawCircles(warped, pix, acd.MainTargetDetails.BlackCenter); result.Warped = warped.Clone();//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ } #endregion rysowanie pierscieni }
private static void SetTargetBoundries(PointF[] src_vertices, int kwadratWidth, ProcessFrameResult result, AditionaCapturelData acd) { //pokaż wszystko na oryginalnym obrazku Mat targetMarked = acd.Frame; CvInvoke.Polylines(targetMarked, Array.ConvertAll(src_vertices, Point.Round), true, new Bgr(Color.DarkOrange).MCvScalar, 2); result.TargetMarked = targetMarked;//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ }