最近会出关于“视频拼接”的系列文章,作者是我们公司音视频业务线研发负责人钱波,有近20年音视频研发经验,毕业于长安大学,硕士研究生,专业是交通工程-计算机网络,曾任职于东方网力,中国电信等公司,音视频产品研发带头人,截止目前在CSDN中有417多篇原创文章,文章涵盖音视频、3D、AI等方向,欢迎关注,也欢迎大家技术交流、咨询。
一、视频拼接产品概述
将多达8个视频拼接在一起,拼成上帝视角的大图,并且可以共享最终生成的画面。
三维方案
三维方案应该是最接近事实的方案,多个画面应该是在三个维度,x,y,z 上面进行缩放,平移,旋转,可以形成柱面立体的图像,而底座的平面不一定是平面,有可能是一个曲面。不过这个方案虽然好,难度却比较大, 自己做一个三维引擎?还是用Unity,UE等工具直接编辑?这个难度在于掌握Unity、UE 工具的人员一般不具备视频概念,因此我们做了一个三维工具,可以在三维中显示视频,也做了一些文本,天空盒等功能,思考到后面,有一个问题没有解决,就是三维合成二维图像的问题,多个视频在三维空间中不能直接拼接成二维的图像,压缩成jpeg,h264,h265等的流进行发送,存储是这个拼接工具的最直接的功能,三维非常直观,但是要达到这种地步还是要做大量的算法工作。
二、界面问题
界面是最大的问题,不像是一个服务器,本身是逻辑的组合,而界面比较麻烦的是:设计问题,如何做到设计比较符合常理?
首先我设计了一个基本的界面,如下图所示:
它是一个带有尺度刻度的界面,可以加载树来展示所有的实时摄像头,文件也可以。这个界面首先是利于观察,所有的画面展示出来,用于人眼可以看清楚所有的综合画面是什么样子的。
画面调整
每个小窗口画面都是必须能要改变大小的,意味着画面可以随时调整大小。
三、算法
涉及到的算法比较多、畸变矫正、恢复、裁切、透视变换、仿射变换、旋转等。
首先我考虑到的是画面调整完后,有可能需要恢复到原始状态,但是畸形矫正不用恢复,所以畸形矫正应该是一个选项,要么选取(勾上),要不未选(没有勾),很有可能有的画面不需要矫正。
透视变换和裁剪
裁剪是必然的,那么像透视变换和仿射变化,以及单应矩阵可能先做,透视变化和仿射变化我设计了一个界面去调整
首先要选择两个画面,进行算法,在这里插入图片描述
如透视变化,这时候画面会取到最后一帧,出现1,2,3,4 四个方块,调整方块的位置则可以改变矩阵,从而生成新画面,同时这个必须记录下来,确定以后以便于主界面在渲染的时候进行透视变换。
移动
移动和记录移动的像素,并进行记录。
如上图所示,由于摄像头的角度,偏移,高度都可能不尽相同,所以这个必须经过画面的裁剪移动来进行图片帧对齐。
除了窗口的拖动,单帧在窗口里是可以使用键盘移动的,使用键盘WASD来移动帧,符合很多人游戏的上手操作。不过这样留下了黑边,所以必须进行裁剪
裁剪
因此裁剪框也是一个刚需的功能。
透视变换
透视变换是一个最最核心的功能,代替那些orb,shft 特征变换
鱼眼矫正
上面的图片经过矫正以后,图像被拉直,同时,部分画面被切割掉了。
四、关于特征
特征抓取是网上最多的人写过很多文章,这一部分就是使用ORB 特征,和 SIFT 等特征抓取匹配,然后再拼接,生成单应矩阵,这种方案不可取,是最差的方案,因为在实际的项目中,你连特征都抓不到,根本自动化不了,所以尽早放弃这种想法,除了一种情况例外,硬件是自己做的,自己知道自己的单应矩阵。
五、真正可靠的做法
把多路摄像头接入画面,缩小,观察,进行矫正,缩放,变换,裁切,放大,记录,这就是商业上做的做法。
下图是拼接后的画面
数字放大技术
这个太重要了,就算使用gpu 速度也没有那么快,那么尽量使用小的图,然后放大,读者会说,那不是失真了么?不会,这要用上真正的数字放大技术。
下面是原图:模糊了
下面是原图的矫正:
下面左边是原图放大4倍,使用双线性差值,右边是数字放大技术4倍,就是这么的离谱,就是上面的小图放大的,出家人不打诳语。
六、架构设计
插件式编程
所有的算法编写成为插件。
gpu编程
使用glsl 和 cuda 两种语言。
放小接入,放大接出
这个步骤太重要了 ,一切为了速度。
硬件盒子
硬件分为两种,我们考虑了
1 瑞芯微国产硬件的布局
2 jetson nano
输出
1 输出为mp4文件
2 输出为内存共享,为了给AI 输出,将合成的图像给AI以后,本来的跨境追踪reid好做了很多,是不是?
3 输出为rtmp ,rtsp 服务
未来会进行代码上的讲解,敬请期待