#!/usr/bin/python # -*- coding: utf-8 -*- # \file AttributeProfiles.py # \brief TODO # \author Florent Guiotte # \version 0.1 # \date 04 avril 2018 # # TODO details from .core import Filter, Stack ## TODO: dep import sys import numpy as np sys.path.append('../triskele/python') import triskele class AttributeProfiles(Filter): def __init__(self, area=None, sd=None, moi=None): super().__init__(self.__class__.__name__) self.logger.debug('Oh hi Mark!') self.area = np.sort(area) if area is not None else None self.sd = np.sort(sd) if sd is not None else None self.moi = np.sort(moi) if moi is not None else None def _process_desc(self): att_desc = dict() for att in ['area', 'sd', 'moi']: att_desc[att] = list() if self.__getattribute__(att) is not None: att_desc[att].extend( ['Thickening {} {}'.format(att, x) for x in self.__getattribute__(att)[::-1]]) att_desc[att].append(None) att_desc[att].extend( ['Thinning {} {}'.format(att, x) for x in self.__getattribute__(att)]) return att_desc def _process_symb(self): att_symb = dict() for att in ['area', 'sd', 'moi']: att_symb[att] = list() if self.__getattribute__(att) is not None: att_symb[att].extend( ['\phi^{{{}}}_{{{}}}'.format(att, x) for x in self.__getattribute__(att)[::-1]]) att_symb[att].append(None) att_symb[att].extend( ['\gamma^{{{}}}_{{{}}}'.format(att, x) for x in self.__getattribute__(att)]) return att_symb def _process_offset(self): att_offset = dict() for att in ['area', 'sd', 'moi']: values = self.__getattribute__(att) att_offset[att] = len(values) * 2 + 1 if values is not None else 0 return att_offset def _process_len(self): att_len = dict() for att in ['area', 'sd', 'moi']: values = self.__getattribute__(att) att_len[att] = len(values) if values is not None else 0 return att_len def _process(self, data, metadata): t = triskele.Triskele(data, verbose=False) att_min = t.filter(tree='min-tree', area=self.area, standard_deviation=self.sd, moment_of_inertia=self.moi) att_max = t.filter(tree='max-tree', area=self.area, standard_deviation=self.sd, moment_of_inertia=self.moi) ## Merge filtering as APs ## Create new metadata ### Pre-process descriptions att_desc = self._process_desc() att_symb = self._process_symb() ### Compute stack offsets and att length att_len = self._process_len() att_offset = self._process_offset() stack_offset = sum(att_offset.values()) raster_offset = sum(att_len.values()) print('DEBUG: att offset: {}, att len: {}'.format(att_offset, att_len)) print('DEBUG: stack offset: {}, raster offset: {}'.format(stack_offset, raster_offset)) ### Merge old and new descriptions metadata_new = list() ### Re-order to create original APs raster_list = list() for stack in metadata: if stack.end - stack.begin > 1: raise NotImplementedError('Nested filtering not implemented yet') do = dso = 0 sb = stack.begin * (raster_offset + 1) for att in ['area', 'sd', 'moi']: if att_offset[att] == 0: continue al = att_len[att] raster_list.append(att_min[:,:,sb+do+al:sb+do:-1]) raster_list.append(att_min[:,:,sb]) print('DEBUG: copying layer {}'.format(sb)) raster_list.append(att_max[:,:,sb+do+1:sb+do+al+1]) do += al stack_new = Stack(dso + stack_offset * stack.begin, att_offset[att], stack.desc[0], stack.symb[0]) dso += att_offset[att] for old_desc, new_desc in zip(stack_new.desc, att_desc[att]): print('DESCRIPTION: {} > {}'.format(old_desc, new_desc)) old_desc.append(new_desc) for old_symb, new_symb in zip(stack_new.symb, att_symb[att]): print('symbRIPTION: {} > {}'.format(old_symb, new_symb)) old_symb.append(new_symb) metadata_new.append(stack_new) data_new = np.dstack(raster_list) return data_new, metadata_new if __name__ == '__main__': area = [10, 100, 1000] sd = [.1, .9] ap = AttributeProfiles(area, sd) print(ap._process_desc()) print(ap._process_offset())