在StereoPi上探索OpenCV:视频深度图



今天,我们想为Raspberry Pi上的OpenCV学习者共享一系列Python示例,即双腔StereoPi板。 完成的代码(加上Raspbian图像)将帮助您完成所有步骤,从捕获图片开始到从捕获的视频获取深度图结束。

介绍性


我必须立即强调,这些示例仅是为了让您沉浸在该主题中,而不是用于生产解决方案。 如果您是OpenCV的高级用户,并且一直在处理树莓派,那么您应该知道,对于成熟的工作,建议一口气编写代码,甚至使用树莓派GPU。 在本文的结尾,我将详细介绍python解决方案的“瓶颈”和整体性能。

我们在做什么


我们有铁这样的设置:



Raspberry Pi计算模块3+上的StereoPi板。 为Raspberry Pi版本V1(在ov5647传感器上)连接了两个最简单的相机。

安装了什么:

  • Raspbian Stretch(内核4.14.98-v7 +)
  • 的Python 3.5.3
  • OpenCV 3.4.4(预编译,来自Python Wheels的“ pip”)
  • Picamera 1.13
  • StereoVision lib 1.0.3(https://github.com/erget/StereoVision)

安装所有软件的过程不在本文的讨论范围之内,我们只建议下载完成的Raspbian映像(在本文末尾链接到github)。

第一步:拍摄照片


为此,请使用1_test.py脚本

打开控制台,从主文件夹转到包含示例的文件夹:

cd stereopi-tutorial 

运行脚本:

 python 1_test.py 

启动后,屏幕上会显示我们的立体图像的预览。 按下Q按钮可以中断该过程,这将保存最后捕获的图​​像,该图像将在以下脚本之一中用于配置深度图。

该脚本使您可以确保所有硬件都能正常工作,并获得第一张图片以备将来使用。

这是第一个脚本的样子:


第二步:收集图片进行校准


如果我们在真空中谈论球形马,那么要获得高质量的深度图,我们需要有两个绝对相同的摄像机,其垂直轴和光轴完全平行,而水平轴重合。 但是在现实世界中,所有摄像机都略有不同,因此无法完美地布置它们。 因此,发明了一种软件校准技巧。 使用来自现实世界的两台摄像机,拍摄了大量先前已知物体的照片(我们有一张带有棋盘的照片),然后一种特殊的算法计算所有“缺陷”并尝试校正这些照片,以使其接近理想状态。

该脚本完成了第一阶段的工作,即有助于制作一系列照片以进行校准。

在每张照片之前,脚本都会开始5秒钟的倒计时。 通常,这一次足以将板子移动到新位置,以确保在两个摄像机上都不会爬行,并且固定其位置(以使照片中没有模糊)。 默认情况下,系列大小设置为30张照片。

发射:

 python 2_chess_cycle.py 

工艺流程:


结果,我们在/ scenes文件夹中有一系列照片。

我们将图片分成两半


第三个脚本3_pairs_cut.py将拍摄的照片剪切为“左”和“右”照片,并将它们保存在/ pair文件夹中。 实际上,我们可以排除此脚本并即时进行剪切,但是在进一步的实验中它非常有用。 例如,您可以保存来自不同系列的切片,使用脚本与这些对配合使用,甚至可以将在其他立体相机上拍摄的照片成对放开。

另外,在剪切每张图像之前,脚本会显示其图像,这通常使您可以在下一个校准步骤之前查看失败的照片,并将其删除。

运行脚本:

 python 3_pairs_cut.py 

短片:


在完成的图像中,有一组我们用于实验的照片和剪切对。

标定


脚本4_calibration.py绘制棋盘中的所有对,并计算必要的校正以校正图片。 该脚本会自动拒绝未找到棋盘的照片,因此,如果照片不成功,工作不会停止。 上传所有30对图片后,计算开始。 我们大约需要一分钟半的时间。 完成后,脚本将获取一对立体声对,并根据计算出的校准参数对它们进行“校正”,从而在屏幕上显示校正后的图像。 此时,您可以评估校准的质量。

通过命令运行:

 python 4_calibration.py 

工作中的校准脚本:


深度图设置


5_dm_tune.py脚本加载第一个脚本拍摄的图片和校准结果。 接下来,显示一个界面,使您可以更改深度图的设置并查看发生了什么变化。 提示:在设置参数之前,先取一个框架,在该框架中同时放置不同距离的物体:闭合(30-40厘米),平均距离(一两米)和该距离。 这将允许您选择参数,在这些参数中,靠近的对象将为红色,而远处的对象将为深蓝色。

该图像包含具有我们的深度图设置的文件。 您只需单击“加载设置”按钮即可在脚本中加载我们的设置

我们推出:

 python 5_dm_tune.py 

设置过程如下所示:


实时深度图


最后一个脚本6_dm_video.py使用先前脚本的结果(深度图的校准和设置)从视频中构建深度图。

发射:

 python 6_dm_video.py 

实际结果是:


我们希望我们的脚本将对您的实验有用!

为了以防万一,我将添加所有脚本都具有按键处理功能,并且您可以通过按Q按钮来中断工作。如果您“大致”停止(例如Ctrl + C),则Python与摄像头的交互过程可能会中断,并且需要重新启动树莓派。

对于高级


  • 该过程中的第一个脚本显示两次帧捕获之间的平均时间,完成后显示平均FPS。 这是一个简单方便的工具,用于选择python仍未“窒息”的图像参数。 有了它,我们以20 FPS的速度拍摄了1280x480,其中视频呈现没有延迟。
  • 您可能会注意到,我们捕获了1280x480分辨率的立体声对,然后将其缩放为640x240。

    一个合理的问题:为什么要所有这些,为什么不立即抓取缩略图并通过缩小而不加载我们的python?

    答:在非常低的分辨率下直接捕获时,树莓派核心仍然存在问题(图片破裂)。 因此,我们采用较大的分辨率,然后缩小图片。 这里我们使用了一个小技巧:图片不是使用python缩放的,而是在GPU的帮助下缩放的,因此arm核心没有负载。
  • 为什么要以BGRA格式而不是BGR格式捕获视频?
    我们使用GPU资源来减小图片的大小,而调整大小模块的本机是BGRA格式。 如果我们使用BGR代替BGRA,我们将有两个缺点。 第一个略低于最终的FPS(在我们的测试中为20%)。 第二个是控制台“ PiCameraAlfaStripping:使用alpha-stripping转换为非alpha格式; 您可能会更快找到等效的Alpha格式”。 对其进行谷歌搜索导致了Picamera文档部分,该部分描述了该技巧。
  • PiRGBArray在哪里?

    这就像用于相机的本机Picamera类,但此处未使用。 事实证明,在我们的测试中,使用“手工制作”的numpy数组比使用PiRGBArray快得多(大约是一半)。 这并不意味着PiRGBArray不好,很可能是我们弯曲的双手。
  • 计算深度图的百分比如何加载?
    让我们用图片回答:



    我们看到,在处理器的4个内核中,实际上只有一个被加载,占70%。 尽管我们使用GUI,并且我们正在向用户输出图片和深度图,但事实并非如此。 这意味着有很好的性能余量,并且使用C语言中的OpenMP和其他功能对OpenCV进行微调以及没有GUI的“战斗”模式都可以产生非常有趣的结果。
  • 通过这些设置获得的最大FPS深度图是多少?

    当我们从相机每秒捕获20帧时,我们获得的最大速度为17 FPS。 在深度图设置中,就速度参数而言,最“响应”的是MinDisparity和NumOfDisparities。 这是合乎逻辑的,因为它们确定用于比较帧的搜索窗口在算法内执行的“步数”。 第二敏感的是preFilterCap;它特别影响深度图的“平滑度”。
  • 处理器的温度如何?

    在Compute Module 3+ Lite(一个新的系列,过程上有一个铁“帽”)上,它大致显示以下结果:

  • 如何使用GPU?

    至少,它可以用于实时对图片进行安定和校正,因为有示例( 在WebGL上有此示例),Python Pi3d以及Processing项目( 有覆盆子的示例 )。

    中村浩一还有另一个有趣的发展,叫做py-videocore 。 在与他的通讯中,他表达了一个想法,即要加速StereoBM,可以在Cuda支持下使用其核心和OpenCV排序。 总的来说,为了优化-正如他们所说,这是未触及的优势。

感谢您的关注,这是承诺的链接

Source: https://habr.com/ru/post/zh-CN446872/


All Articles