繁体   English   中英

如何在4D numpy数组上执行迭代2D操作

[英]How to perform iterative 2D operation on 4D numpy array

让我在这篇文章前言说我对Python和NumPy很新,所以我确定我忽略了一些简单的东西。 我要做的是使用掩码(掩模卷积操作)在PGM(灰度)文件上进行图像处理; 但是,我不想使用可用的SciPy一体化成像处理库 - 我试图自己实现屏蔽和处理操作。 我想做的是以下内容:

  1. 在256x256阵列上迭代3x3滑动窗口
  2. 在每次迭代中,我想使用3x3图像蒙版(由小数值<1组成的数组)和原始数组中的3x3窗口执行操作
  3. 操作是图像蒙版乘以3x3窗口,结果总计为一个数字,表示原始3x3区域的加权平均值
  4. 这个总和应该插回到3x3窗口的中心,原始的周围值保持不变
  5. 但是,其中一个操作的输出不应该是下一个操作的输入,因此应该创建一个新数组,或者在所有操作完成之前不应更新原始的256x256数组。

这个过程有点像这样,除了我需要将卷积特征的结果放回到它所来自的窗口的中心: http//ufldl.stanford.edu/wiki/images/6/6c/Convolution_schematic。 GIF

因此,在上面的例子中, 4将返回到它所来自的3x3窗口的中心位置(在所有操作结束之后),所以它看起来像[[1, 1, 1], [0, 4, 1], [0, 0, 1]]对于获得的每个其他卷积特征[[1, 1, 1], [0, 4, 1], [0, 0, 1]] 0,0,1 [[1, 1, 1], [0, 4, 1], [0, 0, 1]]等等。 也可以使用原始的非参考副本和插入其中的新值。

所以,这就是我到目前为止所做的:我有一个256x256 2D numpy数组,这是我的源图像。 使用as_strided,我将其转换为as_strided, numpy 3x3切片数组。 我面临的主要问题是我想执行我在每个切片上指定的操作。 我能够在一个切片上执行它,但是在我尝试过的npsum操作中,它将所有切片的结果加到一个值中。 在此之后,我要么想要以我所描述的方式创建一个新的256x256数组,或者迭代原始数据,在适当时替换每个3x3窗口的中间值。 我尝试使用ndenumerate更改我的4D数组的相同值(v, x, 1, 1) ,但是因为从我的4D数组返回的索引是(v, x, y, z),我似乎无法弄清楚如何只迭代(v, x)并将最后两部分保留为根本不应该改变的常量。

到目前为止,这是我的代码:

import numpy as np
from numpy.lib import stride_tricks

# create 256x256 NumPy 2D array from image data and image size so we can manipulate the image data, then create a 4D array of strided windows
# currently, it's only creating taking 10 slices to test with
imageDataArray = np.array(parsedPGMFile.imageData, dtype=int).reshape(parsedPGMFile.numRows, parsedPGMFile.numColumns)
xx = stride_tricks.as_strided(imageDataArray, shape=(1, 10, 3, 3), strides=imageDataArray.strides + imageDataArray.strides)

# create the image mask to be used
mask = [1,2,1,2,4,2,1,2,1]
mask = np.array(mask, dtype=float).reshape(3, 3)/16

# this will execute the operation on just the first 3x3 element of xx, but need to figure out how to iterate through all elements and perform this operation individually on each element
result = np.sum(mask * xx[0,0])

来自http://wiki.scipy.org/Cookbook/GameOfLifeStrides,http://www.johnvinyard.com/blog/?p = 268http://chintaksheth.wordpress.com/2013/07/等来源的研究31 / numpy-the-trade-of-trade-part-ii /非常有用(以及SO),但它们似乎没有解决我正在努力做的事情(除非我失踪明显的东西)。 我可能会使用大量的for循环,但我宁愿学习如何使用我们拥有的这些很棒的Python库。 我也意识到我正在将几个问题结合在一起,但这只是因为我怀疑这一切都可以非常简单地完成! 在此先感谢您的帮助!

当你需要乘以元素,然后减少加法,想想np.dotnp.einsum

from numpy.lib.stride_tricks import as_strided
arr = np.random.rand(256, 256)
mask = np.random.rand(3, 3)
arr_view = as_strided(arr, shape=(254, 254, 3, 3), strides=arr.strides*2)

arr[1:-1, 1:-1] = np.einsum('ijkl,kl->ij', arr_view, mask)

基于示例说明:

In [1]: import numpy as np

In [2]: from scipy.signal import convolve2d

In [3]: image = np.array([[1,1,1,0,0],[0,1,1,1,0],[0,0,1,1,1],[0,0,1,1,0],[0,1,1,0,0]])

In [4]: m = np.array([[1,0,1],[0,1,0],[1,0,1]])

In [5]: convolve2d(image, m, mode='valid')
Out[5]:
array([[4, 3, 4],
       [2, 4, 3],
       [2, 3, 4]])

把它放回原处:

In [6]: image[1:-1,1:-1] = convolve2d(image, m, mode='valid')

In [7]: image
Out[7]:
array([[1, 1, 1, 0, 0],
       [0, 4, 3, 4, 0],
       [0, 2, 4, 3, 1],
       [0, 2, 3, 4, 0],
       [0, 1, 1, 0, 0]])

暂无
暂无

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

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