Source code for ClearMap.ImageProcessing.Filter.Vector.VectorStructureElement

# -*- coding: utf-8 -*-
"""
VectorStructureElement
======================

Routines to generate vector valued structure elements for vector filters.
"""
__author__ = 'Christoph Kirst <christoph.kirst.ck@gmail.com>'
__license__ = 'GPLv3 - GNU General Public License v3 (see LICENSE.txt)'
__copyright__ = 'Copyright © 2020 by Christoph Kirst'

import numpy as np


[docs] def vectors_to_neighbours(shape, max_radius=None, reshape=True, orientation=False, rescale=True): """Generate vectors to voxels in a neighborhood.""" # center center = tuple(s // 2 - 1 if s % 2 == 0 else s // 2 for s in shape) ranges = (np.arange(-c, c + 1) for c in center) if max_radius == 'sphere': max_radius = np.min(center) # all vectors vectors = np.array(np.meshgrid(*ranges, indexing='ij'), dtype=float) if reshape: vectors = vectors.reshape(len(shape), -1).T else: vectors = vectors.transpose(tuple(d for d in range(1, len(shape) + 1)) + (0,)) # length weights # is this a good measure? lengths = np.linalg.norm(vectors, axis=-1) # valid valid = lengths > 0 if max_radius is not None: valid = np.logical_and(valid, lengths <= max_radius) vectors[np.logical_not(valid)] = 0 # orientation if orientation: # invert z < 0 vectors[vectors[..., 2] < 0, :] *= -1 # invert z = 0, y < 0 ids0 = vectors[..., 2] == 0 vectors[np.logical_and(ids0, vectors[..., 1] < 0), :] *= -1 # invert z = 0, y = 0, x < 0 ids0 = np.logical_and(ids0, vectors[..., 1] == 0) vectors[np.logical_and(ids0, vectors[..., 0] < 0), :] *= -1 # rescale vectors if rescale: if rescale is True: def inverse(x): return 1.0/x rescale = inverse vectors[valid] = (vectors[valid] * rescale(lengths[valid][:, np.newaxis])) return vectors, lengths, valid