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

在python中如何从检测到的边点检测平行四边形,python,numpy,computer-vision,edge-detection,hough-transform,Python,Numpy,Computer Vision,Edge Detection,Hough Transform,我正在读一幅图像,并试图检测图像中的平行四边形。我已经使用Hough变换创建了一个包含边缘点(局部峰值)的数组 (p=xcos(θ)+ysin(θ))。我得到了大约2300个边点(X,Y),我不知道如何从中获取/提取平行四边形。在2300个边缘点中,一些边缘点为圆形,三角形包括平行四边形 如果我开始考虑边点(X,Y),那么它将不起作用,因为它们不仅是平行四边形的顶点,而且边点的数量很大(2300点) [第1版] 我已将边缘点存储在test\u img中,它包含像素值。 test_img[poin

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

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

[第1版]

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

测试尺寸=2343

在绘制了上面的测试图像“plt.imshow(test\u img,cmap=“gray”)”之后,我得到的图像如下所示

任何帮助都将不胜感激


更新:此代码是在OP给出任何示例之前编写的。它应该适用于点云。但它找不到“几乎平行四边形”。

一种简单的方法是为每对点计算
(dx,dy)
,并将它们保存在dict中。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个点的输出:


对于2300个点,您可能会发现许多平行四边形。

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

  • 选择属于某条边及其
    N
    邻居的随机点,并将其放入列表
    L
    。调整查找邻居的过程以处理小间隙
  • 计算一条适合
    L
    中数据的线。跟踪直线参数(角度、偏移和MSE)
  • 继续添加多批邻居并重新计算线性模型,直到MSE开始上升
  • 你可能找到了一条线段!它的MSE是否接近零,它是否足够长?如果是,请将线路的估计参数存储在某处
  • 从图片中排除
    L
    中的像素
  • 去#1

  • 在你收集了这些片段之后,找到类似平行四边形的东西应该是非常简单的。

    你很幸运,得到了相当干净和连续的边

    您可以使用道格拉斯·佩克程序,使用合适的直线度公差,将其分段为直线段。保留足够长的线段*

    您还可以尝试填充闭合段和对齐段之间的间隙,以及重建断角(*然后仅在重建后过滤长度)

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


    我们真的需要一些代码和输入/输出的格式/形状,以便开始考虑这个问题。请阅读并感谢您的反馈,我已经更新了感谢您的回答。我正在尝试获取/提取上图中的平行四边形。谢谢您的回答。我想找到这样的平行四边形