gpt4 book ai didi

python - 从一点开始就保持多条线

转载 作者:行者123 更新时间:2023-12-02 16:59:25 26 4
gpt4 key购买 nike

我正在使用OpenCV和python进行项目,但是卡在了这个小问题上。
我在列表中存储的许多行上都有端点的坐标。有时会出现从单个点检测到多条线的情况。从这些行中,我想保持最短的行并消除所有其他行,因此我的图像将不会包含绘制多条线的任何点。
我的变量存储了最初检测到的所有行的信息(两个端点的坐标),如下所示:

var = [[Line1_EndPoint1, Line1_EndPoint2],
[Line2_EndPoint1, Line2_EndPoint2],
[Line3_EndPoint1, Line3_EndPoint2],
[Line4_EndPoint1, Line4_EndPoint2],
[Line5_EndPoint1, Line5_EndPoint2]]
其中,LineX_EndPointY(行号“X”,该行的端点“Y”)的类型为[x,y],其中x和y是图像中该点的坐标。
有人可以建议我如何解决这个问题。
您可以修改行数据的存储方式。如果您进行修改,请说明您的数据结构及其创建方式
此类数据的示例:
[[[551, 752], [541, 730]], 
[[548, 738], [723, 548]],
[[285, 682], [226, 676]],
[[416, 679], [345, 678]],
[[345, 678], [388, 674]],
[[249, 679], [226, 676]],
[[270, 678], [388, 674]],
[[472, 650], [751, 473]],
[[751, 473], [716, 561]],
[[731, 529], [751, 473]]]
Python代码会很有意义。

最佳答案

一个Numpy解决方案
完全基于我的第一个答案可以得到相同的结果
在Numpy上。
首先定义2个功能:

  • 计算一行长度的平方:
     def sqLgth(line):
    p1, p2 = line
    return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
  • 将 vector (一维数组)转换为列数组(二维数组)
    单列:
     def toColumn(tbl):
    return tbl.reshape(-1, 1)

  • 两者都将在以后使用。
    然后执行以下操作:
  • 获取行数:
     lineNo = var.shape[0]
  • 生成线索引(points数组中lineInd列的内容
    (将在以后创建)):
     id = np.repeat(np.arange(lineNo), 2)
  • 生成“来源指标”(1-开始,2-结束)以简化分析
    任何中间打印输出:
     origin = np.tile(np.array([1, 2]), lineNo)
  • 计算行长(以磅为单位的lgth列的内容):
     lgth = np.repeat([ sqLgth(line) for line in var ], 2)
  • 创建包含一些其他数据的点的列表(连续的)
    列包含原点,lineInd,x,y和lgth):
     points = np.hstack([toColumn(origin), toColumn(id),
    var.reshape(-1, 2), toColumn(lgth)])
  • 计算“条件数组”进行排序:
     r = np.core.records.fromarrays(points[:, 2:].transpose(),
    names='x, y, lgth')
  • 排序点(按x,y和lgth):
     points = points[r.argsort()]
  • 计算“逆唯一索引”到点:
     _, inv = np.unique(points[:,2:4], axis=0, return_inverse=True)
  • 将inv移位1位:
     rInv = np.roll(inv,1)
    将用于下一步,以获取上一个元素。
  • 生成要删除的行索引列表:
    toDrop = points[[ i for i in range(2 * lineNo)
    if inv[i] == rInv[i] ], 1]
    行索引(在点数组中)是重复点(元素)的索引
    inv等于前一个元素)。
    列索引(1)-指定lineInd列。
    整个结果(toDrop)是“拥有”行的索引列表
    (包含重复的点)。
  • 生成结果:var从在
    前一步:
    var2 = np.delete(var, toDrop, axis=0)

  • 要打印缩小的行列表,可以运行:
    for line in var2:
    print(f'{line[0]}, {line[1]}')
    结果是:
    [551 752], [541 730]
    [548 738], [723 548]
    [345 678], [388 674]
    [249 679], [226 676]
    [731 529], [751 473]
    要完全理解此代码的工作方式:
  • 分别执行每个步骤
  • 打印结果
  • 将它与先前步骤中的打印输出进行比较。

  • 有时甚至单独打印某些表达式也很有帮助
    (说明的一部分),例如 var.reshape(-1, 2)-转换您的
    var(形状(10,2,2))变成点的2D数组(每行是
    一个点)。
    整个结果当然与我的第一个答案相同,
    但是正如您所写,您对 Pandas 的经验很少,现在您可以
    比较这两种方法,看看 Pandas 允许这样做的情况
    更简单,更直观的东西。
    很好的例子是按某些列排序或查找重复的行。
    在 Pandas 中,这是一个单一指示的问题,
    参数,而在Numpy中,您必须使用更多说明
    并了解各种细节和技巧,如何做到相同。

    关于python - 从一点开始就保持多条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62833614/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com