沿着2d阵列滑动子阵列

时间:2017-08-17 19:17:21

标签: python arrays numpy

这是我几周来一直在努力的事情。算法如下:

  1. 从较大的数组
  2. 中选择一个子行数组作为行和列的数组
  3. 计算子阵列的中位数
  4. 用中值
  5. 替换子阵列中的单元格
  6. 将子阵列向右移动
  7. 重复到数组的结尾
  8. 按子身高度移动子阵列
  9. 重复
  10. 我已按步骤1到3进行操作:

    import numpy as np
    w1 = np.arange(100).reshape(10,10)
    side = 3
    patch = w1[0:side, 0:side]
    
    i, j = patch.shape
    for j in range(side):
        for i in range(side):
            patch[i,j] = np.median(patch)
    

    最终,我将使用图像中的901x877阵列,但我只想先抓住这个简单的任务。如何使用循环滑动阵列然后向下滑动?

2 个答案:

答案 0 :(得分:0)

以下是我看到的一些“代码味道”。 从range(side)开始,因为此号码设置为3,您将得到[0,1,2]的结果。那是你真正想要的吗?

您设置i,j = patch.size然后立即在for循环中写下这些值。

最后,您要重新计算每个循环median

好的,这就是我要做的事。

  1. 计算出宽度和高度都需要多少补丁。然后乘以那边的大小。
  2. 将您的数组(矩阵)切割成这些部分。
  3. 将补丁分配到中位数。
  4. import numpy as np                                                                                                                                                                                         
    w1 = np.arange(100).reshape(10,10)                                                                                                                                                                         
    side = 3                                                                                                                                                                                                   
    w, h = w1.shape                                                                                                                                                                                            
    width_index   = np.array(range(w//side)) * side                                                                                                                                                             
    height_index  = np.array(range(h//side)) * side                                                                                                                                                             
    
    def assign_patch(patch, median, side):                                                                                                                                                                     
        """Break this loop out to prevent 4 nested 'for' loops"""                                                                                                                                              
        for j in range(side):                                                                                                                                                                                  
            for i in range(side):                                                                                                                                                                              
                patch[i,j] = median                                                                                                                                                                            
        return patch                                                                                                                                                                                           
    
    for width in width_index:                                                                                                                                                                                  
        for height in height_index:                                                                                                                                                                            
            patch  = w1[width:width+side, height:height+side]                                                                                                                                                  
            median = np.median(patch)                                                                                                                                                                          
            assign_patch(patch, median, side)                                                                           
    
    print w1        
    

答案 1 :(得分:0)

您可以使用scikit-image的view_as_blocks和NumPy广播来矢量化操作:

import numpy as np
import skimage

w1 = np.arange(144).reshape(12,12)
print(w1)
# [[  0   1   2   3   4   5   6   7   8   9  10  11]
#  [ 12  13  14  15  16  17  18  19  20  21  22  23]
#  [ 24  25  26  27  28  29  30  31  32  33  34  35]
#  [ 36  37  38  39  40  41  42  43  44  45  46  47]
#  [ 48  49  50  51  52  53  54  55  56  57  58  59]
#  [ 60  61  62  63  64  65  66  67  68  69  70  71]
#  [ 72  73  74  75  76  77  78  79  80  81  82  83]
#  [ 84  85  86  87  88  89  90  91  92  93  94  95]
#  [ 96  97  98  99 100 101 102 103 104 105 106 107]
#  [108 109 110 111 112 113 114 115 116 117 118 119]
#  [120 121 122 123 124 125 126 127 128 129 130 131]
#  [132 133 134 135 136 137 138 139 140 141 142 143]]

side = 3
w2 = skimage.util.view_as_blocks(w1, (side, side))
w2[...] = np.median(w2, axis=(-2, -1))[:, :, None, None]
print(w1)
# [[ 13  13  13  16  16  16  19  19  19  22  22  22]
#  [ 13  13  13  16  16  16  19  19  19  22  22  22]
#  [ 13  13  13  16  16  16  19  19  19  22  22  22]
#  [ 49  49  49  52  52  52  55  55  55  58  58  58]
#  [ 49  49  49  52  52  52  55  55  55  58  58  58]
#  [ 49  49  49  52  52  52  55  55  55  58  58  58]
#  [ 85  85  85  88  88  88  91  91  91  94  94  94]
#  [ 85  85  85  88  88  88  91  91  91  94  94  94]
#  [ 85  85  85  88  88  88  91  91  91  94  94  94]
#  [121 121 121 124 124 124 127 127 127 130 130 130]
#  [121 121 121 124 124 124 127 127 127 130 130 130]
#  [121 121 121 124 124 124 127 127 127 130 130 130]]

请注意,我必须将数组的大小更改为12x12,以便3x3的所有切片都适合放在那里。