【问题标题】:Slicing different parts of numpy array切片numpy数组的不同部分
【发布时间】:2020-09-24 00:45:42
【问题描述】:

我正在导入图像并将它们转换为 numpy 数组。我想分析它们,但它们对于我程序的下一步来说太大了。输入图像为 640 x 480,我正在分析 400x400。我想裁剪这些图像的部分而不是调整大小,这样我就不会丢失任何细节。我想在整个图像上创建分析大小为 400x400 的“蒙版”。 例如,这张图片中应该有 4 个蒙版

0:400,0:400
0:400,80:480
240:640,0:400
240:640:80:480

我当前的代码是这样的: frame 是图像的 numpy 数组

frmwidth = frame.shape[0]
frmheight = frame.shape[1]
# print(frmwidth)
# print(frmheight)
res_width, res_height = 400,400

number_width = math.ceil(frmwidth/res_width)
number_height = math.ceil(frmheight/res_height)
iter = max(number_width, number_height)
print(number_width)
print(number_height)


print('\n\nBOUNDS')
topbound = 0
for i in range(number_width):
    leftbound = 0

    for j in range(number_height):
        if leftbound == 0 and topbound == 0:
            rightbound = leftbound + 400
            print('width')
            print(leftbound)
            print(rightbound)
            leftbound = rightbound

            bottombound = topbound+400
            print('heigth')
            print(topbound)
            print(bottombound)
            topbound = bottombound

        elif leftbound == 0 and topbound != 0:
            rightbound = leftbound + 400
            print('width')
            print(leftbound)
            print(rightbound)
            leftbound = rightbound

            topbound = topbound - ((res_height*number_height)-frmheight)/(number_height-1)
            bottombound = topbound+400
            print('height')
            print(topbound)
            print(bottombound)

        elif topbound == 0 and leftbound != 0:
            leftbound = leftbound - ((res_width*number_width)-frmwidth)/(number_width-1)
            rightbound = leftbound+400
            print('width')
            print(leftbound)
            print(rightbound)
            bottombound = topbound+400

            print('heigth')
            print(topbound)
            print(bottombound)
            topbound = bottombound
        else:
            leftbound = leftbound - ((res_width*number_width)-frmwidth)/(number_width-1)
            rightbound = leftbound+400
            print('width')
            print(leftbound)
            print(rightbound)

            topbound = topbound - ((res_height*number_height)-frmheight)/(number_height-1)
            bottombound = topbound+400
            print('height')
            print(topbound)
            print(bottombound)

我已将 leftbound=0rightbound=0 移入和移出 for 循环。这是我得到的最接近 3/4 的“面具”正确。

BOUNDS
width
0
400
heigth
0
400
width
80.0
480.0
height
240.0
640.0
width
0
400
height
80.0
480.0
width
80.0
480.0
height
-80.0
320.0

我为所有的印刷声明道歉,它让一切井井有条

这部分(res_width*number_width)-frmwidth)/(number_width-1) 计算每个作物与前一个作物的重叠程度。

【问题讨论】:

  • 640x480 太大了怎么办?弄清楚 那个 可能更容易和更健壮。此外,如果您有 400x400 的 640x480 部分,为什么还需要图像的其余部分?你能指定 4 个子部分吗?目前尚不清楚您要做什么。
  • 它总是固定大小和窗口吗?如果是这样,为什么不使用硬编码 4 子图像?
  • 您的代码的实际问题是什么?您期望的确切输入和输出是什么?
  • @asylumax 我将它们输入到输入大小为 400x400 的卷积神经网络中。
  • 你说你想概括,但我不知道你提出的一般解决方案是什么,或者为什么它不起作用。

标签: python arrays numpy image-processing numpy-ndarray


【解决方案1】:

这不能回答您的问题吗? (如果尺寸和切口始终相同):

sub_img1 = frame[0:400,0:400]
sub_img2 = frame[0:400,80:480]
sub_img3 = frame[240:640,0:400]
sub_img4 = frame[240:640:80:480]

有时简单的硬编码比概括情况更容易。

编辑:对于一般情况,此代码为您提供图像窗口数组:

from skimage.util.shape import view_as_windows
window_shape = (400,400)
step = 400
B1 = view_as_windows(frame, window_shape, step)
B2 = view_as_windows(frame[-window_shape[0]:,:], window_shape, step)
B3 = view_as_windows(frame[:,-window_shape[1]:], window_shape, step)
B4 = view_as_windows(frame[-window_shape[0]:,-window_shape[1]:], window_shape, step)
arr_sub_images = np.vstack((B1.reshape(-1,*window_shape),B2.reshape(-1,*window_shape),B3.reshape(-1,*window_shape),B4.reshape(-1,*window_shape)))

【讨论】:

  • 这将是一个快速的解决方案,但我希望能够灵活地处理多种尺寸的图像,始终采用 400x400 切片
  • 因此,您可能有一个 1280x960 的图像,并且您想将其分解为 400x400 的块,然后进行概括。由于 400x400 可能不适合,您可以尽可能多次平铺图像,对于最后一个元素,您从最大尺寸重叠。如果这是正确的,那么第一个“整数”平铺很容易,您可以从最大值开始工作。或者,您是否必须为 each 图像重叠?在一维中;如果你从 0 到 1279,你想要 0-399,400-799 等还是需要 0-399、399-重叠、700-重叠等?试图在这里找到一般情况,不清楚。
  • 任何一种方法都对我有用,只要覆盖整个图像。对于您的一维示例,我的方法将执行 1-400、293-693、589-986,879-1279。在这种情况下,它们同样重叠。但是,如果这样做更容易,执行 1-400,400-800,800-1200,879-1279 也可以。
  • @theastronomist 请在帖子上找到我对一般情况的编辑。如果这回答了您的问题,请继续并接受答案以关闭问题。谢谢。
【解决方案2】:

我想出了一个使用np.linspace 的解决方案。 linspace 找到每个裁剪的中心点,然后我针对 x 和 y 轴中的每一个遍历 linspace 并将它们用作组合来获取位置。然后我们加或减 200(在本例中为 400x400 裁剪)得到裁剪。

frmwidth = frame.shape[0]
frmheight = frame.shape[1]
print(frame.shape)
res_width, res_height = 400,400

number_width = math.ceil(frmwidth/res_width)
number_height = math.ceil(frmheight/res_height)
iter = max(number_width, number_height)

y_centers = np.linspace((res_height/2), (frmheight-(res_height/2)), math.ceil(frmheight/res_height))
x_centers = np.linspace((res_width/2), (frmwidth-(res_width/2)), math.ceil(frmwidth/res_width))
for i in y_centers:
    for j in x_centers:
        i = int(i)
        j = int(j)
        topbound = i-200
        bottombound = i+200
        leftbound = j-200
        rightbound = j+200
        frame = frame[i-200:i+200,j-200:j+200]

【讨论】:

  • 出了什么问题?请注意,它会返回您需要的子图像数组。
  • 该解决方案仅适用于需要 4 种作物的情况。有人帮我找到并在此处发布的解决方案适用于任何数量的作物
  • 添加的编辑适用于任意数量的作物,无需使用任何循环。请随意查看。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 2015-08-12
  • 2017-03-06
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
相关资源
最近更新 更多