首页 > 解决方案 > OpenCV - How to remove convexity defects in a cam scanner?

问题描述

I get in trouble by finding an algorithm to remove the convexity of my photos. As you can see the photos are captured from book pages, and I wanna remove the convexity. My question is similar to this but what I have is just page boundaries as input and neither I have grid nor am able to find by processing algorithms. enter image description here

I wanna output as the right one in the below photo. enter image description here

Obviously, the perspective transformation is the first thing comes in mind. However, as you can see the result is not promising: enter image description here

标签: pythonc++opencv

解决方案


这是解决您的问题的可能管道。主要思想是识别文本,创建一个具有某种形态的超级斑点,定位这个超级斑点的 4 个角并将这些点提供给透视“unwarper”(或整流器,或任何你希望称之为透视校正的东西方法)。

首先将图像转换为灰度并对其应用自适应阈值。尝试使用更适合您的测试的参数的高斯或均值方法。这是我在稍微摆弄一下值后得到的结果:

在此处输入图像描述

现在,我们的想法是只隔离 text。我应用的解决方案是:获取最大的斑点并从原始图像中减去它们。您将需要一种方法来计算每个二进制 blob 的面积。查看上一篇文章以获取有关如何实施的建议。

这些是图像中最大的斑点:

在此处输入图像描述

从原始图像中减去最大的斑点。这是结果:

在此处输入图像描述

如您所见,文本几乎是孤立的。让我再次应用一个区域过滤器来清理一点点像素。这次要消除小斑点。这是结果:

在此处输入图像描述

很好,运行过程中有些字符丢失了,不过没关系。我们需要一个漂亮的连续文本块,因为我们要扩大它的地狱。我尝试应用大小为 5 和 5 Op 迭代的矩形结构元素。之后再用 5 次迭代腐蚀输出,所以你最终得到了这个漂亮的 - 隔离的 - 超级 blob,文本曾经是:

在此处输入图像描述

一探究竟。您看到的 3 个标记是我在图像上检测到的最大斑点的质心。我们需要找到super blob 的 4 个角。图像中最大的斑点是我们所追求的。我决定重新使用面积过滤器并寻找面积最大的斑点。这是孤立的超级 blob:

在此处输入图像描述

从这里开始,操作非常简单。同样,目标是获得这个 blob 的四个角。您可以拟合矩形或应用边缘检测器,然后进行霍夫变换,以获得跟随超级斑点边缘的直线。

我决定应用Canny Edge 检测器,然后应用Hough 变换。当然,我调整了变换以仅过滤我感兴趣的可能线——超过一定长度的直线。这是线检测的结果:

在此处输入图像描述

图像上绘制了一些额外的信息。您看到的标记(红色和黄色)是线条的起点/终点。我的想法是找到一堆这些线并计算这些点的平均值。这个想法是我们有一组点,这些点在“象限”中分开。如果我们计算每个象限每条线的起点和终点的平均值,我们将得到 4 个平均值——这些是超级斑点角的近似值!

我将K-means应用于线条的起点和终点,但您更喜欢其他处理方法。没关系。我的近似角由上图中的大红色 O 标记标识。

正如我所建议的,尝试为这些角提供一个固定的输出位置。我为要映射的角定义了红色矩形。对于这个测试,我几乎手动调整了矩形。透视校正产生以下结果:

在此处输入图像描述

一些建议:

  1. 根据输入图像的分辨率,您可以缩小它以获得更快更好的结果,因为您的输入似乎足够大。

  2. 调整霍夫线检测以产生更大的线。我当前的配置检测到一些较小的线,这可能会阻碍角近似。

  3. 我选择了一种比较稳健的方法来计算我之前个人使用过的超级斑点的 4 个角(边缘检测 + 霍夫线变换 + K-means),但是您选择获取数据的任何处理链完全取决于您!


推荐阅读