Matlab Unity图像传输,实现Matlab与Unity之间通信

该文章描述了一个使用Unity建立的TCP服务器,用于接收来自Matlab的命令并执行相应操作,如移动相机和显示/隐藏游戏对象。Matlab端通过TCP连接发送指令,Unity端接收并解析这些指令,包括读取图像数据。文章展示了Unity中的代码实现,包括连接管理、数据接收和处理,以及Matlab端的图像读取和通信函数。
摘要由CSDN通过智能技术生成

Unity端实现代码

using System;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using System.Net;
using System.IO;
using System.Globalization;


public class Server : MonoBehaviour {

    //General Init
    private List<ServerClient> clients;
    private List<int> disconnectIndex;

    public int Port;
    public TcpListener server;
    private bool serverStarted;

    public GameObject sphere;

    Camera MainCamera;

    // Use this for initialization
    void Start () {
        clients = new List<ServerClient>();
        disconnectIndex = new List<int>();

        try {
            server = new TcpListener(IPAddress.Any, Port);
            server.Start();

            Startlistening();
            serverStarted = true;
            Debug.Log("Server has started on port:" + Port.ToString());
        }
        catch (Exception e) {
            Debug.Log("Socket Error " + e.Message);
        }

        InvokeRepeating("UpdateLoop", 0f, 0.003f);
    }

    public void UpdateLoop()
    {
        if(!serverStarted)
            return;
        if(clients.Count == 0)
            return;

        for(int c = 0; c < clients.Count; c++ ) {
            //Check if clients are connected
            if(!isConnected(clients[c].tcp)) {
                clients[c].tcp.Close();
                disconnectIndex.Add(c);
                Debug.Log(clients[c].clientName + " has disconnected from the server");
                continue;
            }
            // Check for data from client
            else {
                NetworkStream s = clients[c].tcp.GetStream();
                if(s.DataAvailable) {
                  //  StreamReader reader = new StreamReader(s, true);
                    byte[] DataLength = new byte[1];
                    s.Read(DataLength, 0, 1);
                    if (DataLength != null)
                    {
                        byte[] RecievedString = new byte[(int)DataLength[0]];
                        s.Read(RecievedString, 0, (int)DataLength[0]);
                        OnIncomingData(clients[c],RecievedString); //Handles incoming data
                    }
                    s.Flush();
                }               
            }
        }
        //Clean up Disconnected Clients
        for(int i = 0; i < disconnectIndex.Count; i++) {
            clients.RemoveAt(disconnectIndex[i]);
        }
        disconnectIndex.Clear();
    }

