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)