需要结合使用Unity3d和OpenCV (最好使用NumPy,因为函数也将从那里使用,这意味着也需要+Python )。其主要思想是将来自Unity的图像从Unity传递到OpenCV进行处理,然后将动作发送回Unity。
我尝试了许多变体,从RenderTexture (Unity)获取图片字节流,并将其发送到websockets上的python服务器。一切工作,传输速度是可以接受的,但在“摄影”的纹理,它需要大量的资源和统一的主线挂起…所以我得到了5fps,这是不好的。我想以正确的方式重写它:要么将openCV集成到unity中,要么从视频内存中提取纹理(但这是可怕的C++和openGL,我想要python,因为我需要numPy)。
我尝试了FMETP流(它没有启动前端,这意味着它可以工作,但图像不能在浏览器中显示),然后放入IronPython openCV并在C#中使用它们(我无法以任何方式安装opencv ),尝试放入C#的模块: OpenCVSharp (这个包似乎还可以),NumSharp (缺少一些在项目中使用的方法)和socket图像传输方法(工作,但非常长和滞后)。。。在每个变体中,几乎所有的东西都进行了彻底的尝试和研究。
实际上,我想请教一下,选择哪种集成更好,如何做得更好?
我用来向python服务器发送图像字节的代码:https://pastebin.com/pRyutRcj
    WebSocket ws;
    void Start () {
        ws = WebSocketFactory.CreateInstance("ws://localhost:12345");
        // ...
        // Connect to the server
        ws.Connect();
        InvokeRepeating("Capture", 1f, 0.2f);  //1s delay, repeat every 1s
    }
    public void Capture()
    {
        RenderTexture activeRenderTexture = RenderTexture.active;
        RenderTexture.active = Camera.targetTexture;
        Camera.Render();
        Texture2D image = new Texture2D(Camera.targetTexture.width, Camera.targetTexture.height);
        image.ReadPixels(new Rect(0, 0, Camera.targetTexture.width, Camera.targetTexture.height), 0, 0);
        image.Apply();
        RenderTexture.active = activeRenderTexture;
        byte[] bytes = image.EncodeToPNG();
        Destroy(image);
        ws.Send(bytes);
    }发布于 2021-03-30 14:54:14
你最初的解决方案是在unity上运行你的主线程中的所有东西。因此,它将像预期的那样滞后。如果你用PNG编码,数据量会很大。
在FMETP STREAM中,他们使用了多线程编码器,这至少可以解决你的性能问题。这就是为什么它可以在低端设备和VR耳机上流畅运行的原因。
输出的byte[]是jpeg的块,而不是一个图像。它是为UDP数据包大小限制而设计的。
如果你尝试自己解码FMETP STREAM的图像,你必须将这些byte[]组合成一个完整的jpeg,在C#中参考它们的解码器不会太困难。
PS:如需技术支持,请直接联系开发者。
https://stackoverflow.com/questions/66173069
复制相似问题