Source code for pyctools.components.arithmetic

#  Pyctools - a picture processing algorithm development kit.
#  http://github.com/jim-easterbrook/pyctools
#  Copyright (C) 2014-20  Pyctools contributors
#
#  This program is free software: you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see
#  <http://www.gnu.org/licenses/>.

__all__ = ['Arithmetic', 'Arithmetic2']
__docformat__ = 'restructuredtext en'

import numpy

from pyctools.core.config import ConfigStr
from pyctools.core.base import Component, Transformer
from pyctools.core.types import pt_float, pt_complex


[docs]class Arithmetic(Transformer): """Do simple arithmetic. Applies a user supplied arithmetical expression to every pixel in each frame. To set the expression, set the component's ``func`` config to a suitable string expression. The input data should appear in your expression as the word ``data``. For example, to convert video levels from the range ``16..235`` to ``64..204`` you could do this:: setlevel = Arithmetic( func='((data - pt_float(16.0)) * pt_float(140.0 / 219.0)) + pt_float(64.0)') ... pipeline(..., setlevel, ...) Note the liberal use of :py:data:`~pyctools.core.types.pt_float` to coerce numbers to the Pyctools default floating point type (:py:class:`numpy:numpy.float32`). NumPy will otherwise convert Python :py:class:`float` to :py:class:`numpy:numpy.float64`. """ def initialise(self): self.config['func'] = ConfigStr(value='data') def transform(self, in_frame, out_frame): self.update_config() func = self.config['func'] data = in_frame.as_numpy() out_frame.data = eval(func) out_frame.set_audit(self, 'data = {}\n'.format(func)) return True
[docs]class Arithmetic2(Component): """Do simple arithmetic with two inputs. Similar to :py:class:`Arithmetic`, but has two inputs. For example, to subtract the second input from the first you could do:: subtracter = Arithmetic2(func='data1 - data2') """ inputs = ['input1', 'input2'] #: def initialise(self): self.config['func'] = ConfigStr(value='data1 + data2') def process_frame(self): in_frame1 = self.input_buffer['input1'].get() in_frame2 = self.input_buffer['input2'].get() out_frame = self.outframe_pool['output'].get() self.update_config() func = self.config['func'] data1 = in_frame1.as_numpy() data2 = in_frame2.as_numpy() out_frame.initialise(in_frame1) out_frame.data = eval(func) # audit out_frame.merge_audit({'data1': in_frame1, 'data2': in_frame2}) out_frame.set_audit(self, 'data = {}\n'.format(func)) self.send('output', out_frame)