I am trying to calculate L1 Distance matrix on images and neural network features. I wrote a naive to calculate this using scipy operations on 2d arrays. If any one can suggest fast and efficient approach to calculate the same if I have 4d Tensor (N x C x H x W). I don’t want to iterate over N and C to calculate L1 Distance matrix, as it will slow down the training process.
import numpy as np
from scipy.ndimage import iterate_structure, generate_binary_structure
import scipy.ndimage as ndimage
from itertools import repeat
def nearestPixelDifference(values,a,idx,offset,size):
current_value = values[len(values)/2]
current = np.unravel_index(idx[0],size)
for i, pair in enumerate(offset):
ii = np.add(current, pair)
if ii[0] < 0 or ii[1] < 0:
continue
if ii[0] >= size[0] or ii[1] >= size[1]:
continue
a[idx[0],np.ravel_multi_index(ii,size)] = np.abs(current_value - values[i])
idx[0] += 1
return 0
def getSimilarityMatrix(gt,radius, func):
index = [0]
h,w = gt.shape
foot = np.array(generate_binary_structure(2, 1),dtype=int)
footprint = np.array(iterate_structure(foot , radius),dtype=int)
shape = footprint.shape
num_cols = np.where(footprint==1)[1].shape[0] #int(0.5 * radius*(4 + 2*(radius-1)))# n/2(2a+(n-1)d)
x,y = np.where(footprint==1)
offsets = zip(x-shape[0]/2,y-shape[1]/2)
affinity = np.zeros((h**2,w**2),dtype=np.uint8)
results = ndimage.generic_filter(gt, func,footprint=footprint,mode='constant',
extra_arguments=(affinity,index,offsets,gt.shape))
return affinity,footprint
Given an array x, algorithm computes L1 distance between nearest pixels within radius 2. Following is simple code for the same.
x = np.array([[1., 1., 1., 0.],
[1., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 1., 1., 1.]])
pixel_affinity, struct = getSimilarityMatrix(x,2,nearestPixelDifference)
Thanks