我在Pixel 3上使用ARcore Unity SDK。 我需要在运行时读取相机的当前帧,并使其成为可以在ma场景上使用的纹理。
我在文档中看到有不同的方式(Frame.CameraImage.Texture,Frame.CameraImage.AcquireCameraImageBytes(),TextureReaderApi),但是我找不到哪个折旧了。 我检查了GitHub问题并尝试了一些解决方案:
使用Frame.CameraImage.Texture:
MyObject.GetComponent<Renderer>().material.mainTexture = Frame.CameraImage.Texture
这可行,但是纹理每帧更新一次,所以我尝试了这个:
yield return new WaitForEndOfFrame();
Texture2D texture2D = (Texture2D)Frame.CameraImage.Texture;
var pix = texture2D.GetPixels32();
var destTex = new Texture2D(texture2D.width, texture2D.height);
destTex.SetPixels32(pix);
destTex.Apply();
MyObject.GetComponent<Renderer>().material.mainTexture = destTex;
此功能仅在即时预览模式下有效,而在我构建应用程序并在设备上运行时不起作用。 (我有白色的纹理)
我尝试了如下的TextureReaderAPI:
void Start()
{
textureReader.OnImageAvailableCallback += OnImageAvailable;
}
public void OnImageAvailable(TextureReaderApi.ImageFormatType format, int width, int height, IntPtr pixelBuffer, int bufferSize)
{
Texture2D TextureToRender = new Texture2D(width, height,
TextureFormat.RGBA32, false, false);
byte[] Texture_Raw = new byte[width * height * 4];
System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, Texture_Raw, 0,
bufferSize);
TextureToRender.LoadRawTextureData(Texture_Raw);
TextureToRender.Apply();
GetComponent<Renderer>().material.mainTexture = TextureToRender;
}
但是我遇到了这个错误:DllNotFoundException:arcore_camera_utility GoogleARCore.Examples.ComputerVision.TextureReaderApi.Create,因此永远不会触发回调函数。
我还尝试了AcquireCameraImageBytes函数,然后将结果从YUV转换为RGB:
private void Update()
{
using (var image = Frame.CameraImage.AcquireCameraImageBytes())
{
if (!image.IsAvailable)
{
return;
}
_OnImageAvailable(image.Width, image.Height, image.Y, 0);
}
}
private void _OnImageAvailable(int width, int height, IntPtr pixelBuffer,
int bufferSize)
{
Debug.Log("UPDATE_Image");
Texture2D m_TextureRender = new Texture2D(width, height, TextureFormat.RGBA32, false, false);
bufferSize = width * height * 3 / 2;
byte[] bufferYUV = new byte[bufferSize];
System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, bufferYUV, 0, bufferSize);
Color color = new Color();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
float Yvalue = bufferYUV[y * width + x];
float Uvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height)];
float Vvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height) + (width * height) / 4];
color.r = Yvalue + (float)(1.37705 * (Vvalue - 128.0f));
color.g = Yvalue - (float)(0.698001 * (Vvalue - 128.0f)) - (float)(0.337633 * (Uvalue - 128.0f));
color.b = Yvalue + (float)(1.732446 * (Uvalue - 128.0f));
color.r /= 255.0f;
color.g /= 255.0f;
color.b /= 255.0f;
if (color.r < 0.0f)
color.r = 0.0f;
if (color.g < 0.0f)
color.g = 0.0f;
if (color.b < 0.0f)
color.b = 0.0f;
if (color.r > 1.0f)
color.r = 1.0f;
if (color.g > 1.0f)
color.g = 1.0f;
if (color.b > 1.0f)
color.b = 1.0f;
color.a = 1.0f;
m_TextureRender.SetPixel(width - 1 - x, y, color);
}
}
m_TextureRender.Apply();
MyObject.GetComponent<Renderer>().material.mainTexture = m_TextureRender;
}
在即时预览中,我收到此错误:EntryPointNotFoundException:AImage_getPlaneData。
它几乎可以在构建中使用,但是我从YUV转换为RGB时出了点问题,我想是这样的图像:
我不知道怎么了。
我的解决方案用光了,不知道应该做什么,哪里不对。欢迎任何建议:)
预先感谢您的帮助。
答案 0 :(得分:0)
您要尝试的只是将相机的框架更改为纹理? 制作一个渲染纹理资产并将其放入所述相机的“目标纹理”中,如果您要制作一个小型地图系统(因为我猜这是最常见的用途),则可以将所述纹理输入到原始图像中,因为它们带有纹理