Python Numpy 生成X和Y值在特定范围内的坐标

7

我试图生成一组坐标,这些坐标将位于图像上。 使用的图像是640x480像素的框架。我已经能够创建一个包含所有我想要使用的xy点的数组。我试图在每个这些点上绘制小圆圈,仅用于可视化和以后使用,因此我正在尝试将坐标转换成可输入到OpenCV圆形函数的形式。下面是我到目前为止的进展:

Ypts = np.arange(5, 480, 5)
Xpts = np.arange(5, 640, 5)

我尝试使用了。
[pts]= np.vstack([Xpts, Ypts]).T

并且
coordinate = []
for x in range(Xpts.size):
    for y in range(Ypts.size):
        coordinate.append((x, y))

没有成功,我得到的坐标输出是[0, 0], [0, 1], [0, 2], ...,而不是与XptsYpts的值相关的点。

在更小的范围内,这是x和y数组的示例:

Xpts = [5, 10, 15, 20, 25, 30, 35]
Ypts = [5, 10, 15]

我的问题是希望得到以下答案:

Points = [[5, 5],
    [5, 10],
    [5, 15],
    [10, 5],
    [10, 10],
    [10, 15],
    [15, 5],
    [15, 10],
    ......,
    [35, 15]]

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - BrenBarn
4个回答

17

这个解决方案的启发并专注于性能,您也可以使用np.meshgrid -

X2D,Y2D = np.meshgrid(Ypts,Xpts)
out = np.column_stack((Y2D.ravel(),X2D.ravel()))

运行示例 -

In [39]: Xpts=np.array([5, 10, 15, 20, 25, 30, 35])
    ...: Ypts=np.array([3, 6, 9])
    ...: 

In [40]: X2D,Y2D = np.meshgrid(Ypts,Xpts)

In [41]: np.column_stack((Y2D.ravel(),X2D.ravel()))
Out[41]: 
array([[ 5,  3],
       [ 5,  6],
       [ 5,  9],
       ......
       [35,  6],
       [35,  9]])

运行时测试

通常我会列出用于解决问题的向量化方法的时间。因此,这里列出的方法归功于各自的作者。

列出的方法包括函数:

def itertools_based():
    Ypts = np.arange(5, 480, 5)
    Xpts = np.arange(5, 640, 5)
    return np.array(list(itertools.product(Xpts, Ypts)))

def c__based():
    py, px = np.mgrid[5:640:5,5:480:5]
    return np.c_[py.ravel(), px.ravel()]

def meshgrid_based():
    Ypts = np.arange(5, 480, 5)
    Xpts = np.arange(5, 640, 5)
    X2D,Y2D = np.meshgrid(Ypts,Xpts)
    return np.column_stack((Y2D.ravel(),X2D.ravel()))

最后验证并计时它们:

In [111]: %timeit itertools_based()
     ...: %timeit c__based()
     ...: %timeit meshgrid_based()
     ...: 
100 loops, best of 3: 9.16 ms per loop
1000 loops, best of 3: 380 µs per loop
10000 loops, best of 3: 198 µs per loop

In [112]: np.allclose(itertools_based(),c__based())
Out[112]: True

In [113]: np.allclose(itertools_based(),meshgrid_based())
Out[113]: True

6
你可以使用numpy的mgrid生成所有可能的组合:
>>> py, px = np.mgrid[5:480:5, 5:640:5]
>>> points = np.c_[py.ravel(), px.ravel()]
>>> points
array([[  5,   5],
       [  5,  10],
       [  5,  15],
       ..., 
       [475, 625],
       [475, 630],
       [475, 635]])

1
按照示例的预期输出,应该是 py, px = np.mgrid[5:640:5,5:480:5],不是吗? - Divakar
@Divakar 是的,我认为你是对的!我倾向于将图像视为“高度x宽度”(就像Python中的C排序一样)。我想如果OP只想要点,并且顺序不重要,这也可能有点无关紧要。 - Imanol Luengo

6

您可以使用itertools.product,它会返回提供的列表的所有可能组合。以下是一个示例代码:

import numpy as np
import itertools

Xpts=[5, 10, 15, 20, 25, 30, 35]
Ypts=[5, 10, 15]

Points = np.array(list(itertools.product(Xpts, Ypts)))

这将返回以下内容:
array([[ 5,  5],
       [ 5, 10],
       [ 5, 15],
       [10,  5],
       [10, 10],
       [10, 15],
       [15,  5],
       [15, 10],
       [15, 15],
       [20,  5],
       [20, 10],
       [20, 15],
       [25,  5],
       [25, 10],
       [25, 15],
       [30,  5],
       [30, 10],
       [30, 15],
       [35,  5],
       [35, 10],
       [35, 15]])

这在纯Python中运行,可能会更慢。 - qwr

3

人们已经建议使用numpy.mgrid和itertools。 使用它们。

然而,为了教育的目的,Python为我们提供了一个强大的概念,称为“列表推导式”。 您可以通过运行以下命令获得笛卡尔积:

[(a,b) for a in range(5, 485, 5) for b in range(5, 645, 5)]

如果你不想要一个元组列表,可以将(a,b)更改为[a,b]


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