openCV进阶之二:自动校准扫描图像生成鸟瞰图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了openCV进阶之二:自动校准扫描图像生成鸟瞰图相关的知识,希望对你有一定的参考价值。

参考技术A 上一节介绍了如何openCV的透视转换方法的应用,并构建了一个基于给定四角点转换鸟瞰图的方法函数,这一节将继续这个运用,通过查找边缘的方法实现自动转换的功能。

实现步骤实际上很简单,只需要三步:

第一步:查找文档的边缘

第二步:通过边缘查找文档轮廓并找到四个角点的坐标

第三步:使用透视转换函数完成图像转换

下面的代码基于openCV/python的版本:openCV2.4/3+, python2.7/3+

上一章节我们完成了transform.py模块的构建,我们将在接下来的涉及图像四角点处理的问题中均会使用到。打开你的python编辑器,创建一个新的文档,并命名为scan.py。

接下来就是第一步:边缘查找:

测试一下效果:

shell

虽然背景有点不干净但是文档的边缘还是很明显的,接下来我们想办法查找文档的边缘并生成轮廓。

第二步:寻找轮廓:

事实上,在构建文档扫描器时,有一个非常重要的前提:扫描仪只是在一张纸上扫描。一张纸被假定为长方形,矩形有四条边。因此,我们可以创建一个简单的方法来帮助我们构建文档扫描器。我们假设图像中最大的轮廓恰好有四个点,这就是我们要扫描的那张纸。这也是一个相当安全的假设——当然,也可以人为的给定文档轮廓。

运行一下代码测试效果:shell中输入

正如您所看到的,我们已经成功地利用边缘检测图像找到了文档的轮廓(outline),我的收据周围的绿色矩形显示了轮廓(outline)。最后,让我们进入步骤3,这将是用到four_point_transform函数。

第三步:转换图像:构建移动文档扫描器的最后一步是取代表文档大纲的四个点,并应用透视图转换来获得自顶向下的图像“鸟瞰图”。

我们将把两个参数传递给four_point_transform:第一个参数是我们从磁盘加载的原始图像(不是调整大小的图像),第二个参数是表示文档的轮廓线,乘以调整大小的比例。

你可能会想,为什么要乘以调整后的比例? 我们乘以调整后的比例,因为我们进行了边缘检测,在调整后的高度=500像素的图像上发现了轮廓。但是,我们希望对原始图像进行扫描,而不是对调整大小的图像进行扫描,因此我们将轮廓点乘以调整大小的比例。

为了获得图像的黑白感觉,我们将扭曲后的图像转换为灰度图像,并应用自适应阈值。

好的,我们来运行一下效果:

shell

好了,到目前为止,扫描图像到文档提取鸟瞰图的过程实现完成了。遗留问题:

实际上这个程序还有不少地方需要你的改进,比如要求转换的文档本身是规则的四边形,拍摄时尽量放在对比度明显的桌面背景,这样做的目的是为了避免边缘查找时出现多于四边的情况,多于四边的边缘后续轮廓查找会出现问题。也就是找不到合适的四边轮廓来匹配。

解决方案:可以采用人工标注四个角点的方式来提取轮廓更为可靠。因为在实际应用场景往往是不规则的文档。下一节我们来探讨这个方案实现过程。

图像裁剪的 OpenCV 相机校准(ROI 子矩阵)

【中文标题】图像裁剪的 OpenCV 相机校准(ROI 子矩阵)【英文标题】:OpenCV camera calibration of an image crop (ROI submatrix) 【发布时间】:2014-03-16 13:53:32 【问题描述】:

我在使用 OpenCV 的 undistort 函数时遇到了一点问题。我正在使用使用广角镜头的相机。假设我对它的访问是有问题的,因为它已经安装了。问题基本上归结为:

我已经成功测量了所有镜头参数,并且可以毫无问题地使全帧图像不失真,问题是我实际上是在某种线扫描模式下工作。我们只在传感器中间使用了一个切口,大约 100 像素高。图片说明:

现在,如果我对相关图像的 ROI(感兴趣区域)应用 undistort,它自然会假定它是全帧顶部的切口,因此校正与它应该做的大不相同全画幅高度的一半。

如果我只使用较低分辨率的全帧,我了解如何修改相机矩阵以补偿图像比例,但问题是:我能否以任何方式补偿裁剪的部分偏移以实现正确的转换?

我想我可以使用全帧分辨率的黑色图像,然后将相关数据复制到其中,但这是不可能的,因为这样会影响处理速度。

感谢您的任何见解!

干杯, 一月。

【问题讨论】:

你试过调整主点(cx,cy)吗? 意思是如果我说服 undistort 认为镜头的中心位于全画幅图像的顶部可能会有所帮助?会尝试...谢谢。 如果你裁剪图像,那么主点将有不同的坐标。例如,如果您的原始主点位于 (30,40),并且您在两侧裁剪 10 个像素,那么您的新主点将位于 (20,30),因为像素 (20,30) 在裁剪后的图像与原始图像中的像素 (30,40) 相同。 果然如此。谢谢一堆。您能否将其发布为答案,以便我接受? 【参考方案1】:

如果您裁剪图像,则主点将具有不同的坐标。例如,如果您的原始主点位于 (30,40),并且您在边上裁剪了 10 个像素,那么您的新主点将位于 (20,30),因为像素 (20,30) 在裁剪后的图像与原始图像中的像素 (30,40) 相同。

您需要相应地调整相机矩阵中的 cx an cy 值。

【讨论】:

以上是关于openCV进阶之二:自动校准扫描图像生成鸟瞰图的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV在车道线查找中的使用

什么是无人机陀螺仪?

深度图 - 带有 OpenCV 的 Android 中的立体图像

使用来自 OpenCV 的转换矩阵手动进行图像校准

为啥在 OpenCv 中调整图像大小会降低相机校准的重投影误差?

opencv - 生成巨大的校准模式