void TakeSnapshot()
    {
        Texture2D snap = new Texture2D(webCamTextureToMatHelper.GetWidth(), webCamTextureToMatHelper.GetHeight());

        snap.SetPixels(webCamTextureToMatHelper.GetWebCamTexture().GetPixels());
        snap.Apply();

        System.IO.File.WriteAllBytes(_SavePath + _CaptureCounter.ToString() + ".png", snap.EncodeToPNG());
        ++_CaptureCounter;
    }
    void Update()
    {
        if (!running)
        {
            return;
        }


        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log($"Mouse Position: {Input.mousePosition} -> World: {Camera.main.ScreenToWorldPoint(Input.mousePosition)}");
        }


        if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame())
        {
            Mat rgbaMat = webCamTextureToMatHelper.GetMat();
            //Writes into the mat
            Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_RGB2GRAY);     //COLOR_RGBA2GRAY
            //Applies gaussian blur for better results
            Imgproc.GaussianBlur(grayMat, grayMat, new Size(3, 3), 2);
            using (Mat circles = new Mat()) {
                //Circle detection using the hough gradient
                Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius);
                Point pt = new Point();

                //Limits the circle drawing when too much circles are detected
                if ((int)circles.total() > 5)
                {
                    for (int i = 0; i < circles.rows(); i++)
                    {
                        double[] data = circles.get(i, 0);
                        pt.x = data [0];
                        pt.y = data [1];
                        double rho = data [2];
                        Imgproc.circle(rgbaMat, pt, (int)rho, GlobalValues.DETECTION_COLOR, GlobalValues.RINGS_RADIUS);
                    }
                }
                else      //Tennis ball tracking starts here
                {
                    for (int i = 0; i < circles.rows(); i++)
                    {
                        for (var j = 0; j < circles.cols(); j++)
                        {
                            //Get the data from the API
                            double[] data = circles.get(i, j);
                            pt.x = data [0];
                            pt.y = data [1];
                            double rho = data [2];

                            //Convert to worldspace
                            Vector2 pos      = new Vector2((float)data[0], webCamTextureToMatHelper.GetWebCamTexture().height - (float)data[1]);
                            Vector3 worldPos = Camera.main.ScreenToWorldPoint(AdjustToResolution(pos));

                            //Drawings for debug purposes
                            Debug.DrawRay(worldPos, Vector3.up * 10, Color.magenta, 1f);
                            Debug.DrawRay(worldPos, Vector3.down * 10, Color.magenta, 1f);
                            Debug.DrawRay(worldPos, Vector3.left * 10, Color.magenta, 1f);
                            Debug.DrawRay(worldPos, Vector3.right * 10, Color.magenta, 1f);

                            //If the ball went outside the detection threshold
                            if (ball_tracker.AwaitingForRegainFocus(worldPos))
                            {
                                //Flash a blue cirlcle to indicate the player where to start
                                if (Mathf.Sin(Time.time * GlobalValues.CHECK_POINT_BLINKING_FRECUENCY) > 0)
                                {
                                    var last_pos   = ball_tracker.GetLastPosition();
                                    var screen_pos = InvertAdjustToResolution(Camera.main.WorldToScreenPoint(last_pos));
                                    screen_pos.y = webCamTextureToMatHelper.GetWebCamTexture().height - screen_pos.y;
                                    Imgproc.circle(rgbaMat, new Point(screen_pos.x, screen_pos.y), (int)rho, GlobalValues.CHECK_POINT_COLOR, GlobalValues.RINGS_RADIUS);
                                }
                            }    //Otherwise Update the ball tracker
                            else if (ball_tracker.Update(worldPos))
                            {
                                Imgproc.circle(rgbaMat, pt, (int)rho, GlobalValues.TRACKING_COLOR, GlobalValues.RINGS_RADIUS);
                            }
                        }
                    }
                }
            }

//                Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);

            Utils.matToTexture2D(rgbaMat, texture, webCamTextureToMatHelper.GetBufferColors());
        }
    }