Ini adalah sesuatu yang telah saya perjuangkan selama beberapa minggu. Algoritmanya adalah sebagai berikut:

  1. Pilih subarray sebagai array baris dan kolom dari array yang lebih besar
  2. Hitung median dari subarray
  3. Ganti sel di subarray dengan nilai median
  4. Pindahkan subarray ke kanan dengan panjangnya sendiri
  5. Ulangi hingga akhir array
  6. Pindahkan subarray ke bawah dengan ketinggiannya sendiri
  7. Ulang

Saya punya langkah 1 hingga 3 sebagai berikut:

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)

Akhirnya, saya akan menggunakan array 901x877 dari sebuah gambar, tetapi saya hanya mencoba untuk menguasai tugas sederhana ini terlebih dahulu. Bagaimana saya bisa menggeser array dan kemudian turun dengan satu lingkaran?

0
Jim421616 17 Agustus 2017, 22:17

2 jawaban

Jawaban Terbaik

Anda dapat menggunakan scikit-image view_as_blocks dan penyiaran NumPy untuk membuat vektor operasi:

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]]

Perhatikan bahwa saya harus mengubah ukuran larik Anda menjadi 12x12 sehingga semua ubin 3x3 Anda benar-benar muat di sana.

0
Nils Werner 18 Agustus 2017, 10:33

Berikut adalah beberapa "bau kode" yang saya lihat. Mulailah dengan range(side) karena nomor ini disetel ke 3 maka Anda akan mendapatkan hasil [0,1,2]. Apakah itu yang Anda inginkan?

Anda menyetel i,j = patch.size lalu segera tulis nilai-nilai ini, dalam loop for Anda.

Terakhir, Anda menghitung ulang median setiap loop.

Oke, inilah yang akan saya lakukan.

  1. cari tahu berapa banyak tambalan yang Anda perlukan dalam lebar dan tinggi. dan kalikan dengan ukuran sisinya.
  2. iris array Anda (matriks) menjadi potongan-potongan itu.
  3. tetapkan tambalan ke median.

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        
0
VoNWooDSoN 17 Agustus 2017, 20:26