优秀网页翻译:Raspberry Pi + OpenCV 进行 360° 街景拼接
2022/3/21 1:28:27
本文主要是介绍优秀网页翻译:Raspberry Pi + OpenCV 进行 360° 街景拼接,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
优秀网页翻译:Raspberry Pi + OpenCV 进行 360° 街景拼接
- 图像拼接
- 缝合,最简单的方法
- 旋转 vs 平移
- 相机硬件
- 相机同步
- 拼接流水线
- 360度视频,终于诞生啦
- 注释
- 结论
- 源代码
- 参考
- 走得更远
- 更好的接缝
- 更好的同步
原文链接:
https://medium.com/@vejipe/360-video-stitching-with-raspberry-pi-and-opencv-30549b37acbc
制作自己的 360 度视频片段需要什么? 答案是:一堆相机和一些开源软件。 我们试试吧…
首先我们需要谈谈图像拼接。毫不奇怪,OpenCV 有一个很好的示例实现,并且经常提供令人印象深刻的无缝结果。问题是我们想要制作视频,而不是静态图像,所以接下来我们需要讨论 Raspberry Pi 上的相机同步,以便同时捕获帧。最后,我们如何用所有这些制作 360 度视频?
图像拼接
拼接是以无缝方式合并多个重叠图像的过程,使其看起来像一个单一的图像。
缝合,最简单的方法
第 1 步:
拍照,转动相机,再拍一张。小心保持一些重叠。
第 2 步:
运行特征算法以找到每张图片的关键点。五颜六色的小圆圈是关键点。这里每张图片有2000多个。
第 3 步:
匹配相似的关键点。这里有580根火柴,大部分是在向日葵上。
第 4 步:
计算单应矩阵并扭曲一张图片以获取另一张图片的视角。这是从左图(1)的角度看的右图(2)。
步骤 5:
并排显示图片。
旋转 vs 平移
需要知道的重要一点:如果相机只是旋转而从不平移,那么在任何距离上拼接都会很好,例如,将相机放在三脚架上拍摄静态图像,如上一节中的向日葵示例。
当相机被平移时,问题就开始了。在这种情况下,缝合只会在给定的距离上是最好的。由于多个记录摄像机不能物理上位于同一点,因此摄像机平移是不可避免的。
请参见下面的示例。如果我们尝试将山峰与花顶对齐,则相机的任何平移移动背景和不同的图片都不会像纯旋转那样重叠。
上图:花山与旋转的相机
幸运的是,OpenCV 的示例拼接实现已经附带了一个缓解方法:使用 GraphCut 的接缝蒙版。该算法最初旨在创建无缝纹理。当它穿过对比线时,错位是非常明显的。 GraphCut 将尝试将其最小化。
上图:3 帧之间的两个 GraphCut
例如,在这个例子中,GraphCut 避免了在蓝天上对比强烈的屋顶(右侧)的切割。同样在左侧,切口偏向于树木中较暗的区域,在该区域不对齐不太明显。
相机硬件
上图:来自 Inatech 的一个秘密地点
一些规格:RPi 相机 v2 的水平视野为 62 度。我们使用 8 个摄像头进行 360° 视图。每个 Raspberry Pi 都在硬件中以 H264 编码视频流并将其存储在其 SD 卡上。在录制会话结束时,所有八个流都被收集并在另一台计算机上处理。 Raspberry Pi 可以使用完整的传感器以最高 42fps 的速度进行捕获和编码。请参阅 RPi 相机模块文档。
上图(视频地址):树莓派“相机轮子”
为了携带相机轮子,它被安装在自行车车上,连同电池和逆变器一起供电。是的,紧凑性显然不是这里的优先事项……
上图:树莓派视频拼接车
相机同步
为了在移动时进行拼接,所有八个摄像机都需要同时捕捉一帧。它们不能在独立的时钟上运行。在 40fps 时,帧时间为 25ms(两个连续帧之间的时间)。在最坏的情况下,帧捕获时间会相差 12.5 毫秒,即使在低速拼接后,视频中也会出现延迟。
我修改了相机工具 raspivid,在视频帧 CPU 回调中添加了一个软件 PLL。 “锁相环”(又名 PLL)将两个循环事件(即时钟)同步在一起。
软件 PLL 在运行时更改相机帧速率,以在 Linux 系统时钟上对齐帧捕获时间。
所有八个系统时钟都使用 PTP(代表精确时间协议)通过以太网同步。即使 Raspberry Pi 以太网缺少用于高精度 PTP 时钟(硬件时间戳)的专用硬件,它仍然经常在软件模式下使用 PTP 实现低于 1ms 的时钟同步。录制视频时,网络仅用于 PTP,不进行其他通信。
拼接流水线
Step1:
录制视频
打开电源,让 PTP 稳定(可能需要几分钟),开始在每个 Raspberry Pi 上录制。
Step2:
对齐框架
复制视频流,将视频拆分为单个 JPEG 文件以及文本文件中的捕获时间信息(即,修改后的 raspivid PTS 文件)。
找到匹配的帧。
Step3:
校准转换
在一些匹配的帧上运行 OpenCVstitching_detailed 以找到转换矩阵。根据特征算法(例如,SURF、ORB、……)和帧重叠区域中可见的细节,匹配是否成功。
在成功的情况下,每一帧都有两个矩阵:编码相机特征(例如焦距、纵横比)的相机矩阵(又名“K”)和编码相机旋转的旋转矩阵(又名“R”)。
正如本文开头所解释的,拼接将假定为纯旋转,而现实生活中并非如此。流的每个匹配帧将具有不同的矩阵。下一步只选择一组矩阵。
Step4:
拼接框架
使用上一步中选择的矩阵作为硬编码变换重建stitching_detailed,并拼接所有视频帧。
Step5:
编码视频
将所有拼接的 JPEG 文件再次组合成一个视频,并将其编码回 H264。
360度视频,终于诞生啦
上图(视频地址)
结果是非常宽的视频流。请注意,不同步的帧将替换为纯白色,而不是显示延迟的帧。
如果此视频太宽而无法在您的屏幕上显示,这里是一个狭缝版本:
上图(视频地址)
注释
这里介绍的视频的一个很大限制是拼接在每一帧上独立运行,而不考虑前一帧:
GraphCut 算法每次都会选择不同的路径,视频看起来会出现故障。 矩阵校准对所有帧只进行一次。
结论
在拼接和时钟同步方面有了些许改进,加上 GPS 接收器,Raspberry Pi 街景指日可待……
在新文章中查看有关街景理念的进一步发展:
制作您自己的 Google 街景的想法,扫描街道可能不需要昂贵的设置
源代码
由 Inatech 修改的 raspivid:
https://github.com/inastitch/raspivid-inatech
查看预编译二进制 raspivid-inatech 的发布部分。
参考
Vivek Kwatra、Arno Schödl、Irfan Essa、Greg Turk 和 Aaron Bobick。 Graphcut 纹理:使用图形切割的图像和视频合成。在 ACM Transactions on Graphics (ToG),第 22 卷,第 277-286 页。 ACM,2003。[https://dl.acm.org/doi/10.1145/882262.882264](https://dl.acm.org/doi/10.1145/882262.882264)
OpenCV的stitching_detailed,源码:https://github.com/opencv/opencv/blob/master/samples/cpp/stitching_detailed.cpp
原始树莓派 raspivid,源代码:https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/raspicam/RaspiVid.c
走得更远
更好的接缝
为了解决 GraphCut 接缝看起来有问题的问题,下面的论文提出了一种有前途的时空内容保留扭曲算法:
[https://www.cv-foundation.org/openaccess/content_cvpr_workshops_2015/W10/papers/Jiang_Video_Stitching_With_2015_CVPR_paper.pdf](https://www.cv-foundation.org/openaccess/content_cvpr_workshops_2015/W10/papers/Jiang_Video_Stitching_With_2015_CVPR_paper.pdf)
更好的同步
要解决 PTP 时钟同步问题,请在另一篇文章中查看更深入的分析:
https://vejipe.medium.com/sync-your-clocks-better-ptp-settings-on-raspberry-pi-37a9a54e4802
(译者注:这篇文章的翻译:查看文章)
这篇关于优秀网页翻译:Raspberry Pi + OpenCV 进行 360° 街景拼接的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享