GPU上的硬件加速视频拼接

使用OpenCV进行拼接的效果非常好,但是如果想在只有普通OpenGL的GPU上的硬件中完成所有操作,该怎么办?

简介

OpenCV附带了一个高级示例,它可以在静态图像上产生出色的结果,但是在视频流的每一帧上使用此程序的 速度非常慢 。这是使用Raspberry Pi进行360°视频的解决方案。

本文沿用了上面提到的内容,并且使用OpenCV在CPU上转换了视频帧,介绍了完整的GPU流水线。

应该注意的是,OpenCV具有许多GPU在操作上的支持,但是启用它仍然会导致CPU和GPU之间来回数据复制效率低下。

为什么用OpenGL代替OpenCV?

为了实现低延迟和实时视频拼接,OpenCV 2D像素转换被微型OpenGL 3D引擎取代。

相比之下,OpenGL具有多个优点:

  • 相机ISP或硬件视频解码器可以将视频帧直接传递到GPU中的OpenGL纹理(避免通过CPU复制缓冲区)

  • GPU具有用于像素处理和纹理采样的特定硬件加速

  • 拼接的帧已经在GPU中,并且可以几乎无延迟地推动显示

  • OpenGL是一个开放标准,对大多数嵌入式目标都具有良好的支持

它也有缺点:

  • 将OpenGL帧缓冲区读回CPU内存的过程通常很慢且效率低下

  • OpenGL渲染功能(尤其是OpenGL ES)通常取决于所连接的屏幕(例如,渲染速度不能超过60fps)

  • OpenGL的API大而复杂

嵌入式视频拼接的体系结构


涉及CPU,视频硬件和GPU的拼接管线

-CPU从MJPEG(连接的JPEG文件)中读取流

-JPEG解析器在流中查找单个帧,并将它们与捕获时间戳做关联。

—JPEG硬件解码器将位图帧生成到OpenGL纹理缓冲区。

-GPU对每个纹理进行采样以应用2D透视变换(使用像素着色器)

-GPU输出帧缓冲区由JPEG编码硬件回读

-CPU获取回调并将JPEG缓冲区附加到输出文件

介绍Inatech的开源拼接器

inastitch 是一个开源项目,旨在实现以下拼接流程:

inastitch/inastitch
Inatech stitcher. Contribute to inastitch/inastitch development by creating an account on GitHub.
github.com

注意:在撰写本文时,尚未实现JPEG硬件解码,并且在CPU上使用 libturbojpeg 进行了解码/编码(由于CPU向量化,速度仍然相当快)。

inastitch 内部

inastitch 将一组视频流以及帧时间戳以及每个流的2D转换矩阵作为输入。

同步的视频流和时间戳由改良的Raspberry Pi摄像头工具- raspivid-inatech 生成。

标定工具

转换矩阵由使用OpenCV库的校准工具生成: inastitch_cal

https://github.com/inastitch/inastitch/tree/master/tools/calibration

校准阶段的目的是找到 单应 矩阵

单应性矩阵是第二台摄像机视点的变换,使其看起来像第一台摄像机的视点。

请在OpenCV单应性教程中参阅“ 什么是单应矩阵? ”。

注意:在校准工具中, 左图像 保留作为参考视点(第一个摄像机),而变换矩阵应用于 右图像 (第二个摄像机)。

OpenGL渲染场景的描述

每个视频帧都变成了一个纹理,然后绑定到两个三角形的扁平矩形,以并排呈现每个匹配的帧。

透视2D的转换通过非常简单的像素着色器应用于纹理:

varying vec2 texCoordVar;
uniform sampler2D texture1;
uniform mat3 warp;

void main() {
   vec3 dst = warp * vec3((texCoordVar.x+1.0), texCoordVar.y, 1.0f);
   gl_FragColor = texture2D(texture1, vec2((dst.x/dst.z), (dst.y/dst.z)) );
}

warp 是OpenCV的单应性矩阵,已归为OpenGL坐标。

现在是演示时间!

以下是演示以 100fps 记录的三个同步流拼接的演示。

https://youtu.be/o4ChnfXTKjU
首次 试驾的视频网址

具有内部视图的同一视频:
https://youtu.be/FXiMbfj9BX8

同一视频的一部分以25fps(而不是100fps)(即4倍慢动作)播放:
https://youtu.be/635VaCyS0GQ

注意:Youtube将原始视频缩小到60fps。

结论

对于拼接静止图像,OpenCV很棒且可自定义,但不适用于整个管道需要硬件加速的视频处理。

OpenGL ES中的微型3D引擎在这里是更好的选择,它对从嵌入式SoC到数据中心GPU的硬件加速提供了标准化支持。

当然,Vulkan会比OpenGL更好,但要以与更少GPU硬件兼容的成本为代价。

下一步

下一步是使用相同的GPU管线 进行实时 拼接。

这里的主要挑战是将通过Ethernet使用实时视频流。同步视频帧需要一起传递并具有一致的延迟,以避免在网络的订书机侧进行缓冲。普通Ethernet网络不支持这种用例。

时间感应网络 (TSN)是对Ethernet的补充,旨在解决对时间感应的数据包传递问题。

继续下一步

使用3D转换而不是2D

你可能已经注意到, Inastitch 使用像素着色器在纹理中进行2D透视变换,而不是使用顶点着色器进行3D渲染以产生相同的透视,这将更好/更简单地使用GPU硬件。

一个主意是将单应性矩阵分解为更简单的3D旋转和平移,然后可以将其应用于视频矩形的顶点。

请参见OpenCV单应性教程中的演示4:分解单应性矩阵 ”和该功能。

拼接效果更好

前一篇文章中详细解释的那样,由于相机变换 不是 纯旋转,因此拼接不能完美。使用Alpha通道和视频纹理的网格,可以在OpenGL中有效地进行接缝融合和遮罩。

制作适合汽车使用的原型

inastitch 可以使用一个很好的后视镜,不是吗?

这里有一些建议:

关于下一个友好型汽车原型
想让原型与汽车更加兼容吗?请点击这里
medium.com


当心那只狗!

原文作者 Vincent Jordan
原文链接 https://levelup.gitconnected.com/faster-video-stitching-with-opengl-9e9132c72def

推荐阅读
作者信息
AgoraTechnicalTeam
TA 暂未填写个人简介
文章
120
相关专栏
本专栏仅用于分享音视频相关的技术文章,与其他开发者和 Agora 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。