有效地集中和叠加numpy阵列

2024-10-05 14:21:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个三维uint8numpy数组表示的RGBA图像数据。我想把其中一个(image)放在另一个(canvas)的中心。image的宽度和高度通常会小于canvas的相应尺寸,但它们可能会更大——在这种情况下,将使用image的中心部分,并将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包含一些功能时,我不会感到惊讶,这些功能的名称我还没猜出来,但它们可以在一行中完成。。。你知道吗


Tags: imageifis情况math中心intcanvas
1条回答
网友
1楼 · 发布于 2024-10-05 14:21:56

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

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))

现在让我们来测试一下:

image = np.ones((3, 7, 4))
canvas = np.zeros((5, 5, 4))

ind_can, ind_im = get_slices_ND(canvas.shape, image.shape)
canvas[ind_can] = image[ind_im]

canvas[:, :, 0]
# array([[ 0.,  0.,  0.,  0.,  0.],
#        [ 1.,  1.,  1.,  1.,  1.],
#        [ 1.,  1.,  1.,  1.,  1.],
#        [ 1.,  1.,  1.,  1.,  1.],
#        [ 0.,  0.,  0.,  0.,  0.]])

作为奖励,这种方法可以推广到任意维数的数组!你知道吗

相关问题 更多 >