0

我正在尝试为 Bonsai 框架开发一个模块,它通过 tcp 流连接通过它自己的名为 jit.net.send 和 jit.net.recv 的 TCP 通信协议/标准/模块将 OpenCV.NET IplImage 的流发送到 Max 6.1

cycling74.com/sdk/MaxSDK-6.1.3/html/chapter_jit_networking.html 上有一些关于 jit.net.send 和 jit.net.recv 的文档

在 C++ 上完成了一些类似的工作,将纹理从 OpenFrameworks 发送到 github.com/bakercp/ofxJitterNetworkSender 上的 Max

还有一些 5 年前的 C# 代码在 disis.music.vt.edu/main/portfolio.php 上将纹理从 Max 发送到 Unity3D

我所追求的是从 C# 应用程序(在 Bonsai 框架的模块下)向 Max 发送视频流(OpenCV.NET IplImage 的)。

我当前的源代码位于https://bitbucket.org/artica/bonsai-with-jitnetsend

我设法移植了 C++ 代码并找出了大端问题(使用来自另一个 stackoverflow 线程的一些代码)。现在,当我运行应用程序时,Max 标记它已连接,并且在应用程序端,调试时,所有内容都在发送。但是没有显示数据矩阵图像。

编辑-设法取得了一些进展,在 2 台机器之间发送了一些测试 jit.net.send 数据包,并捕获了数据包以使用 Wireshark 进行分析。以下是我的分析摘要:

https://bitbucket.org/artica/bonsai-with-jitnetsend/wiki/Example%204x4

