KNNExample.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using OpenCVForUnity.CoreModule;
  2. using OpenCVForUnity.ImgprocModule;
  3. using OpenCVForUnity.MlModule;
  4. using OpenCVForUnity.UnityUtils;
  5. using UnityEngine;
  6. using UnityEngine.SceneManagement;
  7. namespace OpenCVForUnityExample
  8. {
  9. /// <summary>
  10. /// KNN Example
  11. /// An example to understand the concepts of the k-Nearest Neighbour (kNN) algorithm.
  12. /// https://docs.opencv.org/4.x/d5/d26/tutorial_py_knn_understanding.html
  13. /// </summary>
  14. public class KNNExample : MonoBehaviour
  15. {
  16. // Use this for initialization
  17. void Start()
  18. {
  19. //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console.
  20. Utils.setDebugMode(true);
  21. // Feature set containing (x,y) values of 25 known/training data
  22. Mat trainData = new Mat(25, 2, CvType.CV_32FC1);
  23. using (Mat trainDataInt = new Mat(25, 2, CvType.CV_16SC1))
  24. {
  25. Core.randu(trainDataInt, 0, 100); // random values
  26. trainDataInt.convertTo(trainData, CvType.CV_32FC1);
  27. }
  28. //Debug.Log(trainData.dump());
  29. // Label each one either Red or Blue with numbers 0 and 1
  30. Mat responses = new Mat(25, 1, CvType.CV_32FC1);
  31. using (Mat responsesInt = new Mat(25, 1, CvType.CV_16SC1))
  32. {
  33. Core.randu(responsesInt, 0, 2); // random values
  34. responsesInt.convertTo(responses, CvType.CV_32FC1);
  35. }
  36. //Debug.Log(responses.dump());
  37. KNearest knn = KNearest.create();
  38. knn.train(trainData, Ml.ROW_SAMPLE, responses);
  39. Mat newcomer = new Mat(1, 2, CvType.CV_32FC1, new Scalar(50, 50));
  40. Mat results = new Mat();
  41. Mat neighbours = new Mat();
  42. Mat dist = new Mat();
  43. knn.findNearest(newcomer, 3, results, neighbours, dist);
  44. Mat plotMat = new Mat(500, 500, CvType.CV_8UC4, new Scalar(255, 255, 255, 255));
  45. // Take Red neighbours and plot them
  46. // Take Blue neighbours and plot them
  47. for (int i = 0; i < trainData.rows(); i++)
  48. {
  49. bool red = ((int)responses.get(i, 0)[0] == 0);
  50. double x = trainData.get(i, 0)[0];
  51. double y = trainData.get(i, 1)[0];
  52. Imgproc.circle(plotMat, new Point(x * 5f, y * 5f), 5, red ? new Scalar(255, 0, 0, 255) : new Scalar(0, 0, 255, 255), -1);
  53. }
  54. // Plot newcomer and the neighbours distance circle
  55. Imgproc.circle(plotMat, new Point(50f * 5f, 50f * 5f), 5, new Scalar(0, 255, 0, 255), -1);
  56. Imgproc.circle(plotMat, new Point(50f * 5f, 50f * 5f), (int)(Mathf.Sqrt((float)dist.get(0, 2)[0]) * 5f), new Scalar(0, 255, 0, 255), 1);
  57. Debug.Log("0:Red / 1:Blue");
  58. Debug.Log("result: " + results.dump());
  59. Debug.Log("neighbours: " + neighbours.dump());
  60. Debug.Log("distance: " + dist.dump());
  61. Imgproc.putText(plotMat, "0:Red / 1:Blue", new Point(5, 30), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 0, 255));
  62. Imgproc.putText(plotMat, "result: " + results.dump(), new Point(5, 65), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 0, 255));
  63. Imgproc.putText(plotMat, "neighbours: " + neighbours.dump(), new Point(5, 100), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 0, 255));
  64. Imgproc.putText(plotMat, "distance: " + dist.dump(), new Point(5, 135), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 0, 255));
  65. Texture2D texture = new Texture2D(plotMat.cols(), plotMat.rows(), TextureFormat.RGBA32, false);
  66. Utils.matToTexture2D(plotMat, texture);
  67. gameObject.GetComponent<Renderer>().material.mainTexture = texture;
  68. Utils.setDebugMode(false);
  69. }
  70. // Update is called once per frame
  71. void Update()
  72. {
  73. }
  74. /// <summary>
  75. /// Raises the back button click event.
  76. /// </summary>
  77. public void OnBackButtonClick()
  78. {
  79. SceneManager.LoadScene("OpenCVForUnityExample");
  80. }
  81. }
  82. }