简体   繁体   English

过滤二维数组并从中间返回坐标

[英]Filter 2D array and return co-ordinates from intermediate

I have a 2D array of zeros with some positive integers at (1,6) and (2,7):我有一个二维零数组,在 (1,6) 和 (2,7) 处有一些正整数:

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 2. 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.]]

And I want to filter the array by a custom kernel:我想通过自定义 kernel 过滤数组:

[[1 0 1]
 [0 1 0]
 [0 1 0]]

I want to filter the array with this kernel and when 2 or 3 of the ones in this kernel are multiplied by a positive integer, I want it to return the co-ordinates of the ones that were multiplied by 0.我想用这个 kernel 过滤数组,当这个 kernel 中的 2 或 3 个乘以正 integer 时,我希望它乘以坐标的乘积。

I know from image analysis that it's easy to convolve a 2D array by a kernel but it doesn't yield the intermediate results.我从图像分析中知道,很容易用 kernel 对二维数组进行卷积,但它不会产生中间结果。 On the above 2D array, it would return (1,8) and (3,7).在上述二维数组上,它将返回 (1,8) 和 (3,7)。

Is there some package functions that I can use to make this process simple and easy, or will I have to implement it myself?是否有一些 package 函数可以用来简化此过程,还是我必须自己实现? As always, all help is appreciated一如既往,感谢所有帮助

This is a numpy implementation of it to start with.这是一个 numpy 实现开始。 You can increase performance probably by modifying it.您可以通过修改它来提高性能。

Here, num_ones is the lower and upper number of ones in the kernel you would like to filter, referring to when 2 or 3 of the ones in this kernel are multiplied by a positive integer此处, num_ones是您要过滤的 kernel 中的下限和上限数,指的是当此 kernel 中的 2 或 3 个乘以正 Z157DB7DF530023575E8ZB27 时

a = np.array([[0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.],
 [0.,0.,0.,0.,0.,0.,2.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.],
 [0.,0.,0.,0.,0.,0.,0.,2.,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.]])

kernel = np.array([[1.,0.,1.],\
 [0.,1.,0.],\
 [0.,1.,0.]])

sub_shape = kernel.shape
#throshold of number of kernel ones to have non-zero value
num_ones = [2,3]

#divide the matrix into sub_matrices of kernel size
view_shape = tuple(np.subtract(a.shape, sub_shape) + 1) + sub_shape
strides = a.strides + a.strides
sub_matrices = np.lib.stride_tricks.as_strided(a,view_shape,strides)
#convert non_zero elements to 1 (dummy representation)
sub_matrices[sub_matrices>0.] = 1.

#Do convolution
m = np.einsum('ij,klij->kl',kernel,sub_matrices)

#find sub_matrices that satisfy non-zero elements' condition
filt = np.argwhere(np.logical_and(m>=num_ones[0], m<=num_ones[1]))
#for each sub_matix find the zero elements located in non-zero elements of kernel
output = []
for [i,j] in filt:
  output.append(np.argwhere((sub_matrices[i,j,:,:]==0)*kernel) + [i, j])

output is an array of indices arrays where each array is indices where your condition is met per kernel application in each location [i,j] of your image. output 是一个索引数组 arrays ,其中每个数组是每个 kernel 应用程序在图像的每个位置[i,j]中满足您的条件的索引。 If you wish to aggregate them all, you can stack all arrays and take a unique list of it.如果您希望将它们全部聚合,您可以堆叠所有 arrays 并获取它的唯一列表。 I am not sure how you would like the output be in case of multiple occurrences.我不确定您希望 output 在多次出现的情况下如何。

output: output:

output =
[[1 8]
 [3 7]] 

UPDATE: regarding einsum:更新:关于 einsum:

I would recommend this post about einsum to learn: Understanding NumPy's einsum我会推荐这篇关于 einsum 的帖子来学习: Understanding NumPy's einsum

sub_matrices is a 4-dimensional array. sub_matrices是一个 4 维数组。 sub_matrices[k,l,:,:] is sub matrix of a starting at position [k,l] and shape of kernel. sub_matrices[k,l,:,:] a从 position [k,l]和形状 kernel 开始的子矩阵。 (later we changed all non-zero values of it to 1 for our purpose) (后来为了我们的目的,我们将它的所有非零值更改为 1)

m = np.einsum('ij,klij->kl',kernel,sub_matrices) multiplies two dimensions i and j of kernel into last two dimensions i and j of sub_matrices array (in other words, it element-wise multiplies kernel to sub matrices sub_matrices[k,l,:,:] ) and sums all elements into m[k,l] . m = np.einsum('ij,klij->kl',kernel,sub_matrices) multiplies two dimensions i and j of kernel into last two dimensions i and j of sub_matrices array (in other words, it element-wise multiplies kernel to sub矩阵sub_matrices[k,l,:,:] )并将所有元素相加到m[k,l]中。 This is known as 2D convolution of kernel into a .这称为将kernel二维卷积a .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM