使用 numpy.roll 在特殊位置移动数组
Shifting an array in a special location using numpy.roll
我有一个 256x256 数组,我想使用特殊的行和列向右移动。我正在使用 numpy.roll 来实现它。如果我使用下面的代码,移位是向右一列。
import cv2
import matplotlib.pyplot as plt
import numpy as np
# Input (256x256 0 values array)
array = np.zeros((256,256))
# Draw a square inside the array (1 values)
array[100:156,100:156] = 1
# Shift the square to the right (1 as shift value)
shifted_array = np.roll(array,1)
如果我无限重复这个过程,它会在数组的整个宽度(256 列)上移动,然后重新启动。我想要做的是将数组从第 120 列移动到第 130 列。这意味着最大移动是 10 列(而不是以前的 256 列)。我怎样才能做到这一点?
[已解决] 最后,我找到了使用以下代码实现该目标的方法:
import cv2
import matplotlib.pyplot as plt
import numpy as np
# Input (256x256 0 values array)
array = np.zeros((256,256))
# Draw a square inside the array (1 values)
array[100:156,100:156] = 1
# Cropping the image between columns 120 and 130
cropped_image = array[:,120:130]
# Loop to shift the image every column and get the original dimensions
i = 1
shift_value = 1
while i < len(cropped_image):
shifted_array = np.roll(cropped_image, shift_value)
shift_value = shift_value + 1
i = i + 1
new_array = np.zeros(array.shape)
new_array[:,120:130] = shifted_array
上面的 while
循环没有做任何事情。 array
永远不会改变它的状态,所以只有最后一次迭代保存在 shifted_array 中。下面使用较小的数组来查看结果。
import numpy as np
arr = np.zeros((12,12), dtype=np.int)
arr[ 4:8, 6:10] = 1
arr
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
crop = np.s_[:, 5:11] # crop is the selection to roll.
new_array = np.zeros_like(arr)
new_array[crop] = np.roll(arr[crop], len(arr)-1)
new_array
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
这具有将正方形向下移动两行并向左移动一列的效果。
根据您要实现的目标,最好探索使用轴参数 np.roll(arr, 1, axis=1)
显式滚动 left/right 和/或 axis=0
滚动 up/down.
谢谢克里斯。
确实,这不是预期的结果,但我只是需要移动方块。
我的目标是比较两个图像(imageA 有一个居中的正方形,imageB 有一个移动的正方形)并移动 imageB 的正方形以匹配 imageA 的正方形。
为了检测匹配位置,我使用快速傅立叶变换 (FFT),如下所示。然后,我计算两个结果图像之间的差异。如果差异等于0,则找到匹配位置。所以我成功地使用下面的代码找到了它。
import cv2
import matplotlib.pyplot as plt
import numpy as np
img1 = np.zeros((256,256))
img1[100:156,100:156] = 1
img2 = np.zeros(img1.shape)
img2[50:255, 50:255] = img1[:205,:205]
f = np.fft.fft2(img1)
fshift1 = np.fft.fftshift(f)
f = np.fft.fft2(img2)
fshift2 = np.fft.fftshift(f)
cropped_image = img2[90:220, 90:220]
i = 0
shift_value = 1
min_diff = 1000000000
while i < np.size(cropped_image):
img3 = np.roll(cropped_image, shift_value)
shift_value = shift_value + 1
img4 = np.zeros(img1.shape)
img4[90:220, 90:220] = img3
f = np.fft.fft2(img4)
fshift3 = np.fft.fftshift(f)
real_value = np.sum(np.abs(np.real(fshift1) - np.real(fshift3)))
if min_diff > real_value:
min_diff = real_value
print(i)
i = i + 1
print(min_diff)
我有一个 256x256 数组,我想使用特殊的行和列向右移动。我正在使用 numpy.roll 来实现它。如果我使用下面的代码,移位是向右一列。
import cv2
import matplotlib.pyplot as plt
import numpy as np
# Input (256x256 0 values array)
array = np.zeros((256,256))
# Draw a square inside the array (1 values)
array[100:156,100:156] = 1
# Shift the square to the right (1 as shift value)
shifted_array = np.roll(array,1)
如果我无限重复这个过程,它会在数组的整个宽度(256 列)上移动,然后重新启动。我想要做的是将数组从第 120 列移动到第 130 列。这意味着最大移动是 10 列(而不是以前的 256 列)。我怎样才能做到这一点?
[已解决] 最后,我找到了使用以下代码实现该目标的方法:
import cv2
import matplotlib.pyplot as plt
import numpy as np
# Input (256x256 0 values array)
array = np.zeros((256,256))
# Draw a square inside the array (1 values)
array[100:156,100:156] = 1
# Cropping the image between columns 120 and 130
cropped_image = array[:,120:130]
# Loop to shift the image every column and get the original dimensions
i = 1
shift_value = 1
while i < len(cropped_image):
shifted_array = np.roll(cropped_image, shift_value)
shift_value = shift_value + 1
i = i + 1
new_array = np.zeros(array.shape)
new_array[:,120:130] = shifted_array
上面的 while
循环没有做任何事情。 array
永远不会改变它的状态,所以只有最后一次迭代保存在 shifted_array 中。下面使用较小的数组来查看结果。
import numpy as np
arr = np.zeros((12,12), dtype=np.int)
arr[ 4:8, 6:10] = 1
arr
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
crop = np.s_[:, 5:11] # crop is the selection to roll.
new_array = np.zeros_like(arr)
new_array[crop] = np.roll(arr[crop], len(arr)-1)
new_array
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
这具有将正方形向下移动两行并向左移动一列的效果。
根据您要实现的目标,最好探索使用轴参数 np.roll(arr, 1, axis=1)
显式滚动 left/right 和/或 axis=0
滚动 up/down.
谢谢克里斯。
确实,这不是预期的结果,但我只是需要移动方块。 我的目标是比较两个图像(imageA 有一个居中的正方形,imageB 有一个移动的正方形)并移动 imageB 的正方形以匹配 imageA 的正方形。
为了检测匹配位置,我使用快速傅立叶变换 (FFT),如下所示。然后,我计算两个结果图像之间的差异。如果差异等于0,则找到匹配位置。所以我成功地使用下面的代码找到了它。
import cv2
import matplotlib.pyplot as plt
import numpy as np
img1 = np.zeros((256,256))
img1[100:156,100:156] = 1
img2 = np.zeros(img1.shape)
img2[50:255, 50:255] = img1[:205,:205]
f = np.fft.fft2(img1)
fshift1 = np.fft.fftshift(f)
f = np.fft.fft2(img2)
fshift2 = np.fft.fftshift(f)
cropped_image = img2[90:220, 90:220]
i = 0
shift_value = 1
min_diff = 1000000000
while i < np.size(cropped_image):
img3 = np.roll(cropped_image, shift_value)
shift_value = shift_value + 1
img4 = np.zeros(img1.shape)
img4[90:220, 90:220] = img3
f = np.fft.fft2(img4)
fshift3 = np.fft.fftshift(f)
real_value = np.sum(np.abs(np.real(fshift1) - np.real(fshift3)))
if min_diff > real_value:
min_diff = real_value
print(i)
i = i + 1
print(min_diff)