对指定像素执行不同的邻域操作

时间:2020-08-02 11:52:36

标签: python arrays numpy opencv pytorch

我有一个HxW“功能图” F。让我们假设它是一个HxWx1映射。通过其他操作,我得到了一组我感兴趣的像素(例如N个像素)。这些像素中的每个像素都具有不同的值,因此我的集合的格式为Nx3,其中每个像素的格式为xyval。请注意,此val与该位置的要素地图值不同。

这是我的问题。是否可以对这些点中的每一个进行邻域运算矢量化?对于n中的每个像素N,我希望将对应的val乘以其在特征图F中的3x3邻域。对于3x3社区,这给出了一组3x3的新元素new val。我想在3x3窗口中将x y替换为最大new val(乘以特征图)的像素。

这听起来像是卷积运算(此处是术语的轻微滥用),其后是最大池运算,但不完全是因为每个像素位置的乘积值不同。

输入和输出示例,以及所需解决方案的演练

让我们假设H = 10W = 10

这是样本F

0.635955  0.922379  0.993406  0.007837  0.818661  0.983730  0.199866  0.757519  0.073152  0.015831
0.397718  0.097353  0.231351  0.177886  0.343099  0.419940  0.017342  0.087294  0.402266  0.366337
0.978686  0.476594  0.067836  0.148977  0.058994  0.810586  0.542894  0.797419  0.386559  0.225982
0.479860  0.033354  0.353366  0.431562  0.336208  0.674272  0.398151  0.713732  0.598623  0.829230
0.940838  0.869564  0.287100  0.669844  0.631836  0.748982  0.762292  0.597999  0.540236  0.758802
0.925995  0.141296  0.466772  0.672663  0.929746  0.544029  0.991860  0.197474  0.762866  0.798973
0.543519  0.128332  0.624323  0.876569  0.050709  0.223705  0.708381  0.380842  0.818092  0.163447
0.283125  0.329618  0.283481  0.672950  0.136922  0.897785  0.385479  0.764824  0.132671  0.091148
0.661984  0.369459  0.501181  0.352681  0.554113  0.133283  0.593048  0.108534  0.397813  0.836065
0.654929  0.928576  0.539204  0.931213  0.344114  0.591214  0.126809  0.456681  0.036531  0.725228

我的像素结构,让我们说N = 3 这三个值按row,col,val的顺序排列:(为简单起见,我假设x是行,而y是cols,尽管不一定是这种情况)。 这完全独立于上一步中的特征图。

3,2,0.38
4,4,0.602
7,5,0.9647

(3,2)附近的邻居是:

[[0.4765941 , 0.06783561, 0.14897662],
[0.03335438, 0.35336647, 0.4315618 ],
[0.86956374, 0.28709952, 0.66984412]]

因此val *邻域收益率。 (此处val为0.38)

[[0.18110576, 0.02577753, 0.05661112],
[0.01267466, 0.13427926, 0.16399349],
[0.33043422, 0.10909782, 0.25454077]]

此处最大值的位置是(2,0),即相对于中心像素为(1,-1)。因此,我更新后的(x,y)应该是(3,2) + (1,-1) = (4,1)。 与其他两个像素类似,更新后的像素为:(5,4)(7,5)

如何并行处理整个过程? (希望可以使用Pytorch加载到GPU上,但不一定,我还没有进入那个阶段。)

注意:我几天前曾问过这个问题,但是没有适当的信息,框架设计得很糟糕。希望这可以解决问题。

编辑:对于此特定实例,可以将F生成为随机数组:

F = np.random.rand(10,10)

1 个答案:

答案 0 :(得分:3)

如果我理解正确,那么您想要这样做:

from skimage.util.shape import view_as_windows
idx = pixels[:,0:2].astype(int)
print((np.unravel_index((view_as_windows(F,(3,3))[tuple(idx.T-1)]*pixels[:,-1][:,None,None]).reshape(-1,9).argmax(1),(3,3))+idx.T).T-1)
#if you need to replace the values of F with new values
F[tuple(idx.T)] = (view_as_windows(F,(3,3))[tuple(idx.T-1)]*pixels[:,-1][:,None,None]).reshape(-1,9).max(1)

我假设您的窗口形状为(3,3)。当然,您可以更改它。而且,如果您需要处理边缘邻域,则在使用F之前,请使用np.padview_as_windows填充[[4 1] [5 4] [7 5]] 足够的0(取决于您的窗口大小)。

输出:

{{1}}