虚幻UE4中如何采集360度全景图片和VR视频 Posted 2020-09-01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚幻UE4中如何采集360度全景图片和VR视频相关的知识,希望对你有一定的参考价值。
如何使用虚幻 4来制作一个VR 视频播放器呢,简单来讲,使用虚幻4的视频采集插件来获取图像,并对图像进行处理,就能获取我们需要的图像了,下一步,你可以把图像投影到一个360度球体上,就能形成球形的播放器了。
1.插件测试—采集单帧双眼图像
打开Epic Games Launcher,启动引擎 (我使用的版本为4.14.0)。在弹出的对话框中点击New Project标签栏,再选择C++标签页,选择Vehicle Advanced模板,并将项目命名为STEREOSCOPIC。最后点击CreateProject。
在打开的编辑器菜单栏依次点击Edit→Plugins,然后选择左侧的Movie Capture,在右侧Stereo Panoramic Movie Capture条目中勾选Enabled。然后重启编辑器。 当编辑器重启后,再次点击Edit→Plugins→Movie Capture,再次检查Stereo Panoramic Movie Capture是否已启用。 在工具栏,依次点击Blueprints→OpenLevelBlueprint。在Event BeginPlay事件后,新建两个(具体依据需求而定)Execute Console Command节点保存我们需要执行的命令。 这里先进行采集测试 ,将下面这两条命令分别放入Execute Console Command节点中:
[代码]:
1
<font size=
"3"
>SP.OutputDir D:/StereoCaptureFrames
3
SP.PanoramicScreenshot</font>
如下图所示:
然后就可以点击工具栏的Play按钮了。此时系统可能会长时间没有响应(一分钟左右),然后将会有两帧图像存储到先前用SP.OutputDir指定的目录中(实际是在改目录中的一个日期与时间目录下,点击一次Play生成一个),一个是左眼图像,一个是右眼图像。
2.在项目中集成插件
首先将引擎中的全景采集插件(Stereo Panomic Movie Capture)备份,再将整个插件目录剪切(注意是剪切,而不是复制)出来,一是供我们修改,二是防止和我们自己编译有冲突。Unreal引擎中的插件在路径\Epic Games\4.14\Engine\Plugins下,在这里我们需要将其中的StereoPanorama(\Plugins\Experimental\StereoPanorama)剪切出来。 然后打开Stereo项目文件夹,在文件夹根目录下新建一个Plugins文件夹,将上一步剪切的StereoPanorama文件夹粘贴到这里。目录结构示例如下(限于篇幅这里只列出了必要的文件):
打开项目的场景编辑器,依次点击Editor→Plugins→Project→MovieCaputure,启用Stereo Panoramic Movie Caputure,然后重启项目。再次检查Stereo Panoramic Movie Capture是否被启用。 项目编辑器中,依次点击File→OpenVisualStudio,在VS工程中,依次点击Solution→Games→STEREOSCOPIC→Config,打开DefaultEngine.ini文件,在该文件末尾添加如下文字。
[代码]:
1
<font size=
"3"
>[Plugins]
2
+EnabledPlugins=StereoPanorama</font>
如下所示(截图是添加插件后的工程,默认没有Plugins):
为了强制打包项目的时候插件能够和项目相连,在VS工程中,依次点击Solution→Games→STEREOSCOPIC→Source→STEREOSCOPIC→STEREOSCOPIC.Build.cs文件中添加模块依赖项。
[代码]:
1
<font size=
"3"
> PrivateDependencyModuleNames.AddRange(
new
string
[] {
"StereoPanorama"
});</font>
如下所示:
关闭Visual Studio和ue4 编辑器,并重启。重启之后可以发现VS工程中已经添加了Plugins文件夹和StereoPanorama插件。
3将左右眼图像自动组合成单一图像
在VS工程中,依次打开Solution→Games→STEREOSCOPIC→Plugins→StereoPahorama→Source→StereoPahorama\Private,打开文件SceneCapture.cpp文件。全部修改工作均在次完成。
为了使我们能够方便地控制合成的开关,我们需要定义一个bool常量在文件的头部,这样,在我们不需要开启合并的时候修改该常量的值即可,不必再修改其余的代码。
[代码]:
2
const
bool
CombineAtlasesOnOutput =
true
;</font>
现在我们需要在代码中有条件地禁用每只眼睛的输出(通过上面定义的CombineAtlasesOnOutput来控制)。然后找到USceneCapturer::SaveAtlas()的底部,找到这样一段代码:
[代码]:
1
<font size=
"3"
>IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG );
2
ImageWrapper->SetRaw(SphericalAtlas.GetData(), SphericalAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight, ERGBFormat::BGRA, 8);
3
const
T<a href=
"http://www.52vr.com/armr/"
style=
"font-weight: bold;color: ;"
target=
"_blank"
>AR</a>ray<uint8>& PNGData = ImageWrapper->GetCompressed(100);
4
FFileHelper::SaveArrayToFile( PNGData, *AtlasName );</uint8></font>
这几行代码就是控制左右眼输出的,如果我们定义的CombineAtlasesOnOutput为true,就意味这我们需要合并两张眼睛的图像,那么我们就需要禁掉它(左右单独输出),如果为false则我们需要输出左右眼的单独序列帧,所以就需要执行它。
综上,可以写一个if语句来判断CombineAtlasesOnOutput的值:
[代码]:
1
<font size=
"3"
>IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG );
2
if
(!CombineAtlasesOnOutput)
4
ImageWrapper->SetRaw(SphericalAtlas.GetData(), SphericalAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight, ERGBFormat::BGRA, 8);
5
const
TArray<uint8>& PNGData = ImageWrapper->GetCompressed(100);
6
FFileHelper::SaveArrayToFile(PNGData, *AtlasName);
这样会导致一个错误,因为PNGData是在if的作用域内定义的,如果执行到了if后(被释放掉)或者根本没有执行到(if判断为false(!true))就会导致后面对PNGData的使用造成错误。
在上面if语句之后的代码块中对PNGData的使用处为:
[代码]:
01
<font size=
"3"
>
if
(FStereoPanoramaManager::GenerateDebugImages->GetInt() != 0)
03
FString FrameStringUnprojected = FString::Printf(TEXT(
"%s_%05d_Unprojected.png"
), *Folder, CurrentFrameCount);
04
FString AtlasNameUnprojected = OutputDir / Timestamp / FrameStringUnprojected;
06
ImageWrapper->SetRaw(SurfaceData.GetData(), SurfaceData.GetAllocatedSize(), UnprojectedAtlasWidth, UnprojectedAtlasHeight, ERGBFormat::BGRA, 8);
07
const
TArray<uint8>& PNGDataUnprojected = ImageWrapper->GetCompressed(100);
09
FFileHelper::SaveArrayToFile(PNGDataUnprojected, *AtlasNameUnprojected);
对禁用左右眼单帧输出部分,如果只写这部分代码,现在再执行采集是不会有任何有意义图像输出的(因为现在已经把左右眼输出禁用了)。下面继续搞将两张合并到一块的方法。
查找代码:
[代码]:
1
<font size=
"3"
>TArray<fcolor> SphericalLeftEyeAtlas = SaveAtlas( TEXT(
"Left"
), UnprojectedLeftEyeAtlas );
2
TArray<fcolor> SphericalRightEyeAtlas = SaveAtlas(TEXT(
"Right"
), UnprojectedRightEyeAtlas);</fcolor></fcolor></font>
在其后添加:
[代码]:
02
if
(CombineAtlasesOnOutput)
04
TArray<fcolor> CombinedAtlas;
05
CombinedAtlas.Append(SphericalLeftEyeAtlas);
06
CombinedAtlas.Append(SphericalRightEyeAtlas);
07
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
08
ImageWrapper->SetRaw(CombinedAtlas.GetData(), CombinedAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight * 2, ERGBFormat::BGRA, 8);
09
const
TArray<uint8>& PNGData = ImageWrapper->GetCompressed(100);
11
FString FrameString = FString::Printf(TEXT(
"Frame_%05d.jpg"
), CurrentFrameCount);
12
FString AtlasName = OutputDir / Timestamp / FrameString;
13
FFileHelper::SaveArrayToFile(PNGData, *AtlasName);
此时在VS工程中编译项工程STEREOSCOPIC,并重启UE4编辑器和VS,就会采集并将左右眼合并成一张图片了。
以上是关于虚幻UE4中如何采集360度全景图片和VR视频的主要内容,如果未能解决你的问题,请参考以下文章
北京VR视频外包团队:全景VR视频科普
VR全景智慧城市:360全景市场需要背景及其优势~
全景智慧城市VR全景行业佼佼者,VR全景
360度全景效果图,如何制作?
腾讯云推4K全景实验室:视频用户可获360度观看视角
360度全景视频后视镜