我正在对图像进行腐蚀。图像已相应填充。 简而言之,我将一个cross元素(+)放在图像的每个像素上,并从上,下,右,左及其本身的像素中选取该像素的最小值。
效率低下,我想不出矢量化版本。由于所有计算都是彼此独立进行的,因此必须有可能。
for y in range(t,image.shape[0]-b):
for x in range(l,image.shape[1]-r):
a1 = numpy.copy(str_ele)
for filter_y in range(a1.shape[0]):
for filter_x in range(a1.shape[1]):
if (not (numpy.isnan(a1[filter_y][filter_x]))):
a1[filter_y][filter_x] = str_ele[filter_y][filter_x]*image[y+(filter_y-str_ele_center_y)][x+(filter_x-str_ele_center_x)]
eroded_image[y][x] = numpy.nanmin(a1)
基本上:
最终图像中的每个像素=距原始图像的最小值(上,下,左,右)像素
for y in range(len(eroded_image)):
for x in range(len(eroded_image[1])):
eroded_image2[y][x] = numpy.nanmin(str_ele*image2[y:y+len(str_ele),x:x+(len(str_ele[1]))])
这就是我现在拥有的。还有2个循环。
答案 0 :(得分:2)
如果image
是一个填充了NaN的数组,并且您的十字形脚印正在侵蚀,
您可以通过堆叠image
的切片来删除for循环(以有效地向上,向左,向右和向下移动图像)
然后将np.nanmin
应用于切片堆栈。
import numpy as np
def orig(image):
t, l, b, r = 1, 1, 1, 1
str_ele = np.array([[np.nan, 1, np.nan], [1, 1, 1], [np.nan, 1, np.nan]], dtype='float')
str_ele_center_x, str_ele_center_y = 1, 1
eroded_image = np.full_like(image, dtype='float', fill_value=np.nan)
for y in range(t,image.shape[0]-b):
for x in range(l,image.shape[1]-r):
a1 = np.copy(str_ele)
for filter_y in range(a1.shape[0]):
for filter_x in range(a1.shape[1]):
if (not (np.isnan(a1[filter_y][filter_x]))):
a1[filter_y][filter_x] = str_ele[filter_y][filter_x]*image[y+(filter_y-str_ele_center_y)][x+(filter_x-str_ele_center_x)]
eroded_image[y][x] = np.nanmin(a1)
return eroded_image
def erode(image):
result = np.stack([image[1:-1, 1:-1], image[2:, 1:-1], image[:-2, 1:-1], image[1:-1, 2:], image[1:-1, :-2]])
eroded_image = np.full_like(image, dtype='float', fill_value=np.nan)
eroded_image[1:-1, 1:-1] = np.nanmin(result, axis=0)
return eroded_image
image = np.arange(24).reshape(4,6)
image = np.pad(image.astype(float), 1, mode='constant', constant_values=np.nan)
收益
In [228]: erode(image)
Out[228]:
array([[nan, nan, nan, nan, nan, nan, nan, nan],
[nan, 0., 0., 1., 2., 3., 4., nan],
[nan, 0., 1., 2., 3., 4., 5., nan],
[nan, 6., 7., 8., 9., 10., 11., nan],
[nan, 12., 13., 14., 15., 16., 17., nan],
[nan, nan, nan, nan, nan, nan, nan, nan]])
对于上面的小示例image
,erode
的运行速度似乎比orig
快33倍:
In [23]: %timeit erode(image)
10000 loops, best of 3: 35.6 µs per loop
In [24]: %timeit orig(image)
1000 loops, best of 3: 1.19 ms per loop
In [25]: 1190/35.6
Out[25]: 33.42696629213483