2017-02-26 43 views
6

Biorąc pod uwagę macierz 2D (M x N) i jądro 2D (K x L), w jaki sposób zwrócić macierz, która jest wynikiem maksimum lub średniej łączenie za pomocą danego jądra nad obrazem?jak wykonać maksymalne/średnie pulowanie na macierzy 2d używając numpy

Chciałbym użyć numpy, jeśli to możliwe.

Uwaga: M, N, K, L mogą być równe lub nieparzyste i nie muszą się wzajemnie idealnie dzielić, np. Macierz 7x5 i jądro 2x2.

np maksymalnego poolingu:

matrix: 
array([[ 20, 200, -5, 23], 
     [ -13, 134, 119, 100], 
     [ 120, 32, 49, 25], 
     [-120, 12, 09, 23]]) 
kernel: 2 x 2 
soln: 
array([[ 200, 119], 
     [ 120, 49]]) 

Odpowiedz

12

Można użyć scikit wizerunek block_reduce:

import numpy as np 
import skimage.measure 

a = np.array([ 
     [ 20, 200, -5, 23], 
     [ -13, 134, 119, 100], 
     [ 120, 32, 49, 25], 
     [-120, 12, 9, 23] 
]) 
skimage.measure.block_reduce(a, (2,2), np.max) 

Daje:

array([[200, 119], 
     [120, 49]]) 
4

Jeśli rozmiar obrazu jest podzielny przez kernal rozmiar, możesz zmienić kształt tablicy i użyć max lub mean, jak uważasz

import numpy as np 

mat = np.array([[ 20, 200, -5, 23], 
     [ -13, 134, 119, 100], 
     [ 120, 32, 49, 25], 
     [-120, 12, 9, 23]]) 

M, N = mat.shape 
K = 2 
L = 2 

MK = M // K 
NL = N // L 
print(mat[:MK*K, :NL*L].reshape(MK, K, NL, L).max(axis=(1, 3))) 
# [[200, 119], [120, 49]] 

Jeśli nie masz parzystej liczby jąder, musisz osobno obsługiwać granice. (Jak podkreślono w komentarzach, powoduje to skopiowanie macierzy, co wpłynie na wydajność).

mat = np.array([[20, 200, -5, 23, 7], 
       [-13, 134, 119, 100, 8], 
       [120, 32, 49, 25, 12], 
       [-120, 12, 9, 23, 15], 
       [-57, 84, 19, 17, 82], 
       ]) 
# soln 
# [200, 119, 8] 
# [120, 49, 15] 
# [84, 19, 82] 
M, N = mat.shape 
K = 2 
L = 2 

MK = M // K 
NL = N // L 

# split the matrix into 'quadrants' 
Q1 = mat[:MK * K, :NL * L].reshape(MK, K, NL, L).max(axis=(1, 3)) 
Q2 = mat[MK * K:, :NL * L].reshape(-1, NL, L).max(axis=2) 
Q3 = mat[:MK * K, NL * L:].reshape(MK, K, -1).max(axis=1) 
Q4 = mat[MK * K:, NL * L:].max() 

# compose the individual quadrants into one new matrix 
soln = np.vstack([np.c_[Q1, Q3], np.c_[Q2, Q4]]) 
print(soln) 
# [[200 119 8] 
# [120 49 15] 
# [ 84 19 82]] 
+0

'M, N = mat.shape' będzie bardziej przejrzysty. Powinieneś również zauważyć, że twoja odpowiedź działa nawet wtedy, gdy jądro nie dzieli źródła, ale odrzuca granice (i przynosi kopię). – Eric