如何从python中检测到的边缘点检测平行四边形

时间:2017-10-30 12:49:24

标签: python numpy computer-vision edge-detection hough-transform

我正在阅读图像并试图检测图像中的平行四边形。我使用Hough变换创建了一个包含边缘点(局部峰值)的数组 (p = x cos(theta)+ y sin(theta))。我得到了大约2300个边缘点(X,Y),我不知道如何从中获取/提取平行四边形。在2300个边缘点中,一些边缘点为圆形,三角形包括平行四边形。

如果我开始考虑边缘点(X,Y),那么它将不起作用,因为它们不仅是平行四边形和边缘点的顶点都是大数(2300点)。

[EDIT1]

我已将边缘点存储在 test_img 中,并且它包含像素值。 test_img [point.getX(),point.getY()] = 255

test_img.size = 2343

在绘制上面的test_image之后“plt.imshow(test_img,cmap =”gray“)”我得到的图像如下

任何帮助都将受到高度赞赏。

enter image description here

3 个答案:

答案 0 :(得分:0)

更新:此代码是在OP给出任何示例之前编写的。它应该与点云一起使用。然而,它找不到几乎平行四边形的图像。

一种天真的方法是为每对点计算(dx, dy)并将它们保存在一个字典中。 dict的值是点对的列表。如果有超过1对,则每对组合将形成一个平行四边形。

效率不高(O(n**2)),但仍可以使用2300分。它比简单地测试每个4元组的点数要高效得多。

这是一个快速而肮脏的实现:

from random import randint, random
from collections import defaultdict
import matplotlib.pyplot as plt
import matplotlib.patches as patches

# N = 2300
# width = 3000
# height = 2000
N = 180
width = 3000
height = 2000
points = [(randint(0, width), randint(0, height)) for _ in range(N)]
points = list(set(points))  # unique points
n = len(points)

plt.scatter(*zip(*points), linewidth=0.001)

vectors = defaultdict(list)

for i in range(n):
    x1, y1 = points[i]
    for j in range(i + 1, n):
        x2, y2 = points[j]
        vectors[(x2 - x1, y2 - y1)].append((i, j))

ax = plt.gca()
for vector, pairs in vectors.items():
    if len(pairs) > 1:
        # TODO: Consider every combination if len(pairs) > 2
        a, b, c, d = points[pairs[0][0]], points[pairs[0][1]], points[pairs[1][1]], points[pairs[1][0]]
        ax.add_patch(patches.Polygon(xy=[a, b, c, d], fill=False, color=[random(), random(), random()]))

plt.show()

这里的输出在3000 * 2000网格中有180个点:

enter image description here

有2300分,你可能会发现很多平行四边形。

答案 1 :(得分:0)

鉴于你已经有了整齐的边缘,你可以尝试应用linear regression来提取直线边缘:

  1. 选择属于边缘的随机点及其N个邻居,并将其放入列表L。调整寻找邻居的程序以处理小的差距。
  2. 计算适合L中数据的行。跟踪线参数(角度,偏移和MSE)。
  3. 继续添加批次邻居并重新计算线性模型,直到MSE开始上升。
  4. 你可能找到了一个线段!它的MSE接近于零,它足够长吗?如果是,请在某处存储该行的估计参数。
  5. 从图片中排除L的像素。
  6. 转到#1。
  7. 在你收集了这些片段之后,找到类似平行四边形的东西应该是非常简单的。

答案 2 :(得分:0)

你很幸运能获得相当干净和连续的边缘。

您可以通过Douglas-Peucker程序以合适的直线度公差对线段进行分段。保持足够长的段*。

您还可以尝试填补近距离和良好对齐的线段之间的间隙,以及重建断角(*然后只在重建后过滤长度)。

如果一切顺利,您应该能够获得如下所述的描述,并通过分析边/角图来推断出四边形。 (注意形状重叠处的寄生角。)

enter image description here