计算numpy数组的边界框

6

我很困惑一个简单的问题。我有一个形式为numpy数组的:

[[[ 1152.07507324   430.84799194]
  [ 4107.82910156   413.95199585]
  [ 4127.64941406  2872.32006836]
  [ 1191.71643066  2906.11206055]]]

我希望计算边界框,也就是说,我想要左上角、右上角、右下角和左下角的点。

以下应该是正确的解决方案

[[[ 1152.07507324   413.95199585]
  [ 4127.64941406   413.95199585]
  [ 4127.64941406  2906.11206055]
  [ 1152.07507324  2906.11206055]]]

我写了一个能完成任务的函数,但我对它不太满意,因为它不是很符合Python/Numpy的风格。
def bounding_box(iterable):
    minimum_x = min(iterable[0], key=lambda x:x[0])[0]
    maximum_x = max(iterable[0], key=lambda x:x[0])[0]
    minimum_y = min(iterable[0], key=lambda x:x[1])[1]
    maximum_y = max(iterable[0], key=lambda x:x[1])[1]

    return numpy.array([[(minimum_x, minimum_y), (maximum_x, minimum_y), (maximum_x, maximum_y), (minimum_x, maximum_y)]], dtype=numpy.float32)

你有没有想过如何优化上述函数,例如使用numpy内置功能?


1
你的示例数组为什么有三层方括号?这使它看起来像一个形状为(1,n,2)的三维数组。这是有意为之吗? - Warren Weckesser
2个回答

11

使用内置的 numpy.minnumpy.max:

def bounding_box(iterable):
    min_x, min_y = numpy.min(iterable[0], axis=0)
    max_x, max_y = numpy.max(iterable[0], axis=0)
    return numpy.array([(min_x, min_y), (max_x, min_y), (max_x, max_y), (min_x, max_y)])

Argv。我正在研究一种更简短的技巧来获取结果的笛卡尔积,但基本思路是相同的。 - DSM
itertools.product?唯一的问题是它给出的答案顺序错误。 - nneonneo
但是如果你能克服这个问题,仍然有短小的代码,请务必发布。我很好奇 :) - nneonneo
我在考虑像 c = np.array([b.min(0), b.max(0)]); list(np.broadcast(*np.ix_(*c.T))) 这样的东西,但第二部分太聪明了,而且顺序也不对。我更愿意像你和OP一样手动操作,这样结果就能立即明显地呈现出来。 - DSM
1
为了让自己少些麻烦,你可以(1)将iterable转换成一个二维数组iterable=iterable.squeeze(),(2)使用.min/.max方法代替np.min/np.max函数。否则,加一分。 - Pierre GM

3
返回与之前答案相同但更简洁的结果。
返回2*2的ndarray。
def bbox(points):
    """
    [xmin xmax]
    [ymin ymax]
    """
    a = zeros((2,2))
    a[:,0] = np.min(points, axis=0)
    a[:,1] = np.max(points, axis=0)
    return a

3
考虑添加一些文本到你的答案中,解释你在这里做什么以及这与已经被接受的答案有何不同。仅仅是代码块的答案并不是很有用。 - Ryan Bemrose

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