【发布时间】:2018-10-07 07:48:29
【问题描述】:
在项目中,我通过 DllImports 使用 Unity3D 的 C# 脚本和 C++。我的目标是游戏场景有2个立方体(Cube & Cube2),其中一个立方体纹理通过我的笔记本电脑摄像头和Unity的webCamTexture.Play()显示实时视频,另一个立方体纹理显示通过外部C++函数ProcessImage()处理的视频。
代码上下文:
在 c++ 中,我定义了它
struct Color32
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
功能是
extern "C"
{
Color32* ProcessImage(Color32* raw, int width, int height);
}
...
Color32* ProcessImage(Color32* raw, int width, int height)
{
for(int i=0; i<width*height ;i++)
{
raw[i].r = raw[i].r-2;
raw[i].g = raw[i].g-2;
raw[i].b = raw[i].b-2;
raw[i].a = raw[i].a-2;
}
return raw;
}
C#:
声明和导入
public GameObject cube;
public GameObject cube2;
private Texture2D tx2D;
private WebCamTexture webCamTexture;
[DllImport("test22")] /*the name of Plugin is test22*/
private static extern Color32[] ProcessImage(Color32[] rawImg,
int width, int height);
获取相机情况并设置cube1、cube2纹理
void Start()
{
WebCamDevice[] wcd = WebCamTexture.devices;
if(wcd.Length==0)
{
print("Cannot find a camera");
Application.Quit();
}
else
{
webCamTexture = new WebCamTexture(wcd[0].name);
cube.GetComponent<Renderer>().material.mainTexture = webCamTexture;
tx2D = new Texture2D(webCamTexture.width, webCamTexture.height);
cube2.GetComponent<Renderer>().material.mainTexture = tx2D;
webCamTexture.Play();
}
}
通过DllImports 向外部C++ 函数发送数据,并使用Color32[] a 接收处理后的数据。最后,我使用 Unity 的 SetPixels32 设置 tx2D(Cube2) 纹理:
void Update()
{
Color32[] rawImg = webCamTexture.GetPixels32();
System.Array.Reverse(rawImg);
Debug.Log("Test1");
Color32[] a = ProcessImage(rawImg, webCamTexture.width, webCamTexture.height);
Debug.Log("Test2");
tx2D.SetPixels32(a);
tx2D.Apply();
}
结果:
结果只是立方体 1 的纹理显示了实时视频,而无法显示使用立方体 2 的纹理处理的数据。
错误:
SetPixels32 调用时数组中的像素数无效 UnityEngine.Texture2D:SetPixels32(Color32[]) 网络摄像头:Update() (在 资产/脚本/Webcam.cs:45)
我不明白为什么当我将数组 a 输入到 SetPixels32 时数组中的像素数无效
有什么想法吗?
更新(2018 年 10 月 10 日)
感谢@Programmer,现在它可以通过引脚内存工作。
顺便说一句,我找到了一些关于 Unity 引擎的小 problem。当 Unity Camera 在 0 到 1 秒之间运行时,webCamTexture.width 或 webCamTexture.height 总是返回 16x16 大小,甚至请求更大的图像,例如 1280x720,然后它会在 1 秒后返回正确的大小。 (Possibly several frames) 所以,我引用了这个 post 并延迟 2 秒以在 Update() 函数中运行 Process() 并在 Process() 函数中重置 Texture2D 大小。它会正常工作:
delaytime = 0;
void Update()
{
delaytime = delaytime + Time.deltaTime;
Debug.Log(webCamTexture.width);
Debug.Log(webCamTexture.height);
if (delaytime >= 2f)
Process();
}
unsafe void Process()
{
...
if ((Test.width != webCamTexture.width) || Test.height != webCamTexture.height)
{
Test = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.ARGB32, false, false);
cube2.GetComponent<Renderer>().material.mainTexture = Test;
Debug.Log("Fixed Texture dimension");
}
...
}
【问题讨论】:
-
你能分享你定义和初始化Texture2D tx2D变量的代码吗?
-
Texture2D tx2D 初始化 new Texture2D(webCamTexture.width, webCamTexture.height)
代码已经上传,您可以在本站观看[链接:@987654324 @ -
我遇到了同样的问题,你能分享一下你做了什么让它工作吗?我无法将处理后图像的 cv::Mat 数组从 c++ 移动到 C#