123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- using OpenCVForUnity.CoreModule;
- using OpenCVForUnity.ImgprocModule;
- using OpenCVForUnity.UnityUtils;
- using System;
- using System.Collections;
- using UnityEngine;
- using UnityEngine.SceneManagement;
- namespace OpenCVForUnityExample
- {
- /// <summary>
- /// WebCamTextureToMat Example
- /// An example of converting a WebCamTexture image to OpenCV's Mat format.
- /// </summary>
- public class WebCamTextureToMatExample : MonoBehaviour
- {
- /// <summary>
- /// Set the name of the device to use.
- /// </summary>
- [SerializeField, TooltipAttribute("Set the name of the device to use.")]
- public string requestedDeviceName = null;
- /// <summary>
- /// Set the width of WebCamTexture.
- /// </summary>
- [SerializeField, TooltipAttribute("Set the width of WebCamTexture.")]
- public int requestedWidth = 640;
- /// <summary>
- /// Set the height of WebCamTexture.
- /// </summary>
- [SerializeField, TooltipAttribute("Set the height of WebCamTexture.")]
- public int requestedHeight = 480;
- /// <summary>
- /// Set FPS of WebCamTexture.
- /// </summary>
- [SerializeField, TooltipAttribute("Set FPS of WebCamTexture.")]
- public int requestedFPS = 30;
- /// <summary>
- /// Set whether to use the front facing camera.
- /// </summary>
- [SerializeField, TooltipAttribute("Set whether to use the front facing camera.")]
- public bool requestedIsFrontFacing = false;
- /// <summary>
- /// The webcam texture.
- /// </summary>
- WebCamTexture webCamTexture;
- /// <summary>
- /// The webcam device.
- /// </summary>
- WebCamDevice webCamDevice;
- /// <summary>
- /// The rgba mat.
- /// </summary>
- Mat rgbaMat;
- /// <summary>
- /// The colors.
- /// </summary>
- Color32[] colors;
- /// <summary>
- /// The texture.
- /// </summary>
- Texture2D texture;
- /// <summary>
- /// Indicates whether this instance is waiting for initialization to complete.
- /// </summary>
- bool isInitWaiting = false;
- /// <summary>
- /// Indicates whether this instance has been initialized.
- /// </summary>
- bool hasInitDone = false;
- /// <summary>
- /// The FPS monitor.
- /// </summary>
- FpsMonitor fpsMonitor;
- // Use this for initialization
- void Start()
- {
- fpsMonitor = GetComponent<FpsMonitor>();
- Initialize();
- }
- /// <summary>
- /// Initializes webcam texture.
- /// </summary>
- 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
- }
- /// <summary>
- /// Initializes webcam texture by coroutine.
- /// </summary>
- private IEnumerator _Initialize()
- {
- if (hasInitDone)
- Dispose();
- isInitWaiting = true;
- // Checks camera permission state.
- #if (UNITY_IOS || UNITY_WEBGL) && UNITY_2018_1_OR_NEWER
- UserAuthorization mode = UserAuthorization.WebCam;
- if (!Application.HasUserAuthorization(mode))
- {
- isUserRequestingPermission = true;
- yield return Application.RequestUserAuthorization(mode);
- float timeElapsed = 0;
- while (isUserRequestingPermission)
- {
- if (timeElapsed > 0.25f)
- {
- isUserRequestingPermission = false;
- break;
- }
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- }
- if (!Application.HasUserAuthorization(mode))
- {
- if (fpsMonitor != null)
- {
- fpsMonitor.consoleText = "Camera permission is denied.";
- }
- isInitWaiting = false;
- yield break;
- }
- #elif UNITY_ANDROID && UNITY_2018_3_OR_NEWER
- string permission = UnityEngine.Android.Permission.Camera;
- if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permission))
- {
- isUserRequestingPermission = true;
- UnityEngine.Android.Permission.RequestUserPermission(permission);
- float timeElapsed = 0;
- while (isUserRequestingPermission)
- {
- if (timeElapsed > 0.25f)
- {
- isUserRequestingPermission = false;
- break;
- }
- timeElapsed += Time.deltaTime;
- yield return null;
- }
- }
- if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permission))
- {
- if (fpsMonitor != null)
- {
- fpsMonitor.consoleText = "Camera permission is denied.";
- }
- isInitWaiting = false;
- yield break;
- }
- #endif
- // Creates the camera
- var devices = WebCamTexture.devices;
- if (!String.IsNullOrEmpty(requestedDeviceName))
- {
- int requestedDeviceIndex = -1;
- if (Int32.TryParse(requestedDeviceName, out requestedDeviceIndex))
- {
- if (requestedDeviceIndex >= 0 && requestedDeviceIndex < devices.Length)
- {
- webCamDevice = devices[requestedDeviceIndex];
- webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS);
- }
- }
- else
- {
- for (int cameraIndex = 0; cameraIndex < devices.Length; cameraIndex++)
- {
- if (devices[cameraIndex].name == requestedDeviceName)
- {
- webCamDevice = 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 < devices.Length; cameraIndex++)
- {
- #if UNITY_2018_3_OR_NEWER
- if (devices[cameraIndex].kind != WebCamKind.ColorAndDepth && devices[cameraIndex].isFrontFacing == requestedIsFrontFacing)
- #else
- if (devices[cameraIndex].isFrontFacing == requestedIsFrontFacing)
- #endif
- {
- webCamDevice = devices[cameraIndex];
- webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS);
- break;
- }
- }
- }
- if (webCamTexture == null)
- {
- if (devices.Length > 0)
- {
- webCamDevice = 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 (webCamTexture.didUpdateThisFrame)
- {
- 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;
- }
- }
- }
- #if ((UNITY_IOS || UNITY_WEBGL) && UNITY_2018_1_OR_NEWER) || (UNITY_ANDROID && UNITY_2018_3_OR_NEWER)
- bool isUserRequestingPermission;
- IEnumerator OnApplicationFocus(bool hasFocus)
- {
- yield return null;
- if (isUserRequestingPermission && hasFocus)
- isUserRequestingPermission = false;
- }
- #endif
- /// <summary>
- /// Releases all resource.
- /// </summary>
- 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;
- }
- }
- /// <summary>
- /// Raises the webcam texture initialized event.
- /// </summary>
- 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, new Scalar(0, 0, 0, 255));
- Utils.matToTexture2D(rgbaMat, texture, colors);
- gameObject.GetComponent<Renderer>().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);
- }
- }
- /// <summary>
- /// Raises the destroy event.
- /// </summary>
- void OnDestroy()
- {
- Dispose();
- }
- /// <summary>
- /// Raises the back button click event.
- /// </summary>
- public void OnBackButtonClick()
- {
- SceneManager.LoadScene("OpenCVForUnityExample");
- }
- /// <summary>
- /// Raises the play button click event.
- /// </summary>
- public void OnPlayButtonClick()
- {
- if (hasInitDone)
- webCamTexture.Play();
- }
- /// <summary>
- /// Raises the pause button click event.
- /// </summary>
- public void OnPauseButtonClick()
- {
- if (hasInitDone)
- webCamTexture.Pause();
- }
- /// <summary>
- /// Raises the stop button click event.
- /// </summary>
- public void OnStopButtonClick()
- {
- if (hasInitDone)
- webCamTexture.Stop();
- }
- /// <summary>
- /// Raises the change camera button click event.
- /// </summary>
- public void OnChangeCameraButtonClick()
- {
- if (hasInitDone)
- {
- requestedDeviceName = null;
- requestedIsFrontFacing = !requestedIsFrontFacing;
- Initialize();
- }
- }
- }
- }
|