    //Checks if client is connected
    private bool isConnected(TcpClient c)
    {
        try {
            if(c != null && c.Client != null && c.Client.Connected) //Makes sure the client is connected
            {
                if(c.Client.Poll(0, SelectMode.SelectRead))         //Polls the Client for activity
                {
                    return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0); //Checks for response
                }
                
                return true;
            }
            else
                return false;
        }
        catch {
            return false;
        }
    }
    //Begins connection with client
    private void AcceptServerClient(IAsyncResult ar)
    {
        TcpListener listener = (TcpListener)ar.AsyncState;
        ServerClient NewClient = new ServerClient(listener.EndAcceptTcpClient(ar), null);
        Debug.Log("Someone has connected");
        clients.Add(NewClient);
        Startlistening();
    }

    //Starts listening on server socket
    private void Startlistening()
    {
        server.BeginAcceptTcpClient(AcceptServerClient, server);
    }

    //Try to close all the connections gracefully
    public void OnApplicationQuit()
    {
        for (int i = 0; i < clients.Count; i++)
        {
            try
            {
                clients[i].tcp.GetStream().Close();
                clients[i].tcp.Close();
                server.Stop();
            }
            catch { }
        }
        Debug.Log("Connections Closed");
    }

    //Sends out data
    public void OutgoingData(ServerClient c, byte[] data) {
        NetworkStream ClientStream = c.tcp.GetStream();
        try
        {
        ClientStream.Write(data, 0, data.Length);
        }
        catch (Exception e) {
            Debug.LogError("Could not write to client.\n Error:" + e);
        }
    }

    //Handler for incoming data
    private void OnIncomingData(ServerClient c, byte [] ReceivedData)
    {
        string RecivedString = Encoding.UTF8.GetString(ReceivedData,0,ReceivedData.Length);
        char[] delimiterChar = { ':', ','};
        string[] cleanData = RecivedString.Split(delimiterChar);
        string Response;

        //Switch to handle debug messages and extra info between Matlab and Unity
        switch(cleanData[0])
        {      
            case "Camera":
                Debug.Log(cleanData[2]);
                StartCoroutine(SendCamCapture(c, cleanData[2], cleanData[3], cleanData[1]));
                Response = cleanData[3] + ".png";
                break;
            case "MoveCam":
                CamMove(float.Parse(cleanData[1], CultureInfo.InvariantCulture), float.Parse(cleanData[2], CultureInfo.InvariantCulture));
                break;
            case "ActObj":
                ObjAct(int.Parse(cleanData[1], CultureInfo.InvariantCulture));
                break;
            default:
                break;       
        }
    }

    public void CamMove(float movementX, float movementY)
    {
        GameObject.Find("Main Camera").transform.position = new Vector3(movementX, movementY, 0);
    }

    public void ObjAct(int activate)
    {
        if (activate == 1)
        {
            sphere.SetActive(true);
        }
        if (activate == 0)
        {
            sphere.SetActive(false);
        }
    }

    //Organizes and Sends Picture
    IEnumerator SendCamCapture(ServerClient c, string FilePath, string FileName, string CameraSelect)
    {
        GameObject Cube = GameObject.Find("saveCam");
        camScript CubeComp = Cube.GetComponent<camScript>();
        CubeComp.CaptureImage(FilePath, FileName, CameraSelect);
        while (!CubeComp.CaptureDone())
        {
            yield return null;
        }
        StartCoroutine(SerializeCapture(c, CubeComp.ReturnCaptureBytes(), CubeComp.Width, CubeComp.Height));
    }

    IEnumerator SerializeCapture(ServerClient c, byte[] PixelData, int Width, int Length)
    {
        OutgoingData(c, PixelData);
        yield return null;
    }

    public void OpenWebSite()
    {
        Application.OpenURL("https://Matlab与Unity图像传输TCP资源-CSDN文库");
    }
}

public class ServerClient {

    public TcpClient tcp;
    public string clientName;
    public GameObject ClientObj;

    public ServerClient(TcpClient clientSocket, string Name) {
        clientName = Name;
        tcp = clientSocket;
    }
}

Matlab端实现代码

function image = ImageReadTCP_One(TCP_Handle,CameraSelect)
writeTCP(TCP_Handle,sprintf("Camera:%s,%s,%s",CameraSelect,'test','test'));
pause(0.054);

while(TCP_Handle.BytesAvailable == 0)    
end
data = read(TCP_Handle);
% pause(0.005);
while(TCP_Handle.BytesAvailable ~= 0)
    data1 = read(TCP_Handle);
    data = [data,data1];
%    pause(0.005);
end
fid = fopen('image.png','w');
fwrite(fid,data,'uint8');
fclose(fid);
image = imread('image.png');
% Part 1 - display Image
clc;
clear all;
name = "Matlab";
Client = TCPInit('127.0.0.1',55001,name);
test = ImageReadTCP_One(Client,'Center');
imshow(test);
disp("Program done");

%% Part 2 - display Image and move Camera
clc;
clear all;
name = "Matlab";
Client = TCPInit('127.0.0.1',55001,name);

for move = 0 : 0.2 : 2
    func_move_cam(Client,move);
    test = ImageReadTCP_One(Client,'Center');
    imshow(test);
end

disp("Program done");

%% Part 3 - display Image, move Camera and hide Object for specific region
clc;
clear all;
name = "Matlab";
Client = TCPInit('127.0.0.1',55001,name);

for move = 0 : 0.2 : 2
    func_move_cam(Client,move);

    if move > 0.6 && move < 1.2
        act_obj = 0;
        func_activate_obj(Client,act_obj);
    else
        act_obj = 1;
        func_activate_obj(Client,act_obj);
    end   

    test = ImageReadTCP_One(Client,'Center');
    imshow(test);
end

disp("Program done");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值