Streaming des images en direct de la caméra vers Unity3D

Supposons que je dispose d’une caméra sans fil que je souhaite diffuser en continu, en temps réel, des séquences vidéo à l’unité. Y a-t-il un moyen d’y parvenir?

Questions bonus:

  • Qu’en est-il des caméras avec des angles plus larges (180, voire 360)
  • À quel point le délai serait-il problématique s’il s’agit d’une séquence avec laquelle je souhaite interagir?
  • Possible d’envoyer plus de données telles que la perception de la profondeur (à l’aide d’une caméra de perception de la profondeur) en dehors du métrage normal uniquement?
  • Suis-je fou ou est-ce que cela a été fait?

Merci d’avance

Je suppose que c’est une caméra avec port Ethernet ou Wi-Fi à laquelle vous pouvez vous connecter et diffuser des images en direct.

Si oui, alors oui, cela peut être fait avec Unity.

Comment cela se fait sans une bibliothèque externe :

Connexion à la caméra :

1 .Connectez-vous au même réseau local avec la caméra ou si le protocole unpn est pris en charge, vous pouvez également vous connecter via Internet. Pour ce faire, vous avez généralement besoin de l’adresse IP et du port de la caméra. Supposons que l’adresse IP de la caméra est 192.168.1.5 et le numéro de port est 900 . L’URL à laquelle se connecter est http://192.168.1.5:900 .

Parfois, il s’agit simplement d’une URL se terminant par .mjpg ou .bin, telle que http://192.168.1.5/mjpg/video.mjpg et http://192.168.1.5/mjpg/video.bin

Chaque caméra est différente. La seule façon de trouver l’URL est de lire son manuel. Si le manuel n’est pas disponible, connectez-le avec son application officielle, puis utilisez Wireshark pour découvrir l’URL de la caméra Image. Le username et le password (si nécessaire) sont également disponibles dans le manuel. Si non disponible, google le numéro de modèle et tout ce dont vous avez besoin devrait être trouvé.

Extraire le JPEG de la caméra :

Une fois connecté à l’appareil photo, celui-ci vous enverra une infinité de données. Ces données, vous pouvez numériser et récupérer l’image à partir d’elle.

2. Recherchez l’en-tête JPEG qui est 0xFF suivi de 0xD8 . Si ces deux octets sont côte à côte, commencez à les lire et continuez de les enregistrer dans un tableau. Vous pouvez utiliser une variable d’index ( int ) pour conserver le nombre d’octets que vous avez reçus.

 int counter = 0; byte[] completeImageByte = new byte[500000]; byte[] receivedBytes = new byte[500000]; receivedBytes[counter] = byteFromCamera; counter++; 

3. Pendant la lecture des données de la caméra, vérifiez si les deux octets suivants sont le pied de page JPEG, 0xFF suivi de 0xD9 . Si cela est vrai, alors vous avez reçu l’image complète (1 image).

Vos octets d’image doivent ressembler à quelque chose comme:

0xFF 0xD8 octets (en milliers) ….. puis 0xFF 0xD9

Copiez receivedBytes dans la variable completeImageByte afin qu’elle puisse être utilisée pour afficher l’image ultérieurement. Remettre la variable de counter à 0.

 Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter); counter = 0; 

Affichage de l’image JPEG à l’écran :

4. Afficher l’image à l’écran

Etant donné que vous recevrez plusieurs images par seconde, le moyen le plus efficace d’afficher ceci est d’utiliser le composant RawImage . Donc, n’utilisez pas Image ou Sprite Renderer pour cela si vous voulez que cela fonctionne sur des appareils mobiles.

 public RawImage screenDisplay; if(updateFrame){ Texture2D camTexture = new Texture2D(2, 2); camTexture.LoadImage(completeImageByte); screenDisplay.texture = camTexture; } 

Il suffit de faire camTexture = new Texture2D(2, 2); une fois dans la fonction Start() .

5. Revenez à l’étape 2 et continuez jusqu’à ce que vous souhaitiez tout à fait.

API pour la connexion à la caméra:.

Utilisez HttpWebRequest si la caméra nécessite une authentification (nom d’utilisateur et mot de passe).

Pour ceux qui ne nécessitent pas d’authentification, utilisez UnityWebRequest . Lorsque vous utilisez UnityWebRequest , vous devez UnityWebRequest vos propres classes à partir de DownloadHandlerScript , UnityWebRequest votre application se bloquera lorsque vous recevrez des données sans interruption.

Exemple de dérivation de votre propre classe à partir de DownloadHandlerScript :

 using UnityEngine; using System.Collections; using UnityEngine.Networking; public class CustomWebRequest : DownloadHandlerScript { // Standard scripted download handler - will allocate memory on each ReceiveData callback public CustomWebRequest() : base() { } // Pre-allocated scripted download handler // Will reuse the supplied byte array to deliver data. // Eliminates memory allocation. public CustomWebRequest(byte[] buffer) : base(buffer) { } // Required by DownloadHandler base class. Called when you address the 'bytes' property. protected override byte[] GetData() { return null; } // Called once per frame when data has been received from the network. protected override bool ReceiveData(byte[] byteFromCamera, int dataLength) { if (byteFromCamera == null || byteFromCamera.Length < 1) { //Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer"); return false; } //Search of JPEG Image here return true; } // Called when all data has been received from the server and delivered via ReceiveData protected override void CompleteContent() { //Debug.Log("CustomWebRequest :: CompleteContent - DOWNLOAD COMPLETE!"); } // Called when a Content-Length header is received from the server. protected override void ReceiveContentLength(int contentLength) { //Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength)); } } 

Utilisation :

 using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Test : MonoBehaviour { CustomWebRequest camImage; UnityWebRequest webRequest; byte[] bytes = new byte[90000]; void Start() { ssortingng url = "http://camUrl/mjpg/video.mjpg"; webRequest = new UnityWebRequest(url); webRequest.downloadHandler = new CustomWebRequest(bytes); webRequest.Send(); } } 

Vous pouvez les exécuter aux étapes 2 , 3 , 4 et 5 dans la fonction ReceiveData partir du script CustomWebRequest .

Caméra de contrôle :

Les caméras ont des commandes pour effectuer un panoramique, une rotation, un retournement, un miroir et une autre fonction. C’est différent dans chaque caméra, mais il est simple de faire une demande GET / POST à ​​une URL de la caméra et de fournir les requêtes. Ces commandes peuvent être trouvées dans le manuel de l'appareil photo.

Par exemple: http://192.168.1.5?pan=50&rotate=90

Autres frameworks :

AForge - Un cadre libre capable de gérer les formats JPEG / MJPES et FFMPEG à partir de l'appareil photo. Vous devez le modifier pour fonctionner avec Unity et vous devriez le faire si vous ne pouvez pas effectuer les étapes 2 , 3 , 4 et 5 .