Source code for node_imagelists

# This file is part of Sympathy for Data.
# Copyright (c) 2017, Combine Control Systems AB
#
# SYMPATHY FOR DATA COMMERCIAL LICENSE
# You should have received a link to the License with Sympathy for Data.
from sympathy.api import node
from sympathy.api.nodeconfig import Port, Ports, Tag, Tags

import numpy as np
from sylib.imageprocessing.image import ImagePort
from sylib.imageprocessing.image import File as ImageFile
from sylib.imageprocessing.algorithm_selector import (
    ImageFiltering_abstract)


[docs] class ImageToList(ImageFiltering_abstract, node.Node): name = 'Image to List' author = 'Mathias Broxvall' icon = 'image_list.svg' description = ('Generates a list of images based on algorithms operating ' 'on one image') nodeid = 'syip.image2list' tags = Tags(Tag.ImageProcessing.Layers) def alg_from_labels(im, results, par): if not np.issubdtype(im.dtype, np.integer): # Early return, input is not a labeled image return if len(im.shape) == 3: im = im[:, :, 0] for value in range(np.min(im), np.max(im)+1): mask = im == value if value == 0 and not par['do background'].value: pass elif np.sum(mask) > 0: new_image = ImageFile() new_image.set_image(mask) results.append(new_image) def alg_from_channels(im, results, par): if len(im.shape) < 3: im = im.reshape(im.shape + (1,)) channels = im.shape[2] for channel in range(channels): new_image = ImageFile() new_image.set_image(im[:, :, channel]) results.append(new_image) algorithms = { 'from labels': { 'description': ('Generates an image mask selecting each label in ' 'an image once'), 'do background': 'If true include the background object (ID=0)', 'multi_chromatic': False, 'algorithm': alg_from_labels}, 'from channels': { 'description': ('Generates a list of grayscale images from each ' 'channel in input image'), 'multi_chromatic': True, 'algorithm': alg_from_channels}} options_list = ['do background'] options_types = {'do background': bool} options_default = {'do background': True} parameters = node.parameters() parameters.set_string('algorithm', value=next(iter(algorithms)), description='', label='Algorithm') ImageFiltering_abstract.generate_parameters(parameters, options_types, options_default) inputs = Ports([ ImagePort('source image', name='source')]) outputs = Ports([ Port.Custom('[image]', 'Resulting list of images', name='results')]) __doc__ = ImageFiltering_abstract.generate_docstring( description, algorithms, options_list, inputs, outputs) def execute(self, node_context): image = node_context.input['source'].get_image() params = node_context.parameters alg_name = params['algorithm'].value results = node_context.output['results'] alg = self.algorithms[alg_name]['algorithm'] alg(image, results, params)
[docs] class ListToImage(ImageFiltering_abstract, node.Node): name = 'List to Image' author = 'Mathias Broxvall' icon = 'image_list2image.svg' description = 'Generates an image based on a list of images' nodeid = 'syip.list2image' tags = Tags(Tag.ImageProcessing.Layers) def alg_concatenate(images, par): max_x, max_y = 0, 0 channels = 0 if len(images) == 0: return np.zeros((1, 1, 1)) dtype = images[0].get_image().dtype for im_obj in images: im = im_obj.get_image() max_x = max(max_x, im.shape[1]) max_y = max(max_y, im.shape[0]) if len(im.shape) > 2: channels += im.shape[2] else: channels += 1 result = np.zeros((max_y, max_x, channels), dtype=dtype) ch = 0 for im_obj in images: im = im_obj.get_image() if len(im.shape) < 3: im = im.reshape(im.shape + (1,)) result[:im.shape[0], :im.shape[1], ch:ch+im.shape[2]] = im ch += im.shape[2] return result algorithms = { 'concatenate channels': { 'description': ('Generates an image by concatenating all channels ' 'in the input images. Resulting datatype given by ' 'first image in the list'), 'multi_chromatic': True, 'algorithm': alg_concatenate}} options_list = ['do background'] options_types = {'do background': bool} options_default = {'do background': True} parameters = node.parameters() parameters.set_string('algorithm', value=next(iter(algorithms)), description='', label='Algorithm') ImageFiltering_abstract.generate_parameters(parameters, options_types, options_default) inputs = Ports([ Port.Custom('[image]', 'Input list of images', name='inputs') ]) outputs = Ports([ ImagePort('result image', name='result'), ]) __doc__ = ImageFiltering_abstract.generate_docstring( description, algorithms, options_list, inputs, outputs) def execute(self, node_context): params = node_context.parameters output = node_context.output['result'] inputs = node_context.input['inputs'] alg_name = params['algorithm'].value alg = self.algorithms[alg_name]['algorithm'] im = alg(inputs, params) output.set_image(im)