有效地居中和叠加numpy数组

时间:2015-11-18 21:31:13

标签: python arrays numpy

我有两个三维uint8 numpy数组表示的RGBA图像数据。我想将其中一个(image)置于另一个(canvas)中。 image的宽度和高度通常会小于canvas的相应尺寸,但可能更大 - 在这种情况下,{image的中心部分将使用1}}并将完全模糊canvas。在所有情况下,输出将是canvas的大小和形状。

我可以毫无错误地做到这一点,但我很惊讶代码最终是多么奇怪的怪异:

h, w = canvas.shape[ :2 ]    # canvas.shape is [ h, w, 4 ] because it is an RGBA image
ih, iw = image.shape[ :2 ]   # image.shape is [ ih, iw, 4 ] because it is an RGBA image
xoffset = ( w - iw ) / 2.0
yoffset = ( h - ih ) / 2.0
xoffset = [ int( math.ceil( xoffset ) ), int( math.floor( xoffset ) ) ] # how much free space left and right
yoffset = [ int( math.ceil( yoffset ) ), int( math.floor( yoffset ) ) ] # how much free space top and bottom
if xoffset[ 0 ] < 0:
    image = image[ :, -xoffset[ 0 ]:, : ]
    iw += xoffset[ 0 ]
    xoffset[ 0 ] = 0
if xoffset[ 1 ] < 0:
    image = image[ :, :xoffset[ 1 ],  : ]
    iw += xoffset[ 1 ]
    xoffset[ 1 ] = 0
if yoffset[ 0 ] < 0:
    image = image[ -yoffset[ 0 ]:, :, : ]
    ih += yoffset[ 0 ]
    yoffset[ 0 ] = 0
if yoffset[ 1 ] < 0:
    image = image[ :yoffset[ 1 ],  :, : ]
    ih += yoffset[ 1 ]
    yoffset[ 1 ] = 0
canvas[ yoffset[ 0 ]:yoffset[ 0 ] + ih, xoffset[ 0 ]:xoffset[ 0 ] + iw, : ] = image

您能看到更优雅/可读/可维护的方式吗?必须有一个比我更好的解决方案。我不会惊讶地发现numpy包含了一些我尚未能够猜到的功能,但可以在一行中完成...

1 个答案:

答案 0 :(得分:3)

我认为你可以通过认识到每个维度的逻辑相同来简化这一过程,因此你可以编写一个函数来处理每个维度并输出相应的数组切片。然后在两个维度上调用它并将切片应用于数组。例如:

NSManagedObjectContext

现在让我们测试一下:

import numpy as np

def get_slices_1D(canvas_size, image_size):
    buffer = abs(canvas_size - image_size) // 2
    if canvas_size > image_size:
        return slice(buffer, buffer + image_size), slice(None)
    else:
        return slice(None), slice(buffer, buffer + canvas_size)

def get_slices_ND(canvas_shape, image_shape):
    pairs = zip(canvas_shape, image_shape)
    return zip(*(get_slices_1D(*pair) for pair in pairs))

作为奖励,这种方法可以推广到任意数量的数组!