【UE Unreal Camera】【保姆级教程二】【包含源代码】手把手教你通过UE获取摄像头帧数据~
c6ebbaddb1aff.png)
概述
在UE 摄像头教程一中,我们已经通过Unreal自带的媒体播放器打开了摄像头,并且将摄像头的数据展示在了游戏画面中。当然这只是最基本的功能,一般情况下,我们需要对摄像头的画面数据进行处理,比如进行人脸的检测,或者在图像中绘制新内容,或者仅仅是保存图像数据,这时候应该怎么办呢?关于这一部分内容,网上资料其实挺少的,官方文档也没有具体的说明,不过不用担心,我已经帮你踩好坑了,跟着我一步步来就可以了~
方法介绍
首先梳理一下逻辑,我们是如何打开摄像头和预览画面的?
1. 为了打开相机,首先通过MediaPlayer(CameraMeidaPlayer)来打开相机,在创建MediaPlayer的时候系统会自动为它创建一个MediaTexture(CameraMeidaPlayer_Video)此时我们已经可以在UE 的编辑器中看到MediaPlayer和MediaTexture中已经展示出了摄像头的画面了。
2. 为了展示画面,我们在游戏关卡中拖了一个Plane(平面),然后将MediaTexture拖到Plane上,此时引擎又为我们创建了一个材质(CameraMediaPlayer_Video_Mat)。
这是我们上一节所作的工作。看一下我们的内容浏览器,现在我们有CameraMeidaPlayer,CameraMediaPlayer_Video_Mat,CameraMeidaPlayer_Video三个东西。
获取帧数据的核心也就是如何将CameraMediaPlayer_Video_Mat转化为帧数据,在C++代码中也就是包含图像信息的数组了。具体思想,就是通过渲染目标(RenderTarget2D)来将图像信息导出。
简单来讲,渲染目标(Render Target)就是一种可以在运行时写入的纹理。从引擎的角度讲,渲染目标会存储颜色、法线以及AO等信息。
具体步骤
1. 创建一个RenderTarget2D,这里将其命名为CameraRender2D。
2. 在蓝图界面中创建一个RenderTarget2D的变量,这里命名为RenderTarget,然后将它的默认值指向在内容管理器中的CameraRender2D.
3. 在蓝图界面中创建一个Material的变量,这里命名为CameraMaterial,然后将它的默认值指向在内容管理器中的CameraMdiaPlayer_Video_Mat.
4. 开始绘制蓝图了。图中的实例是以点击屏幕中的plane,每点一次,就会对RenderTarget2D进行绘制,绘制好以后,RenderTarget2D就保存好了图像信息,这个时候将它输入到ProcessData中,使用C++对图像数据进行处理,得到我们想要的结果后,就可以通过渲染目标释放掉资源。
在c++中,如何将Target2D转换为图像数据呢?通过如下代码,首先我们在上述步骤得到了Target2D,函数中作为参数rt输入。首先将rt转化成了Unreal中的数据格式 TArray 的数组,然后将这个数组转成更通用的c形式的unsigned char格式。也就是说,我们已经得到了图像的数据,将它保存在下图中unsinged char格式的指针中啦!注意图像数据格式是RGBA格式,从代码中不难看出。至于如何操纵这个图像数据,就请大家自由发挥啦~
bool ProcessData(UTextureRenderTarget2D* rt) {
//Get Imagedata in the format of TArray<FColor>
if (rt == nullptr) {
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 20.0f, FColor::Yellow, TEXT("UTextureRenderTarget2D == nullptr,exit"));
return false;
}
FTextureRenderTargetResource* rtResource = rt->GameThread_GetRenderTargetResource();
FReadSurfaceDataFlags readPixelFlags(RCM_UNorm);
readPixelFlags.SetLinearToGamma(true);
TArray<FColor> outBMP;
outBMP.AddUninitialized(rt->GetSurfaceWidth() * rt->GetSurfaceHeight());
rtResource->ReadPixels(outBMP, readPixelFlags);
for (FColor& color : outBMP)
color.A = 255;
//Convert the image data format from TArray to const char*(c style)
unsigned long dataSize = sizeof(unsigned char) * 4 * (rt->GetSurfaceWidth() * rt->GetSurfaceHeight());
unsigned char *imgData = (unsigned char *)malloc(dataSize);
memset(imgData, 0, dataSize);
int cusPos = 0;
for (FColor& color : outBMP) {
memcpy(imgData + cusPos, (unsigned char*)&color.R, 1);
cusPos += 1;
memcpy(imgData + cusPos, (unsigned char*)&color.G, 1);
cusPos += 1;
memcpy(imgData + cusPos, (unsigned char*)&color.B, 1);
cusPos += 1;
memcpy(imgData + cusPos, (unsigned char*)&color.A, 1);
cusPos += 1;
}
}
大家有做到这个步骤吗?如果你的RenderTarget已经有图像,就像我下图所示的一样,那么恭喜你,你已经正确的完成了以上步骤。
文章来源:https://www.toymoban.com/news/detail-429894.html
方法介绍
Demo工程说明
Demo工程包含以上所讲内容实例,进入工程以后,点击运行,就可以看到Windows电脑摄像头打开,并显示在游戏中。打包出来以后同样可以在Android手机上使用。(注意Mac电脑和iOS手机不可用)
关注公众号后发送:Unreal-Camera即可。
文章来源地址https://www.toymoban.com/news/detail-429894.html
到了这里,关于【UE Unreal Camera】【保姆级教程二】【包含源代码】手把手教你通过UE获取摄像头帧数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!