GrabCutExample.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using UnityEngine;
  2. using UnityEngine.SceneManagement;
  3. using System.Collections;
  4. using OpenCVForUnity.CoreModule;
  5. using OpenCVForUnity.ImgprocModule;
  6. using OpenCVForUnity.UnityUtils;
  7. namespace OpenCVForUnityExample
  8. {
  9. /// <summary>
  10. /// GrabCut Example
  11. /// An example of background removal using the Imgproc.grabCut function.
  12. /// http://docs.opencv.org/3.1.0/d8/d83/tutorial_py_grabcut.html
  13. /// </summary>
  14. public class GrabCutExample : MonoBehaviour
  15. {
  16. // Use this for initialization
  17. void Start()
  18. {
  19. Texture2D imageTexture = Resources.Load("face") as Texture2D;
  20. Mat image = new Mat(imageTexture.height, imageTexture.width, CvType.CV_8UC3);
  21. Utils.texture2DToMat(imageTexture, image);
  22. Debug.Log("image.ToString() " + image.ToString());
  23. Texture2D maskTexture = Resources.Load("face_grabcut_mask") as Texture2D;
  24. Mat mask = new Mat(imageTexture.height, imageTexture.width, CvType.CV_8UC1);
  25. Utils.texture2DToMat(maskTexture, mask);
  26. Debug.Log("mask.ToString() " + mask.ToString());
  27. OpenCVForUnity.CoreModule.Rect rectangle = new OpenCVForUnity.CoreModule.Rect(10, 10, image.cols() - 20, image.rows() - 20);
  28. Mat bgdModel = new Mat(); // extracted features for background
  29. Mat fgdModel = new Mat(); // extracted features for foreground
  30. convertToGrabCutValues(mask); // from grayscale values to grabcut values
  31. int iterCount = 5;
  32. //Imgproc.grabCut (image, mask, rectangle, bgdModel, fgdModel, iterCount, Imgproc.GC_INIT_WITH_RECT);
  33. Imgproc.grabCut(image, mask, rectangle, bgdModel, fgdModel, iterCount, Imgproc.GC_INIT_WITH_MASK);
  34. convertToGrayScaleValues(mask); // back to grayscale values
  35. Imgproc.threshold(mask, mask, 128, 255, Imgproc.THRESH_TOZERO);
  36. Mat foreground = new Mat(image.size(), CvType.CV_8UC3, new Scalar(0, 0, 0));
  37. image.copyTo(foreground, mask);
  38. Texture2D texture = new Texture2D(image.cols(), image.rows(), TextureFormat.RGBA32, false);
  39. Utils.matToTexture2D(foreground, texture);
  40. gameObject.GetComponent<Renderer>().material.mainTexture = texture;
  41. }
  42. private void convertToGrayScaleValues(Mat mask)
  43. {
  44. int width = mask.rows();
  45. int height = mask.cols();
  46. byte[] buffer = new byte[width * height];
  47. mask.get(0, 0, buffer);
  48. for (int x = 0; x < width; x++)
  49. {
  50. for (int y = 0; y < height; y++)
  51. {
  52. int value = buffer[y * width + x];
  53. if (value == Imgproc.GC_BGD)
  54. {
  55. buffer[y * width + x] = 0; // for sure background
  56. }
  57. else if (value == Imgproc.GC_PR_BGD)
  58. {
  59. buffer[y * width + x] = 85; // probably background
  60. }
  61. else if (value == Imgproc.GC_PR_FGD)
  62. {
  63. buffer[y * width + x] = (byte)170; // probably foreground
  64. }
  65. else
  66. {
  67. buffer[y * width + x] = (byte)255; // for sure foreground
  68. }
  69. }
  70. }
  71. mask.put(0, 0, buffer);
  72. }
  73. private void convertToGrabCutValues(Mat mask)
  74. {
  75. int width = mask.rows();
  76. int height = mask.cols();
  77. byte[] buffer = new byte[width * height];
  78. mask.get(0, 0, buffer);
  79. for (int x = 0; x < width; x++)
  80. {
  81. for (int y = 0; y < height; y++)
  82. {
  83. int value = buffer[y * width + x];
  84. if (value >= 0 && value < 64)
  85. {
  86. buffer[y * width + x] = Imgproc.GC_BGD; // for sure background
  87. }
  88. else if (value >= 64 && value < 128)
  89. {
  90. buffer[y * width + x] = Imgproc.GC_PR_BGD; // probably background
  91. }
  92. else if (value >= 128 && value < 192)
  93. {
  94. buffer[y * width + x] = Imgproc.GC_PR_FGD; // probably foreground
  95. }
  96. else
  97. {
  98. buffer[y * width + x] = Imgproc.GC_FGD; // for sure foreground
  99. }
  100. }
  101. }
  102. mask.put(0, 0, buffer);
  103. }
  104. // Update is called once per frame
  105. void Update()
  106. {
  107. }
  108. /// <summary>
  109. /// Raises the back button click event.
  110. /// </summary>
  111. public void OnBackButtonClick()
  112. {
  113. SceneManager.LoadScene("OpenCVForUnityExample");
  114. }
  115. }
  116. }