質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

367閲覧

udp通信を用いて、MATLABからunityへ画像データを送り受信した画像データをもとにunity側で画像を表示させたい。

mixthki

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2023/12/12 07:53

編集2023/12/13 18:57

実現したいこと

udp通信を用いて、MATLABからunityへ画像データを送り受信した画像データをもとにunity側で画像を表示させる。

現在卒業研究で、udp通信を用いてMATLABからunityに画像データを送信してunity側で画像を表示させるというプログラムを書いているのですが、表示させることができません。どこが悪いのかもよくわからないので、どのようにしたら画像を表示することができるかご教授お願いいたします。
*画像サイズは横が291、縦が380です。また、受信したバイト配列のデータの長さは512です。

試したこと(Texture2Dの大きさを変える)

エラーメッセージ

該当のソースコード

c#

1**udp.cs(unity)** 2 3using UnityEngine; 4using UnityEngine.UI; 5using System.Net.Sockets; 6using System.Net; 7using System.IO; 8using System; 9 10public class udp : MonoBehaviour 11{ 12 public int port = 51000; 13 public RawImage rawImage; 14 15 private UdpClient udpClient; 16 17 void Start() 18 { 19 udpClient = new UdpClient(port); 20 udpClient.BeginReceive(ReceiveCallback, null); 21 } 22 23 private void ReceiveCallback(IAsyncResult result) 24 { 25 IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); 26 byte[] receivedData = udpClient.EndReceive(result, ref endPoint); //配列の大きさの指定をしてみる。 27 28 Debug.Log("Received data size: " + receivedData.Length); 29 30 // 受信したデータをテクスチャに変換 31 Texture2D receivedTexture = new Texture2D(291, 380); 32 receivedTexture.LoadImage(receivedData); 33 34 // メインスレッドでUIの更新を行う 35 UnityMainThreadDispatcher.Instance().Enqueue(() => 36 { 37 // RawImageにテクスチャをセット 38 rawImage.texture = receivedTexture; 39 }); 40 41 // 再度受信を開始 42 udpClient.BeginReceive(ReceiveCallback, null); 43 } 44 45 void OnDisable() 46 { 47 if (udpClient != null) 48 { 49 udpClient.Close(); 50 } 51 } 52} 53 54 55**UnityMainThreadDispatcher.cs(unity)** 56 57using UnityEngine; 58using System.Collections; 59using System.Collections.Generic; 60using System; 61 62public class UnityMainThreadDispatcher : MonoBehaviour 63{ 64 private static readonly Queue<Action> _executionQueue = new Queue<Action>(); 65 66 public void Update() 67 { 68 lock (_executionQueue) 69 { 70 while (_executionQueue.Count > 0) 71 { 72 _executionQueue.Dequeue().Invoke(); 73 74 } 75 } 76 } 77 78 public void Enqueue(IEnumerator action) 79 { 80 lock (_executionQueue) 81 { 82 _executionQueue.Enqueue(() => { 83 StartCoroutine(action); 84 }); 85 } 86 } 87 88 public void Enqueue(Action action) 89 { 90 lock (_executionQueue) 91 { 92 _executionQueue.Enqueue(action); 93 } 94 } 95 96 private static UnityMainThreadDispatcher _instance = null; 97 98 public static bool Exists() 99 { 100 return _instance != null; 101 } 102 103 public static UnityMainThreadDispatcher Instance() 104 { 105 if (!Exists()) 106 { 107 throw new Exception("UnityMainThreadDispatcher does not exist."); 108 } 109 return _instance; 110 } 111 112 void Awake() 113 { 114 if (_instance == null) 115 { 116 _instance = this; 117 DontDestroyOnLoad(this.gameObject); 118 119 } 120 } 121 122 void OnDestroy() 123 { 124 _instance = null; 125 } 126} 127 128 129**MATLAB** 130clear all; 131 132% 送信する画像のパス 133imagePath = 'C:\Users\sog4-\My project (1)\Assets\Scripts\MicrosoftTeams-image.png'; 134 135img = imread(imagePath); 136 137% 画像データを1次元ベクトルに変換 138img_vector = img(:); 139 140% 送信先のIPアドレスとポート番号 141ipAddress = '127.0.0.1'; 142port = 51000; 143 144% UDPオブジェクトの作成 145udpSender = udp(ipAddress, port, 'OutputBufferSize', numel(img_vector)); 146fopen(udpSender); 147 148% 画像データをUDPで送信 149 150fwrite(udpSender, img_vector, 'uint8'); 151 152% UDPオブジェクトを閉じる 153fclose(udpSender); 154delete(udpSender); 155

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fiveHundred

2023/12/12 10:15 編集

UDP通信は仕様上「データの順序付けが保証されていない」「パケットが失われる可能性がある」ということがありますが、それを承知の上での質問ですか?
mixthki

2023/12/13 18:53

はい、そうです。
fiveHundred

2023/12/14 02:36

- 画像のサイズは512バイト(0.5KBぐらい)ですか? - MATLABのコードにimreadとありますが、これによってRGBAなどの別の形式になったりしていませんか? - Texture2Dではなく、直接PNGファイルとして書き出した場合、その画像は正常に開けますか? - 「パケットが失われる可能性がある」=「画像データの一部が無くなる」ということになりますが、その対策は考えていますか?。もしくは、そうなった画像は諦めるということですか?
mixthki

2023/12/15 20:16

画像のサイズは512バイトで、別の形式にもなっていないはずです。パケットが失われる可能性への対策は考えていませんでした。また、画像をpngファイルとして正常に開くこともできます。
guest

回答1

0

C#

1 // 受信したデータをテクスチャに変換 2 Texture2D receivedTexture = new Texture2D(291, 380); 3 receivedTexture.LoadImage(receivedData); 4 5 // メインスレッドでUIの更新を行う 6 UnityMainThreadDispatcher.Instance().Enqueue(() => 7 { 8 // RawImageにテクスチャをセット 9 rawImage.texture = receivedTexture; 10 });

上記を以下のようにするとどうなりますか?
詳細はコードのコメントに記載しています。

C#

1 // メインスレッドでUIの更新を行う 2 UnityMainThreadDispatcher.Instance().Enqueue(() => 3 { 4 // 受信したデータをテクスチャに変換 5 // (メインスレッドに変更) 6 Texture2D receivedTexture = new Texture2D(291, 380); 7 8 // (上手くいかないなら「ImageConversion.LoadImage(receivedTexture, receivedData);」も試してください) 9 receivedTexture.LoadImage(receivedData); 10 11 // (念のため追加) 12 receivedTexture.Apply(); 13 14 // RawImageにテクスチャをセット 15 rawImage.texture = receivedTexture; 16 });

投稿2023/12/16 01:08

fiveHundred

総合スコア9810

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mixthki

2023/12/18 10:34

返信が遅くなり申し訳ございません。上記のプログラムを試してみて、画像の表示はできるようにはなったのですが、その画像が本来の画像ではなく、赤字で「?」という文字が表示されます。
fiveHundred

2023/12/19 03:16

過去のコメントで > また、画像をpngファイルとして正常に開くこともできます。 とのことですが、以下を読んだ感じ、pngファイルそのままでは無く、形式に応じたRGBもしくはグレースケールの配列とのことです。 https://jp.mathworks.com/help/matlab/ref/imread.html 私が言っている「直接PNGファイルとして書き出した場合」とは、受信後のデータを「File.WriteAllBytes("foo.png", receivedData);」などで書き出し、それが正常に開けるか、という意味です。 もしURLの通りであれば、imreadを使わず、pngファイルのデータをそのまま送受信する必要があります。 もしくはTexture2D.LoadRawTextureData関数でimreadのRGB形式を読み込む方法もありますが、おそらくpngファイルよりも送受信データが大きくなるため、ローカル環境で無ければ避けたほうがいいでしょう。
mixthki

2023/12/25 02:26

最終的にはローカル環境ではないのですが、どのような部分を変えればよいか教えてくださいますでしょうか?本当に無知で申し訳ございません。
fiveHundred

2023/12/25 03:29

> imreadを使わず、pngファイルのデータをそのまま送受信する必要があります。 上記の通りで、MATLAB側を変更することになります。 MATLABは触ったことないので、これ以上は分かりません。
mixthki

2023/12/25 17:54

了解です。わざわざご回答いただきありがとうございます。これからの参考にさせてもらいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問