using System; using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using OpenCVForUnity.CoreModule; using OpenCVForUnity.UnityUtils; using OpenCVForUnity.ImgprocModule; namespace OpenCVForUnityExample { /// /// WebCamTextureToMat Example /// An example of converting a WebCamTexture image to OpenCV's Mat format. /// public class WebCamTextureToMatExample : MonoBehaviour { /// /// Set the name of the device to use. /// [SerializeField, TooltipAttribute ("Set the name of the device to use.")] public string requestedDeviceName = null; /// /// Set the width of WebCamTexture. /// [SerializeField, TooltipAttribute ("Set the width of WebCamTexture.")] public int requestedWidth = 640; /// /// Set the height of WebCamTexture. /// [SerializeField, TooltipAttribute ("Set the height of WebCamTexture.")] public int requestedHeight = 480; /// /// Set FPS of WebCamTexture. /// [SerializeField, TooltipAttribute ("Set FPS of WebCamTexture.")] public int requestedFPS = 30; /// /// Set whether to use the front facing camera. /// [SerializeField, TooltipAttribute ("Set whether to use the front facing camera.")] public bool requestedIsFrontFacing = false; /// /// The webcam texture. /// WebCamTexture webCamTexture; /// /// The webcam device. /// WebCamDevice webCamDevice; /// /// The rgba mat. /// Mat rgbaMat; /// /// The colors. /// Color32[] colors; /// /// The texture. /// Texture2D texture; /// /// Indicates whether this instance is waiting for initialization to complete. /// bool isInitWaiting = false; /// /// Indicates whether this instance has been initialized. /// bool hasInitDone = false; /// /// The FPS monitor. /// FpsMonitor fpsMonitor; // Use this for initialization void Start () { fpsMonitor = GetComponent (); Initialize (); } /// /// Initializes webcam texture. /// private void Initialize () { if (isInitWaiting) return; #if UNITY_ANDROID && !UNITY_EDITOR // Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices (e.g. Google Pixel, Pixel2). // https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/ // https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178 if (requestedIsFrontFacing) { int rearCameraFPS = requestedFPS; requestedFPS = 15; StartCoroutine (_Initialize ()); requestedFPS = rearCameraFPS; } else { StartCoroutine (_Initialize ()); } #else StartCoroutine (_Initialize ()); #endif } /// /// Initializes webcam texture by coroutine. /// private IEnumerator _Initialize () { if (hasInitDone) Dispose (); isInitWaiting = true; // Creates the camera if (!String.IsNullOrEmpty (requestedDeviceName)) { int requestedDeviceIndex = -1; if (Int32.TryParse (requestedDeviceName, out requestedDeviceIndex)) { if (requestedDeviceIndex >= 0 && requestedDeviceIndex < WebCamTexture.devices.Length) { webCamDevice = WebCamTexture.devices [requestedDeviceIndex]; webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); } } else { for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) { if (WebCamTexture.devices [cameraIndex].name == requestedDeviceName) { webCamDevice = WebCamTexture.devices [cameraIndex]; webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); break; } } } if (webCamTexture == null) Debug.Log ("Cannot find camera device " + requestedDeviceName + "."); } if (webCamTexture == null) { // Checks how many and which cameras are available on the device for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) { if (WebCamTexture.devices [cameraIndex].isFrontFacing == requestedIsFrontFacing) { webCamDevice = WebCamTexture.devices [cameraIndex]; webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); break; } } } if (webCamTexture == null) { if (WebCamTexture.devices.Length > 0) { webCamDevice = WebCamTexture.devices [0]; webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); } else { Debug.LogError ("Camera device does not exist."); isInitWaiting = false; yield break; } } // Starts the camera. webCamTexture.Play (); while (true) { // If you want to use webcamTexture.width and webcamTexture.height on iOS, you have to wait until webcamTexture.didUpdateThisFrame == 1, otherwise these two values will be equal to 16. (http://forum.unity3d.com/threads/webcamtexture-and-error-0x0502.123922/). #if UNITY_IOS && !UNITY_EDITOR && (UNITY_4_6_3 || UNITY_4_6_4 || UNITY_5_0_0 || UNITY_5_0_1) if (webCamTexture.width > 16 && webCamTexture.height > 16) { #else if (webCamTexture.didUpdateThisFrame) { #if UNITY_IOS && !UNITY_EDITOR && UNITY_5_2 while (webCamTexture.width <= 16) { webCamTexture.GetPixels32 (); yield return new WaitForEndOfFrame (); } #endif #endif Debug.Log ("name:" + webCamTexture.deviceName + " width:" + webCamTexture.width + " height:" + webCamTexture.height + " fps:" + webCamTexture.requestedFPS); Debug.Log ("videoRotationAngle:" + webCamTexture.videoRotationAngle + " videoVerticallyMirrored:" + webCamTexture.videoVerticallyMirrored + " isFrongFacing:" + webCamDevice.isFrontFacing); isInitWaiting = false; hasInitDone = true; OnInited (); break; } else { yield return null; } } } /// /// Releases all resource. /// private void Dispose () { isInitWaiting = false; hasInitDone = false; if (webCamTexture != null) { webCamTexture.Stop (); WebCamTexture.Destroy (webCamTexture); webCamTexture = null; } if (rgbaMat != null) { rgbaMat.Dispose (); rgbaMat = null; } if (texture != null) { Texture2D.Destroy (texture); texture = null; } } /// /// Raises the webcam texture initialized event. /// private void OnInited () { if (colors == null || colors.Length != webCamTexture.width * webCamTexture.height) colors = new Color32[webCamTexture.width * webCamTexture.height]; if (texture == null || texture.width != webCamTexture.width || texture.height != webCamTexture.height) texture = new Texture2D (webCamTexture.width, webCamTexture.height, TextureFormat.RGBA32, false); rgbaMat = new Mat (webCamTexture.height, webCamTexture.width, CvType.CV_8UC4); gameObject.GetComponent ().material.mainTexture = texture; gameObject.transform.localScale = new Vector3 (webCamTexture.width, webCamTexture.height, 1); Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation); if (fpsMonitor != null) { fpsMonitor.Add ("width", rgbaMat.width ().ToString ()); fpsMonitor.Add ("height", rgbaMat.height ().ToString ()); fpsMonitor.Add ("orientation", Screen.orientation.ToString ()); } float width = rgbaMat.width (); float height = rgbaMat.height (); float widthScale = (float)Screen.width / width; float heightScale = (float)Screen.height / height; if (widthScale < heightScale) { Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2; } else { Camera.main.orthographicSize = height / 2; } } // Update is called once per frame void Update () { if (hasInitDone && webCamTexture.isPlaying && webCamTexture.didUpdateThisFrame) { Utils.webCamTextureToMat (webCamTexture, rgbaMat, colors); // 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, colors); } } /// /// Raises the destroy event. /// void OnDestroy () { Dispose (); } /// /// Raises the back button click event. /// public void OnBackButtonClick () { SceneManager.LoadScene ("OpenCVForUnityExample"); } /// /// Raises the play button click event. /// public void OnPlayButtonClick () { if (hasInitDone) webCamTexture.Play (); } /// /// Raises the pause button click event. /// public void OnPauseButtonClick () { if (hasInitDone) webCamTexture.Pause (); } /// /// Raises the stop button click event. /// public void OnStopButtonClick () { if (hasInitDone) webCamTexture.Stop (); } /// /// Raises the change camera button click event. /// public void OnChangeCameraButtonClick () { if (hasInitDone) { requestedDeviceName = null; requestedIsFrontFacing = !requestedIsFrontFacing; Initialize (); } } } }