【问题标题】:Trilateration in python [closed]python中的三边测量[关闭]
【发布时间】:2019-02-03 23:13:26
【问题描述】:

我正在研究定位系统。 我的输入是一个字典,它将给我们从点(x1,y1)等半径为 d1 的圆。 我想要的输出是一个数组(类似于二维坐标系),其中相交区域标记为 1,其余部分为 0。 我试过这个:

xsize=3000
ysize=2000
lis={(x1,y1):d1,(x2,y2):d2,(x3,y3):d3}
array=np.zeros((xsize,ysize))
for i in range(xsize-1):
    for j in range(ysize-1):
        for element in lis:
            if distance((i,j),element)<=(lis[element]):
                array[i][j]=1
            else:
                array[i][j]=0
                break
def distance(p1,p2):
    return math.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)

唯一的问题是数组很大并且花费的时间太长(循环数为 1000 万),尤其是在树莓派上,否则这是可行的。 有没有办法使用openCV和图像然后画圈来更快地获得相交区域?

它必须是 python 2.x。

【问题讨论】:

  • 请提供minimal reproducible example。目前我什至无法弄清楚什么在起作用。
  • 我稍微编辑了一下,你现在明白我的问题了吗?(语法没有问题只是需要一种更快的方法来获得结果而无需那么多循环)@timgeb
  • 我猜你可以在内存中的 numpy 数组中创建一个 3000x2000 的空白黑色图像。然后,对于列表中的每个圆圈,创建一个 2*d x 2*d 黑色画布(同样作为numpy 数组)并在其中使用fill colour=1 绘制一个圆圈。使用切片将该正方形添加到您的主图像中。最后,如果您的列表中有 7 个圆圈,则创建一个包含所有值为 7 的像素的蒙版。顺便提一下,请注意抗锯齿。
  • 上述技术也应该适用于 OpenCV。
  • 顺便说一句,如果您正在测试距离是否小于 10,则不采用 sqrt()(这很慢)并测试距离平方是否小于 100 会更快。

标签: python python-2.7 opencv trilateration


【解决方案1】:

由于您已经在使用 numpy,请尝试以矢量化方式重写您的操作,而不是使用循环。

# choose appropriate dtype for better perf
dtype = np.float32

# take all indices in an array
indices = np.indices((ysize, xsize), dtype=dtype).T
points = np.array(list(lis.keys()), dtype=dtype)

# squared distance from all indices to all points
dist = (indices[..., np.newaxis] - points.T) ** 2
dist = dist.sum(axis=-2)

# squared circle radii
dist_thresh = np.array(list(lis.values()), dtype=dtype) ** 2

intersect = np.all(dist <= dist_thresh, axis=-1)

这在我的机器上比 for 循环版本快 60 倍左右。

它仍然是一个蛮力版本,可能对所有坐标进行许多不必要的计算。问题中没有给出圆圈,因此很难对它们进行推理。如果它们覆盖相对较小的区域,如果考虑较小的区域,问题将更快地解决(仍然是计算上的,而不是分析上的)。例如,可以使用圆的边界框的交集来代替测试所有坐标,这可以大大减少计算量。

【讨论】:

  • 酷 - 干得好!
【解决方案2】:

感谢您的回答!

我还发现了这个:

pos=np.ones((xsize,ysize))
xx,yy=np.mgrid[:xsize,:ysize]
for element in lis:
    circle=(xx-element[0])**2+(yy-element[1])**2
    pos=np.logical_and(pos,(circle<(lis[element]**2)))
    #pos&circle<(lis[element]**2 doesn't work(I read somewhere it does)

我需要这个数组来标记我何时到达目的地。

if pos[dest[0]][dest[1]]==1 #Reached

我也想通过将像素更改为 (0,0,255) 来显示图像上的位置。我该怎么做?

【讨论】:

    猜你喜欢
    • 2012-04-28
    • 2016-03-07
    • 2022-10-05
    • 2012-04-02
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多