我使用栅格图像和模块rasterio
将其实现为numpy
阵列。我想从每个图像的中间切出(1000, 1000)
大小的一部分(以避免图像的边界超出范围)。
image = np.random.random_sample((2000, 2000))
s = image.shape
mid = [round(x / 2) for x in s] # middle point of both axes
margins = [[y + x for y in [-500, 500]] for x in mid] # 1000 range around every middle point
结果是2个列表的清单,每个轴的切割范围。但这就是我的绊脚石:range()
不接受列表,我正在尝试以下暴力破解方法:
cut_image = image[range(margins[0][0], margins[0][1]), range(margins[1][0], margins[1][1])]
但是:
cut_image.shape
## (1000,)
切片数组会丢失尺寸信息,而这正是我所不想要的。 考虑到我感到困惑。 寻找更具品味的解决方案。
答案 0 :(得分:1)
这里的问题是您正在做的事情被称为整数索引,而不是切片索引。行为会发生变化,如果不熟悉,可能会违反直觉。您可以检查docs以获得更多详细信息。
以下是使用基本切片的方法:
# center coordinates of the image
x_0, y_0 = np.asarray(image.shape)//2
# slice taken from the center point
out = image[x_0-x_0//2:x_0+x_0//2, y_0-y_0//2:y_0+y_0//2]
print(out.shape)
# (1000, 1000)
答案 1 :(得分:1)
正如其他答案指出的那样,您不是真正对数组进行切片,而是对它进行索引。
如果您想对数组进行切片(对的话,这比使用索引列表更为优雅),您将对切片更加满意。这些对象代表start:end:step
语法。
就您而言,
import numpy as np
WND = 50
image = np.random.random_sample((200, 300))
s = image.shape
mid = [round(x / 2) for x in s] # middle point of both axes
margins = [[y + x for y in [-WND, WND]] for x in mid] # 1000 range around every middle point
# array[slice(start, end)] -> array[start:end]
x_slice = slice(margins[0][0], margins[0][1])
y_slice = slice(margins[1][0], margins[1][1])
print(x_slice, y_slice)
# slice(50, 150, None) slice(100, 200, None)
cut_image = image[x_slice, y_slice]
print(cut_image.shape)
# (100,100)
您可能想知道问题中发生了什么,导致仅1000个元素,而不是预期的1000 * 1000。
这是使用不同维度的列表建立索引的简单示例
# n and n2 have identical values
n = a[[i0, i1, i2],[j0, j1, j2]]
n2 = np.array([a[i0, j0], a[i1, j1], a[i2, j2]]
需要澄清的是,您将了解,您的代码仅返回该块矩阵的对角系数,而不是使用块矩阵:)