任何形状的四边形的最小外接矩形或凸包?

7

注意: 我正在尝试创建一个可以处理各种图像、方向和质量的进程,而不仅仅是针对这个图像。

我知道您可以使用凸包将一组点用多边形包围起来,并且可以使用其中的几种算法之一为这些点创建最小边界框。然而,我想做类似于最小边界框的事情,但不限于矩形。

比如我有这张收据:

enter image description here

凸包:

enter image description here

最小边界框(旋转卡壳):

enter image description here

我的目标(ms-paint):

enter image description here

正如您所看到的,最小边界框并不完全适用,因为从透视图来看,收据是一个梯形。这只会在透视越低时变得更糟。我想要4个点和尖锐的角落,所以我不能使用凸包。

是否有一种算法可以让我获得类似于凸包或最小边界框的东西,但限制为4个点和任何四边形形状?


为什么不使用Harris角点检测器?或者用您当前的算法拒绝凸包中的小线段,并找到长线段的交点。利用两个端点,可以使用行列式方法找到交点。或者,您可以保留来自凸包的所有点,并使用kmeans聚类找到这些4个点的中心,并称之为您的点。 - alkasm
1
请查看我在此处的答案,了解使用Hough线进行交点聚类的示例。我认为对于该图像,找到轮廓并拟合线条以及像我在那个答案中所做的那样找到交点可能会更好。 - alkasm
@AlexanderReynolds 好主意。现在我生成轮廓,将其近似减少,进行凸包操作,然后查找最小边界框。我不想使用凸包或轮廓的唯一原因是对于形状奇怪的收据,例如非常圆润或扭曲的边缘。霍夫线是一个替代方案,但即使在边缘检测之前进行了重度模糊和平滑处理,我也会从文本中获得数百条线。如果我想改进这一点,那将是另一个问题。编辑好答案,看起来很有前途。 - Douglas Gaskell
使用形态学操作使文本在查找轮廓之前几乎消失。在Stack上看到一个很好的例子(https://dev59.com/rFcP5IYBdhLWcg3wqLow#44054699),做除了你想要做的一切。无论如何,文本处理可以帮助将这些霍夫线跟踪到边界。并且可能有助于进一步处理,我假设您将要进行处理。 - alkasm
1个回答

3
通过对色彩空间过滤和形态学操作的一些调整,我成功地使用了Harris检测器。您也可以像我从霍夫线这里那样使用交点进行扩展,这可能很有用,但有点冗长。这对于特定的图像效果很好,但对于管道来说,需要大量参数(开放和关闭内核大小、迭代次数)。
我的实现是用Python编写的,当然也可以在C++或Java中使用。
import numpy as np
import cv2

# read image
img = cv2.imread('receipt.png')

# thresholding
blur = cv2.GaussianBlur(img, (5,5), 1)
hls = cv2.cvtColor(blur, cv2.COLOR_BGR2HLS)
low = np.array([0, 70, 0])
high = np.array([255, 255, 85])
thresh = cv2.inRange(hls, low, high)

# morphological operations to get the paper
kclose = np.ones((3,3), dtype=np.uint8)
kopen = np.ones((5,5), dtype=np.uint8)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kclose, iterations=2)
opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kopen, iterations=6)

# corner detection
opening = cv2.GaussianBlur(opening, (3,3), 1)
opening = np.float32(opening)
dst = cv2.cornerHarris(opening, 2, 3, 0.04)

# drawing corners
dst = cv2.dilate(dst, None)
img[dst>0.01*dst.max()]=[0,0,255]

cv2.imshow('Corners', img)
cv2.waitKey(0)

这里是角落:

Corners

请注意,从Harris算法中你会得到多个像素点,如果想要在后续的图像处理中使用它们进行变形,你需要进行聚类以获取单个角点。
我对图像应用了颜色空间过滤、闭运算和开运算的掩模,所以你可以在这些操作后看到掩模。
过滤:

Filtering

关闭:

Closing

打开:

Opening


谢谢Alex!我正在浏览这个内容。你为什么选择了这些低/高颜色?这是随意的,还是特定于这张图片,或者是标准的?如果它只是特定于这张图片,那么有没有一种方法来确定给定图片的低/高应该是什么? - Douglas Gaskell
完全针对这张图片。通常情况下,如果没有特定的背景知识,自动过滤是相当困难的。如果您正在开发一个应该与任何背景一起使用的应用程序,则此方法不太健壮。您应该在不同的颜色空间中进行实验,以了解每个颜色对应于白色和浅灰色的感觉。对于任意图像,最好继续使用原始方法——轮廓并按照我在问题评论中建议的方式跟随它们到角落。 - alkasm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接