Source code for node_convolution

# 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.

import numpy as np
import scipy.ndimage.filters

from sympathy.api import node, exceptions
from sympathy.api.nodeconfig import Port, Ports, Tag, Tags

from sylib.imageprocessing.image import ImagePort
from sylib.imageprocessing.utility import table_to_image


[docs] class ImageConvolution(node.Node): """ Convolves the input image with a kernel given by second input as a table. Each channel is processed separately. """ name = 'Image Convolution' author = 'Mathias Broxvall' icon = 'image_convolution.svg' description = ( 'Convolves the input image with a kernel given by second ' 'input as a table. Each channel is processed separately.' ) nodeid = 'com.sympathyfordata.imageanalysis.convolution' tags = Tags(Tag.ImageProcessing.ImageManipulation) parameters = node.parameters() parameters.set_string( 'border mode', value='constant', description=( 'Method used for padding the input'), label='Border mode', editor=node.editors.combo_editor( options=['constant', 'reflect', 'wrap']) ) parameters.set_float( 'k', value=0.0, description=( 'Value used for border mode "constant"'), label='Pad value' ) inputs = Ports([ ImagePort('image to perform convolution on', name='image'), Port.Custom('table', 'Convolution matrix', name='conv'), ]) outputs = Ports([ ImagePort('result after convolution', name='result'), ]) def execute(self, node_context): image = node_context.input['image'].get_image() conv = node_context.input['conv'] border_mode = node_context.parameters['border mode'].value border_value = node_context.parameters['k'].value if int(image.sum()) == 0 or conv.number_of_rows() == 0: raise exceptions.SyDataError("Empty table") kernel = table_to_image(conv) if len(image.shape) == 2: im = scipy.ndimage.filters.convolve( image, kernel, mode=border_mode, cval=border_value) else: im1 = scipy.ndimage.filters.convolve( image[:, :, 0], kernel, mode=border_mode, cval=border_value) im = np.zeros(im1.shape[:2]+image.shape[2:]) im[:, :, 0] = im1 for channel in range(1, image.shape[2]): im[:, :, channel] = scipy.ndimage.filters.convolve( image[:, :, channel], kernel, mode=border_mode, cval=border_value) node_context.output['result'].set_image(im)