#!/usr/bin/python # -*- coding: utf-8 -*- # \file LocalFeatures.py # \brief TODO # \author Florent Guiotte # \version 0.1 # \date 23 août 2018 # # TODO details from ld2dap.core import Filter, Stack, Stacker import numpy as np class LocalFeatures(Filter): def __init__(self, features=None, patch_size=3): super().__init__(self.__class__.__name__) self.features = features self.patch_size = patch_size def _process(self, data, metadata): self.logger.info('Local Features Filtering') stacker = Stacker() for stack in metadata: self.logger.debug('{}'.format(stack)) patches = create_patches(data[:,:,stack.begin:stack.end], self.patch_size) for function in self.features: self.logger.debug('Features function {}'.format(function.__name__)) features = function(patches, axis=-1) features = cast_expand_i(features, patches.dtype) stacker.auto_stack(features, stack, 'Local Features {} {}x{}'.format(function.__name__, self.patch_size, self.patch_size), 'f^{{{}}}_{{{}\\times{}}}'.format(function.__name__, self.patch_size, self.patch_size)) return stacker.pack() def cast_expand_i(X, dtype): return ((X - X.min()) / (X.max() - X.min()) * np.iinfo(dtype).max).astype(dtype) def create_patches(array, patch_size=3): amp = int((patch_size - 1 ) / 2) stack = list() for i in range(-amp, amp+1): ai = i if i > 0 else None bi = i if i < 0 else None ci = -bi if bi is not None else None di = -ai if ai is not None else None for j in range(-amp, amp+1): offset = np.zeros_like(array) #offset = np.empty(array.shape) aj = j if j > 0 else None bj = j if j < 0 else None cj = -bj if bj is not None else None dj = -aj if aj is not None else None offset[ai:bi, aj:bj] = array[ci:di, cj:dj] stack.append(offset) return np.stack(stack, axis=-1)