我重写了代码以匹配实际的数据包示例并设法发送 4x4 图像,但图像在 8x8 上出现故障并开始以更高分辨率抛出错误。我猜此时这是一个 IplImage 格式问题。以下是相关代码:

    private string JIT_MATRIX_PACKET_ID           = "JMTX";
    public unsafe struct t_jit_net_packet_matrix {
        public Int32  id;
        public Int32  size;
        public Int32  planecount;
        public Int32  type;         //0=char,1=long,2=float32,3=float64
        public Int32  dimcount;
        //public fixed Int32 dim[32];
        //public fixed Int32 dimstride[32];
        //public Int32  datasize;
        //public double time; //64 bit double precision float
    }
    private t_jit_net_packet_matrix m_matrixHeader;

    private void sendFrame(IplImage input) {

        // setup matrix

        Int32 matrix_id = BitConverter.ToInt32(Encoding.ASCII.GetBytes(JIT_MATRIX_PACKET_ID), 0);

        Int32 planecount = input.NumChannels;
        Int32 typeSize = input.Depth;
        Int32 type = JIT_MATRIX_TYPE_CHAR;
        Int32 width = 16;// input.Width;
        Int32 height = 16;// input.Height;

        m_matrixHeader.id = matrix_id;
        m_matrixHeader.size = 288;
        m_matrixHeader.planecount = planecount;
        m_matrixHeader.type = type;
        m_matrixHeader.dimcount = 2;

        Int32[] dim = new Int32[32];    
        dim[0] = width;
        dim[1] = height;
        int i2 = 2;
        while (i2 < JIT_MATRIX_MAX_DIMCOUNT)
        {
            dim[i2] = 1;
            i2++;
        }

        Int32[] dimstride = new Int32[32];
        dimstride[0] = planecount;
        dimstride[1] = width * height;
        i2 = 2;
        while (i2 < JIT_MATRIX_MAX_DIMCOUNT)
        {
            dimstride[i2] = 0;
            i2++;
        }

        Int32 datasize = planecount * width * height;


        m_chunkHeader.id = BitConverter.ToInt32(Encoding.ASCII.GetBytes(JIT_MATRIX_PACKET_ID), 0);
        m_chunkHeader.size = sizeof(Int32) * (6 + 32 + 32) + sizeof(double); //should be 288 bytes
        byte[] chunkHeader = StructToBytes(m_chunkHeader, Endianness.LittleEndian);
        //Console.WriteLine(BitConverter.ToString(chunkHeader));

        byte[] matrixHeader = StructToBytes(m_matrixHeader, Endianness.BigEndian);
        //Console.WriteLine(BitConverter.ToString(matrixHeader));

        byte[] dim_send = new byte[4 * 32];
        byte[] dimstride_send = new byte[4 * 32];
        for (int i = 0; i < 32; i++)
        {
            byte[] dimbytes = BitConverter.GetBytes(dim[i]);
            Array.Reverse(dimbytes);
            System.Buffer.BlockCopy(dimbytes, 0, dim_send, i * 4, dimbytes.Length);

            byte[] dimstridebytes = BitConverter.GetBytes(dimstride[i]);                
            Array.Reverse(dimstridebytes);
            System.Buffer.BlockCopy(dimstridebytes, 0, dimstride_send, i * 4, dimstridebytes.Length);
        }
        //Console.WriteLine(BitConverter.ToString(dim_send));
        //Console.WriteLine(BitConverter.ToString(dimstride_send));

        byte[] datasize_send = BitConverter.GetBytes(datasize);
        Array.Reverse(datasize_send);
        //Console.WriteLine(BitConverter.ToString(datasize_send));

        double time = 0; //todo: should be elapsed time, not 0
        byte[] time_send = BitConverter.GetBytes(time);
        Array.Reverse(time_send);
        //Console.WriteLine(BitConverter.ToString(time_send));

        int size = width * height * 4 * 2;//input.Height * input.Width * input.NumChannels * input.Depth / 4;
        byte[] managedArray = new byte[size];
        Marshal.Copy(input.ImageData, managedArray, 0, size);
        Array.Reverse(managedArray);

        //Console.WriteLine(BitConverter.ToString(managedArray));


        byte[] output = new byte[chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length + time_send.Length + managedArray.Length];

        // chunkheader
        System.Buffer.BlockCopy(chunkHeader, 0, output, 0, chunkHeader.Length);
        // matrixheader
        System.Buffer.BlockCopy(matrixHeader, 0, output, chunkHeader.Length, matrixHeader.Length);
        // dim
        System.Buffer.BlockCopy(dim_send, 0, output, chunkHeader.Length + matrixHeader.Length, dim_send.Length);
        // dimstride
        System.Buffer.BlockCopy(dimstride_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length, dimstride_send.Length);
        // datasize
        System.Buffer.BlockCopy(datasize_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length, datasize_send.Length);
        // time
        System.Buffer.BlockCopy(time_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length, time_send.Length);
        // matrix array
        System.Buffer.BlockCopy(managedArray, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length + time_send.Length, managedArray.Length);

        Console.WriteLine(BitConverter.ToString(output));

        if (myClient.Connected)
            myStream.Write(output, 0, output.Length);


        Console.WriteLine("looping");
        //if (myClient.Connected)
        //    myStream.Write(managedArray, 0, managedArray.Length);

        //Console.WriteLine(managedArray.ToString());

    }
4

2 回答 2

0

