// Update is called once per frame void Update() { if (webCamTextureToMatHelper.isPlaying() && webCamTextureToMatHelper.didUpdateThisFrame()) { Mat rgbaMat = webCamTextureToMatHelper.GetMat(); Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY); using (Mat circles = new Mat()) { Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 10, 160, 50, 10, 20); Point pt = new Point(); for (int i = 0; i < circles.cols(); i++) { double[] data = circles.get(0, i); pt.x = data [0]; pt.y = data [1]; double rho = data [2]; Imgproc.circle(rgbaMat, pt, (int)rho, new Scalar(255, 0, 0, 255), 5); } } Imgproc.putText(rgbaMat, "W:" + rgbaMat.width() + " H:" + rgbaMat.height() + " SO:" + Screen.orientation, new Point(5, rgbaMat.rows() - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); Utils.matToTexture2D(rgbaMat, texture, colors); } }
void UpdateCircles() { // Detect blobs. Imgproc.HoughCircles(grayMat, houghCircles, Imgproc.HOUGH_GRADIENT, 2.0, 10.0, 200.0, 150.0, 5, 60); // // Calculate the circles' screen coordinates // and world coordinates. // // Clear the previous coordinates. circles.Clear(); // Count the elements in the matrix of Hough circles. // Each circle should have 3 elements: { x, y, radius } int numHoughCircleElems = houghCircles.cols() * houghCircles.rows() * houghCircles.channels(); if (numHoughCircleElems == 0) { return; } // Convert the matrix of Hough circles to a 1D array: // { x_0, y_0, radius_0, ..., x_n, y_n, radius_n } float[] houghCirclesArray = new float[numHoughCircleElems]; houghCircles.get(0, 0, houghCirclesArray); // Iterate over the circles. for (int i = 0; i < numHoughCircleElems; i += 3) { // Convert circles' image coordinates to // screen coordinates. Vector2 screenPosition = ConvertToScreenPosition( houghCirclesArray[i], houghCirclesArray[i + 1]); float screenDiameter = houghCirclesArray[i + 2] * screenPixelsPerImagePixel; // Convert screen coordinates to world // coordinates based on raycasting. Vector3 worldPosition = ConvertToWorldPosition( screenPosition); Circle circle = new Circle( screenPosition, screenDiameter, worldPosition); circles.Add(circle); } }
// Update is called once per frame void Update() { if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame()) { Mat rgbaMat = webCamTextureToMatHelper.GetMat(); Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_RGB2HSV); Scalar lower_red = new Scalar(145, 42, 154); Scalar lower_blue = new Scalar(90, 50, 50); Scalar upper_red = new Scalar(255, 255, 255); Scalar upper_blue = new Scalar(130, 255, 255); Core.inRange(grayMat, lower_red, upper_red, redframe_threshold); Core.inRange(grayMat, lower_blue, upper_blue, blueframe_threshold); Core.bitwise_or(redframe_threshold, blueframe_threshold, frame_threshold); Size size = new Size(5, 5); Imgproc.erode(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); Imgproc.dilate(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); Imgproc.erode(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); Imgproc.dilate(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); Imgproc.erode(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); Imgproc.dilate(frame_threshold, frame_threshold, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, size)); using (Mat circles = new Mat()) { Imgproc.HoughCircles(frame_threshold, circles, Imgproc.CV_HOUGH_GRADIENT, 1, frame_threshold.rows() / 2, 20, 15, 15, 100); Point pt = new Point(); for (int i = 0; i < circles.cols(); i++) { double[] data = circles.get(0, i); pt.x = data [0]; pt.y = data [1]; double rho = data [2]; // Imgproc.circle (rgbaMat, pt, 3, new Scalar (255, 0, 255), 5); Imgproc.circle(rgbaMat, pt, (int)rho, new Scalar(255, 0, 0, 255), 5); } } Imgproc.putText(rgbaMat, "W:" + rgbaMat.width() + " H:" + rgbaMat.height() + " SO:" + Screen.orientation, new Point(5, rgbaMat.rows() - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); Utils.matToTexture2D(rgbaMat, texture, webCamTextureToMatHelper.GetBufferColors()); } }
void Start() { srcMat = Imgcodecs.imread(Application.dataPath + "/Textures/feature.jpg", 1); grayMat = new Mat(); Imgproc.cvtColor(srcMat, grayMat, Imgproc.COLOR_RGBA2GRAY); //会把五边形识别成圆。模糊处理,提高精确度。 Imgproc.GaussianBlur(grayMat, grayMat, new Size(7, 7), 2, 2); Mat circles = new Mat(); //霍夫圆 Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 10, 160, 50, 10, 40); //Debug.Log(circles); //圆心坐标 Point pt = new Point(); for (int i = 0; i < circles.cols(); i++) { double[] data = circles.get(0, i); pt.x = data[0]; pt.y = data[1]; double rho = data[2]; //绘制圆心 Imgproc.circle(srcMat, pt, 3, new Scalar(255, 255, 0), -1, 8, 0); //绘制圆轮廓 Imgproc.circle(srcMat, pt, (int)rho, new Scalar(255, 0, 0, 255), 5); } //在Mat上写字 Imgproc.putText(srcMat, "W:" + srcMat.width() + " H:" + srcMat.height(), new Point(5, srcMat.rows() - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); Texture2D t2d = new Texture2D(srcMat.width(), srcMat.height()); Sprite sp = Sprite.Create(t2d, new UnityEngine.Rect(0, 0, t2d.width, t2d.height), Vector2.zero); m_showImage.sprite = sp; m_showImage.preserveAspect = true; Utils.matToTexture2D(srcMat, t2d); }
void ComputerVisionAlgo(IntPtr greyscale) { Utils.copyToMat(greyscale, imageMat); // Imgproc.threshold(imageMat, outMat, 128, 255, Imgproc.THRESH_BINARY_INV); Imgproc.Canny(imageMat, edgeMat, 90, 150); outMat = edgeMat; Imgproc.HoughCircles(imageMat, circMat, Imgproc.HOUGH_GRADIENT, 1.0, 20.0); Debug.LogFormat("Circle Metadata {0}", circMat.ToString()); Debug.Log(circMat.size()); if (circMat.size() == null_size) { Debug.Log("No circles found"); } else { double[] c_data = circMat.get(0, 0); Debug.LogFormat("Circle Center: {0} x {1} \n Circle Radius: {2}", c_data[0], c_data[1], c_data[2]); } Debug.Log(circMat.size().width); // Debug.LogFormat("Circle 1: {0} x {1} -- {2}", // circMat.get(0, 0)[0], circMat.get(0, 1)[0], circMat.get(0, 2)[0]); // for (int i = 0; i < 5; i++) // { // Point center = Point(circMat[i][0], circMat[i][1]); // int radius = circMat[i][2]; // circle(imageMat, center, 3, Scalar(0, 255, 0), -1, 8); // circle(imageMat, center, radius, Scalar(0, 0, 255), 3, 8); // } // Debug.LogFormat("Mat Dimensions: {0} x {1}", imageMat.cols(), imageMat.rows()); }
void FindCirclesAndDisplay(ref CCircleDetectorModel pCircleDetectorModel) { Mat pSourceImage = pCircleDetectorModel.image; ShowImage(pSourceImage, "pSourceImage"); Mat imgHsv = new Mat(pSourceImage.size(), pSourceImage.type()); Imgproc.cvtColor(pSourceImage, imgHsv, Imgproc.COLOR_RGB2HSV); List <Mat> vChannels = new List <Mat>(3); // 3 channels Core.split(imgHsv, vChannels); Core.inRange(vChannels[0], new Scalar(lowerHue), new Scalar(upperHue), vChannels[0]); Core.inRange(vChannels[1], new Scalar(lowerSaturation), new Scalar(upperSaturation), vChannels[1]); Core.inRange(vChannels[2], new Scalar(lowerVariance), new Scalar(upperVariance), vChannels[2]); Mat filter = vChannels[0] & vChannels[1] & vChannels[2]; ShowImage(filter, "Filter"); //Imgproc.dilate(filter, filter, new Mat()); //Imgproc.dilate(filter, filter, new Mat()); //Imgproc.erode(filter, filter, new Mat()); //Imgproc.dilate(filter, filter, new Mat()); //ShowImage(filter, "Dilate"); Mat imgResult = new Mat(pSourceImage.size(), pSourceImage.type()); pSourceImage.copyTo(imgResult, filter); ShowImage(imgResult, "Filtered"); //Imgproc.medianBlur(imgResult, imgResult, 3); //ShowImage(imgResult, "Blurred"); Imgproc.threshold(imgResult, imgResult, lowerThreshold, upperThreshold, Imgproc.THRESH_BINARY_INV); ShowImage(imgResult, "Threshold"); Imgproc.cvtColor(imgResult, imgResult, Imgproc.COLOR_RGB2GRAY); ShowImage(imgResult, "GRAY"); Mat circles = new Mat(); Imgproc.HoughCircles(imgResult, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 45, pCircleDetectorModel.param1, pCircleDetectorModel.param2, pCircleDetectorModel.minRadius, pCircleDetectorModel.maxRadius); Debug.Log("Number of circles:" + circles.cols()); Point pt = new Point(); for (int i = 0; i < circles.cols(); i++) { double[] data = circles.get(0, i); pt.x = data[0]; pt.y = data[1]; double rho = data[2]; Imgproc.circle(pSourceImage, pt, (int)rho, new Scalar(255, 0, 0, 255), 3); } ShowImage(pSourceImage, "circles"); }
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()); } }