I have an image in a numpy array and I want to take the slice in red.
I expect the output to look like this.
Imagine the shape is [600,800,3]
I've tried img[200:400,400:900,:]
the 900 being higher than the limit hoping it would wrap around but no.
I know i could also take it as two slices and then hstack them, but i cant help think there is a better way?
Its also possible that the slice could overrun horizontally or vertically or both.
Any suggestions?
You could use np.roll()
, which does a cyclic permutation / cyclic shift, along the specified axis (or axes)
If the shift happens along just axis1, use:
new_img = np.roll (img, split, axis=1)
where split
is the col value at which your image is to be split. The effect of this cyclic shift is exactly as though the image had been split at the specified point on the axis, and the two resulting image-parts have been swapped.
Since you require to shift along axis1, and simultaneously slice along axis0, it would be:
new_img = np.roll (img[low:high,...], split, axis=[0,1])
where low
and high
are appropriate slice boundaries along axis0.
If a shift can happen along both axes simultaneously (and there is on slicing), it would be:
new_img = np.roll (img, [split_0, split_1], axis=[0,1])
where split_0
is the split point along axis0 and split_1
is the split point along axis1
Note: Somewhat surprisingly, instead of returning a view, roll()
returns a copy , which means it may not give much of a speed-advantage, compared to stacking / concatenating.
Try this out:
the_red_slice = np.tile(img, (1, 2, 1))[200:400,400:900,:]
The tile
should duplicate the image at the second dimension so you can index into it. The red area should not be greater than the image width to this solution to work. see: numpy docs: tile
Note: Reason for posting this additional answer:
I realized a little late, that, viewing this problem purely as a "shifting" problem isn't fully meeting the requirement, because, after the shift, the length of the image along the shifted axis remains the same as before, while the requirement is that along axis1, both shifting and slicing needs to happen.
Let:
L_0
be the length of the image along axis0 (in your example, 600
) L_1
be the length of the image along axis1 (in your example, 800
) low_0:high_0
be the required slice along axis0 (in your example, this is probably 200:500
) low_1:high_1
be the required slice along axis1 (in your example, this was 200:900
) Solution:
# Re-compute slice-lengths, slice-starts, for both axes
len_0 = (high_0 - low_0) % L_0 # slice-length for axis0
len_1 = (high_1 - low_1) % L_1 # slice-length for axis1
low_0 = (low_0 % L_0)
low_1 = (low_1 % L_1)
new_img = np.roll(img, [-1 * low_0, -1 * low_1], axis=(0,1)) [:len_0, :len_1, :]
Explanation:
What we are essentially doing is the following steps:
len_0
, len_1
)low_0
(the -1
means upwards)low_1
(the -1
means leftwards):len_0
along axis0, and the slice :len_1
along axis1, and the full slice :
for axis2
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.