簡體   English   中英

沿2D數組滑動子數組

[英]Sliding a subarray along a 2d array

這是我一直努力奮斗的事情。 該算法如下:

  1. 從更大的數組中選擇一個子數組作為行和列的數組
  2. 計算子數組的中位數
  3. 用中值替換子數組中的單元格
  4. 將子數組向右移動自己的長度
  5. 重復到數組末尾
  6. 將子數組向下移動自己的高度
  7. 重復

我有步驟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陣列,但我只是想首先抓住這個簡單的任務。 我如何才能使數組前后滑動並向下循環?

我看到了一些“代碼氣味”。 因為這個數字設置為3所以從range(side)開始,您將得到[0,1,2]的結果。 那是你真正想要的嗎?

您設置i,j = patch.size然后在您的for循環中立即覆蓋這些值。

最后,您要重新計算每個循環的median

好的,這就是我要做的。

  1. 找出在寬度和高度上需要多少個補丁。 並乘以邊的大小。
  2. 將您的數組(矩陣)切成碎片。
  3. 將補丁分配給中位數。

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        

您可以使用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的圖塊實際上都適合其中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM