Pregunta Calcule el producto de vecindario para cada celda en una matriz con números y caracteres


Estoy tratando de implementar un algoritmo de procesamiento de imágenes que implique calcular el producto del vecindario 4-adyacente para cada celda. Es decir, para calcular una nueva matriz Y para X donde y[i, j] = x[i-1, j] * x[i, j-1] * x[i+1, j] * x[i, j+1]. Los vecinos fuera de los límites deben ser ignorados.

Ahora solo puedo pensar en este enfoque: usar scipy.ndimage.filters.correlate y pase pesos con ceros y un 1 para obtener cuatro matrices, cada una con el vecino de cada celda en una dirección, como pasar weight = [[0, 0, 0], [1, 0, 0], [1, 1]] y obtengo a[i, j] = x[i-1, j], y con otras pesas puedo conseguir b[i, j] = x[i, j-1], c[i, j] = x[i+1, j], d[i, j] = x[i, j+1]. Entonces yo uso np.multiply Para calcular el producto de estas cuatro matrices.

Sin embargo, este enfoque es un poco demasiado lento y no puedo ignorar los límites. ¿Hay alguna otra forma de hacerlo con adormecer / scipy para que no tenga que recurrir a los bucles?


5
2017-11-15 12:25


origen


Respuestas:


Necesitará escribir los bordes por separado, pero esto hace lo que está buscando para la parte central de su matriz, y es probablemente mucho más rápido que la correlación:

y = np.empty_like(x)
y[1:-1, 1:-1] = x[1:-1, 1:-1]
y[1:-1, 1:-1] *= x[:-2, 1:-1]
y[1:-1, 1:-1] *= x[2:, 1:-1]
y[1:-1, 1:-1] *= x[1:-1, :-2]
y[1:-1, 1:-1] *= x[1:-1, 2:]

3
2017-11-15 15:34



Creo que esto coincide mejor con lo que estás pidiendo:

import numpy as np

x = np.array([
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 1],
    [2, 3, 4, 5, 6],
    [7, 8, 9, 1, 2]
])

y = np.ones_like(x)
y[+1:, :] *= x[:-1, :]
y[:-1, :] *= x[+1:, :]
y[:, +1:] *= x[:, :-1]
y[:, :-1] *= x[:, +1:]

y
#>>> array([[  12,   21,   64,  135,    4],
#>>>        [  14,  288,  756,  160,  270],
#>>>        [ 126,  448, 1080,  216,   10],
#>>>        [  16,  189,   32,   90,    6]])

Tenga en cuenta que la primera *= Puede ser una tarea si necesitas velocidad extra.


3
2017-11-15 23:26