设法自己弄清楚。

     private void sendFrame(IplImage input) {

        try
        {
            // setup matrix

            Int32 matrix_id = BitConverter.ToInt32(Encoding.ASCII.GetBytes(JIT_MATRIX_PACKET_ID), 0);

            Int32 planecount = input.NumChannels;
            Int32 typeSize = input.Depth;
            Int32 type = JIT_MATRIX_TYPE_CHAR;
            Int32 width = input.Width;
            Int32 height = input.Height;

            m_matrixHeader.id = matrix_id;
            m_matrixHeader.size = 288;
            m_matrixHeader.planecount = planecount;
            m_matrixHeader.type = type;
            m_matrixHeader.dimcount = 2;

            Int32[] dim = new Int32[32];
            dim[0] = width;
            dim[1] = height;
            int i2 = 2;
            while (i2 < JIT_MATRIX_MAX_DIMCOUNT)
            {
                dim[i2] = 1;
                i2++;
            }

            Int32[] dimstride = new Int32[32];
            dimstride[0] = planecount;
            dimstride[1] = width * planecount;
            i2 = 2;
            while (i2 < JIT_MATRIX_MAX_DIMCOUNT)
            {
                dimstride[i2] = 0;
                i2++;
            }

            Int32 datasize = planecount * width * height;

            m_chunkHeader.id = BitConverter.ToInt32(Encoding.ASCII.GetBytes(JIT_MATRIX_PACKET_ID), 0);
            m_chunkHeader.size = sizeof(Int32) * (6 + 32 + 32) + sizeof(double); //should be 288 bytes
            byte[] chunkHeader = StructToBytes(m_chunkHeader, Endianness.LittleEndian);
            //Console.WriteLine(BitConverter.ToString(chunkHeader));

            byte[] matrixHeader = StructToBytes(m_matrixHeader, Endianness.BigEndian);
            //Console.WriteLine(BitConverter.ToString(matrixHeader));

            byte[] dim_send = new byte[4 * 32];
            byte[] dimstride_send = new byte[4 * 32];
            for (int i = 0; i < 32; i++)
            {
                byte[] dimbytes = BitConverter.GetBytes(dim[i]);
                Array.Reverse(dimbytes);
                System.Buffer.BlockCopy(dimbytes, 0, dim_send, i * 4, dimbytes.Length);

                byte[] dimstridebytes = BitConverter.GetBytes(dimstride[i]);
                Array.Reverse(dimstridebytes);
                System.Buffer.BlockCopy(dimstridebytes, 0, dimstride_send, i * 4, dimstridebytes.Length);
            }
            //Console.WriteLine(BitConverter.ToString(dim_send));
            //Console.WriteLine(BitConverter.ToString(dimstride_send));

            byte[] datasize_send = BitConverter.GetBytes(datasize);
            Array.Reverse(datasize_send);
            //Console.WriteLine(BitConverter.ToString(datasize_send));

            double time = 0; //todo: should be elapsed time, not 0
            byte[] time_send = BitConverter.GetBytes(time);
            Array.Reverse(time_send);
            //Console.WriteLine(BitConverter.ToString(time_send));

            int size = width * height * 4;//input.Height * input.Width * input.NumChannels * input.Depth / 4;
            byte[] managedArray = new byte[size];
            Marshal.Copy(input.ImageData, managedArray, 0, size);
            Array.Reverse(managedArray);


            byte[] output = new byte[chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length + time_send.Length + managedArray.Length];

            // chunkheader
            System.Buffer.BlockCopy(chunkHeader, 0, output, 0, chunkHeader.Length);
            // matrixheader
            System.Buffer.BlockCopy(matrixHeader, 0, output, chunkHeader.Length, matrixHeader.Length);
            // dim
            System.Buffer.BlockCopy(dim_send, 0, output, chunkHeader.Length + matrixHeader.Length, dim_send.Length);
            // dimstride
            System.Buffer.BlockCopy(dimstride_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length, dimstride_send.Length);
            // datasize
            System.Buffer.BlockCopy(datasize_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length, datasize_send.Length);
            // time
            System.Buffer.BlockCopy(time_send, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length, time_send.Length);
            // matrix array
            System.Buffer.BlockCopy(managedArray, 0, output, chunkHeader.Length + matrixHeader.Length + dim_send.Length + dimstride_send.Length + datasize_send.Length + time_send.Length, managedArray.Length);

            //Console.WriteLine(BitConverter.ToString(output));

            if (myClient.Connected)
                myStream.Write(output, 0, output.Length);

        } catch ( Exception e )
        {
            Console.WriteLine("Exception: " + e.InnerException.Message);
        }
    }
于 2013-10-01T20:51:57.877 回答
0

抖动外部代码在您的源代码中吗?我似乎找不到它。

于 2013-09-20T12:31:18.007 回答