TextDetectionExample.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #if !UNITY_WSA_10_0
  2. using UnityEngine;
  3. using UnityEngine.SceneManagement;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using OpenCVForUnity.CoreModule;
  8. using OpenCVForUnity.ImgprocModule;
  9. using OpenCVForUnity.TextModule;
  10. using OpenCVForUnity.ImgcodecsModule;
  11. using OpenCVForUnity.UnityUtils;
  12. namespace OpenCVForUnityExample
  13. {
  14. /// <summary>
  15. /// Text Detection Example
  16. /// A demo script of the Extremal Region Filter algorithm described in:Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012.
  17. /// Referring to https://github.com/opencv/opencv_contrib/blob/master/modules/text/samples/textdetection.py.
  18. /// </summary>
  19. public class TextDetectionExample : MonoBehaviour
  20. {
  21. string scenetext01_jpg_filepath;
  22. string trained_classifierNM1_xml_filepath;
  23. string trained_classifierNM2_xml_filepath;
  24. #if UNITY_WEBGL && !UNITY_EDITOR
  25. IEnumerator getFilePath_Coroutine;
  26. #endif
  27. // Use this for initialization
  28. void Start ()
  29. {
  30. #if UNITY_WEBGL && !UNITY_EDITOR
  31. getFilePath_Coroutine = GetFilePath ();
  32. StartCoroutine (getFilePath_Coroutine);
  33. #else
  34. scenetext01_jpg_filepath = Utils.getFilePath ("text/scenetext01.jpg");
  35. trained_classifierNM1_xml_filepath = Utils.getFilePath ("text/trained_classifierNM1.xml");
  36. trained_classifierNM2_xml_filepath = Utils.getFilePath ("text/trained_classifierNM2.xml");
  37. Run ();
  38. #endif
  39. }
  40. #if UNITY_WEBGL && !UNITY_EDITOR
  41. private IEnumerator GetFilePath()
  42. {
  43. var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync ("text/scenetext01.jpg", (result) => {
  44. scenetext01_jpg_filepath = result;
  45. });
  46. yield return getFilePathAsync_0_Coroutine;
  47. var getFilePathAsync_1_Coroutine = Utils.getFilePathAsync ("text/trained_classifierNM1.xml", (result) => {
  48. trained_classifierNM1_xml_filepath = result;
  49. });
  50. yield return getFilePathAsync_1_Coroutine;
  51. var getFilePathAsync_2_Coroutine = Utils.getFilePathAsync ("text/trained_classifierNM2.xml", (result) => {
  52. trained_classifierNM2_xml_filepath = result;
  53. });
  54. yield return getFilePathAsync_2_Coroutine;
  55. getFilePath_Coroutine = null;
  56. Run ();
  57. }
  58. #endif
  59. private void Run ()
  60. {
  61. //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console.
  62. Utils.setDebugMode (true);
  63. Mat img = Imgcodecs.imread (scenetext01_jpg_filepath);
  64. #if !UNITY_WSA_10_0
  65. if (img.empty ()) {
  66. Debug.LogError ("text/scenetext01.jpg is not loaded. Please copy from “OpenCVForUnity/StreamingAssets/text/” to “Assets/StreamingAssets/” folder. ");
  67. }
  68. #endif
  69. //# for visualization
  70. Mat vis = new Mat ();
  71. img.copyTo (vis);
  72. Imgproc.cvtColor (vis, vis, Imgproc.COLOR_BGR2RGB);
  73. //# Extract channels to be processed individually
  74. List<Mat> channels = new List<Mat> ();
  75. Text.computeNMChannels (img, channels);
  76. //# Append negative channels to detect ER- (bright regions over dark background)
  77. int cn = channels.Count;
  78. for (int i = 0; i < cn; i++) {
  79. channels.Add (new Scalar (255) - channels [i]);
  80. }
  81. //# Apply the default cascade classifier to each independent channel (could be done in parallel)
  82. Debug.Log ("Extracting Class Specific Extremal Regions from " + channels.Count + " channels ...");
  83. Debug.Log (" (...) this may take a while (...)");
  84. foreach (var channel in channels) {
  85. ERFilter er1 = Text.createERFilterNM1 (trained_classifierNM1_xml_filepath, 16, 0.00015f, 0.13f, 0.2f, true, 0.1f);
  86. ERFilter er2 = Text.createERFilterNM2 (trained_classifierNM2_xml_filepath, 0.5f);
  87. List<MatOfPoint> regions = new List<MatOfPoint> ();
  88. Text.detectRegions (channel, er1, er2, regions);
  89. MatOfRect matOfRects = new MatOfRect ();
  90. Text.erGrouping (img, channel, regions, matOfRects);
  91. // Text.erGrouping (img, channel, regions, matOfRects, Text.ERGROUPING_ORIENTATION_ANY, Utils.getFilePath ("text/trained_classifier_erGrouping.xml"), 0.5f);
  92. List<OpenCVForUnity.CoreModule.Rect> rects = matOfRects.toList ();
  93. //#Visualization
  94. foreach (var rect in rects) {
  95. Imgproc.rectangle (vis, new Point (rect.x, rect.y), new Point (rect.x + rect.width, rect.y + rect.height), new Scalar (255, 0, 0), 2);
  96. Imgproc.rectangle (vis, new Point (rect.x, rect.y), new Point (rect.x + rect.width, rect.y + rect.height), new Scalar (255, 255, 255), 1);
  97. }
  98. }
  99. Texture2D texture = new Texture2D (vis.cols (), vis.rows (), TextureFormat.RGBA32, false);
  100. Utils.matToTexture2D (vis, texture);
  101. gameObject.GetComponent<Renderer> ().material.mainTexture = texture;
  102. Utils.setDebugMode (false);
  103. }
  104. // Update is called once per frame
  105. void Update ()
  106. {
  107. }
  108. /// <summary>
  109. /// Raises the destroy event.
  110. /// </summary>
  111. void OnDestroy ()
  112. {
  113. #if UNITY_WEBGL && !UNITY_EDITOR
  114. if (getFilePath_Coroutine != null) {
  115. StopCoroutine (getFilePath_Coroutine);
  116. ((IDisposable)getFilePath_Coroutine).Dispose ();
  117. }
  118. #endif
  119. }
  120. /// <summary>
  121. /// Raises the back button click event.
  122. /// </summary>
  123. public void OnBackButtonClick ()
  124. {
  125. SceneManager.LoadScene ("OpenCVForUnityExample");
  126. }
  127. }
  128. }
  129. #endif