%DIPMENUS   Describes the menu system to DIPIMAGE
%   DIPMENUS is used by DIPIMAGE to determine the location of the toolbox
%   functions in the menu system, as well as the input parameters to each
%   of those functions.
%
%   To give your own functions a place in the menus system, create a
%   function called LOCALDIPMENUS, and put it somewhere in the MATLAB
%   path. This function should accept one parameter, the MENULIST,
%   and return a modified MENULIST as well as a FUNCTIONLIST:
%      [MENULIST,FUNCTIONLIST] = LOCALDIPMENUS(MENULIST)
%
%   The MENULIST is a cell array with two columns, the first one contains
%   the names of the sub-menus, the second one contains a cell array with
%   the function names on that menu. Function names that start with '#' are
%   menu names, and put the corresponding menu as a sub-menu at that point.
%   A '-' instead of a function name inserts a menu separator at that
%   point.
%
%   The FUNCTIONLIST describes functions that should be added to the menus.
%   It is a containers.Map where the keys are the function names, and the
%   value is a scalar struct with fields:
%     - display: string to show in the menu, i.e. a very short description
%       of the function).
%     - inparams: struct array, as described below.
%     - outparams: cell array with strings, each a short description of
%       the output parameters.
%   The INPARAMS struct array has one element for each input parameter,
%   and contains the fields:
%     - description: string, a short description of the input parameter.
%     - type: string, the type of the parameter.
%     - constraint: meaning depends on TYPE.
%     - default: default value for the field.
%   For more information on the possible values for the TYPE string, and
%   how each are interpreted, see the DIPimage user manual.
%
%   Note that LOCALDIPMENUS can modify MENULIST at will, and therefore
%   completely rewrite the DIPimage menu system.
%
%   Look at the source code for this function to see how FUNCTIONLIST and
%   MENULIST are defined.
%
% NOTE:
%   There is currently no checking for recursive menu definitions: menu
%   A including menu B as a sub-menu, and menu B including menu A. Do no
%   define your menus that way, it will crash MATLAB.

% (c)2017-2018, Cris Luengo.
% Based on original DIPimage code: (c)1999-2014, Delft University of Technology.
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
%    http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.

function [menulist,functionlist] = dipmenus

%
% Describing the DIPimage meny system
%

% Not all functions listed here have been ported yet. DIPimage will
% leave out any function that is not listed in FUNCTONLIST.
menulist = {...
   'File I/O',{'readim','readroiim','readtimeseries','readrawim','writeim','-',...
      'macro','-','reload','exit'};...
      ... % Note that 'macro', 'reload' and 'exit' are internal functions to dipimage.
   'Display',{'overlay','overlay_confidence','overlay_vector','-','displaylabelnumbers','-',...
      'orientationplot','-','dipgetimage','dipprofile','dipstackinspect',...
      'dipcrop','dipgetcoords','dipdrawpolygon','diproi','-','diptruesize','dipclf'};...
   'Generation',{'newim','newtensorim','newcolorim','joinchannels','-',...
      'deltaim','ramp','xx','yy','zz','rr','phiphi','thetatheta','-',...
      'setborder','-','noise','drawline','drawpolygon','drawshape','gaussianblob'};...
   'Manipulation',{'mirror','shift','correctshift','localshift','-',...
      'rotation','rotation3d','skew','affine_trans','-',...
      'resample','subsample','rebin','split','get_subpixel','-','extend','cut','bbox','-',...
      'arrangeslices','tile','detile'};...
   'Point',{'#Image Arithmetic','#Image Comparison','#Tensor Arithmetic','-',...
      'clip','erfclip','gaussianedgeclip','gaussianlineclip','-',...
      'stretch','hist_equalize','-','lut'};...
   'Image Arithmetic',{'plus','minus','times','rdivide','mod','power','-',...
      'select','-','and','or','xor','-','atan2','hypot','-',...
      'real','imag','abs','phase','-','round','-','cos','sin','tan','sqrt','exp','log'};...
   'Image Comparison',{'eq','gt','ge','lt','le','ne'};...
   'Tensor Arithmetic',{'mtimes','cross','dot','-','norm','trace','det','-','inv','pinv','-',...
      'eig_largest','eig','svd','-','curl','divergence'};...
   'Filters',{'#Differential Filters','#Adaptive Filters','#Morphology',...
      '#Binary Filters','#Diffusion','#Restoration','-',...
      'convolve','-','gaussf','unif','-','maxf','minf','medif','percf','-',...
      'varif','-','gabor','gabor_click'};...
   'Differential Filters',{'derivative','-',...
      'dx','dy','dz','-','gradientvector','gradmag','-',...
      'dxx','dyy','dzz','dxy','dxz','dyz','dgg','dcc','-',...
      'hessian','dethessian','laplace','laplace_plus_dgg','laplace_min_dgg','-',...
      'curl','divergence','-','prewittf','sobelf'};...
   'Adaptive Filters',{'bilateralf','-','kuwahara','selectionf','-',...
      'dgg','dcc','tframehessian'};...
   'Binary Filters',{'bdilation','berosion','bopening','bclosing','hitmiss','-',...
      'bskeleton','bpropagation','brmedgeobjs','smallobjectsremove','fillholes','hull','-',...
      'countneighbors','bmajority','getsinglepixel','getendpixel','getlinkpixel','getbranchpixel'};...
   'Morphology',{'dilation','erosion','closing','opening','tophat','lee','-',...
      'rankmin_closing','rankmax_opening','-','areaopening','pathopening','-',...
      'hmaxima','hminima','reconstruction','-','asf'};...
   'Diffusion',{'gaussf','pmd','pmd_gaussian','aniso','mcd','cpf','ced'};...
   'Restoration',{'wiener','mappg','tikhonovmiller','-','backgroundoffset','afm_flatten'};...
   'Segmentation',{'threshold','hist2image','minima','maxima','-',...
      'watershed','waterseed','splitandmerge','canny','-',...
      'snakeminimize','gvf','vfc','snakedraw','snake2im','im2snake','-',...
      'label','relabel','displaylabelnumbers','traceobjects','countingframe'};...
   'Transforms',{'ft','ift','nufft_type1','nufft_type2','-','riesz','-','dt','vdt','gdt','-',...
      'radoncircle','-','watershed','waterseed'};...
   'Analysis',{'measure','msr2obj','msr2ds','-','scalespace','morphscales','scale2rgb','-',...
      'structuretensor','curvature','pst','quadraturetensor','-',...
      'granulometry','chordlength','paircorrelation','-',...
      'autocorrelation','crosscorrelation','findshift','find_affine_trans','fmmatch','-',...
      'opticflow','findlocalshift','findlocmax','-',...
      'minima','maxima','findminima','findmaxima','subpixlocation'};...
   'Statistics',{'sum','prod','mean','median','percentile','max','min','std','var','any','all','-',...
      'diphist','diphist2d','-','getmaximumandminimum','getsamplestatistics','bbox','-',...
      'radialsum','radialmean','radialmin','radialmax','-',...
      'errormeasure','noisestd','entropy','-','cal_readnoise'}...
};

% For the benefit of our MAKECONTENTS tool, we don't execute the stuff
% below if there is only one output argument. This also prevents
% LOCALDIPMENUS to be called, which could change MENULIST.
if nargout < 2
   return
end

%
% Describing all of the functions in the toolbox... hold on!
%

functionlist = containers.Map('KeyType','char','ValueType','any');
%template = struct('display',{},'inparams',{},'outparams',{});
%template = struct('description',{},'type',{},'constraint',{},'default',{});

% File I/O
functionlist('readim') = struct(...
   'display','Read image',...
   'inparams',struct('description',{'Name of the file to open','File format'},...
                     'type',       {'infile',                  'string'},...
                     'constraint', {'*.*',                     []},...
                     'default',    {'erika.ics',               ''}),...
   'outparams',{{'Output image','Image Parameters'}});
functionlist('readroiim') = struct(...
   'display','Read image',...
   'inparams',struct('description',{'Name of the file to open','Sampling','ROI offset','ROI size','File format'},...
                     'type',       {'infile',                  'array',   'array',     'array',   'string'},...
                     'constraint', {'*.*',                     [],        [],          [],        []},...
                     'default',    {'erika.ics',               4,         [],          [],        ''}),...
   'outparams',{{'Output image','Image Parameters'}});
functionlist('readtimeseries') = struct(...
   'display','Read time series',...
   'inparams',struct('description',{'Base filename','Extension','Range','Conserve color information?','Verbose?'},...
                     'type',       {'infile',       'string',   'array','boolean',                    'boolean'},...
                     'constraint', {'*.*',          [],         [],     [],                           []},...
                     'default',    {'imser',        '',         [],     1,                            0}),...
   'outparams',{{'Output image'}});
functionlist('readrawim') = struct(...
   'display','Read image',...
   'inparams',struct('description',{'Name of the file to open','Sizes',  'Data type'},...
                     'type',       {'infile',                  'array',  'option'},...
                     'constraint', {'*.*',                     [],       {'uint8','uint16','uint32','sint8','sint16','sint32','sfloat','dfloat'}},...
                     'default',    {'trui.ids',                [256,256],'uint8'}),...
   'outparams',{{'Output image'}});
functionlist('writeim') = struct(...
   'display','Write image',...
   'inparams',struct('description',{'Image to write','Name of the file to write','File format'},...
                     'type',       {'image','outfile','string'},...
                     'constraint', {[],     '*.*',     []},...
                     'default',    {'a',    '',        ''}),...
   'outparams',{{}});

% Display
functionlist('overlay') = struct(...
   'display','Overlay image with mask',...
   'inparams',struct('description',{'Grey or color image','Binary or labeled image','Color'},...
                     'type',       {'image',              'image',         'array'},...
                     'constraint', {[],                   {'bin','uint'},  []},...
                     'default',    {'a',                  'b',             [255,0,0]}),...
   'outparams',{{'Output image'}});
functionlist('overlay_confidence') = struct(...
   'display','Overlay an image with confidence',...
   'inparams',struct('description',{'Grey image','Confidence image','Intensity scaling factor'},...
                     'type',       {'image',     'image',           'array'},...
                     'constraint', {[],          {},                []},...
                     'default',    {'a',         'b',               0.75}),...
   'outparams',{{'Output image'}});
functionlist('overlay_vector') = struct(...
   'display','Overlay an image with a vector image',...
   'inparams',struct('description',{'Grey or color image','Vector image','Subsample','Scale'},...
                     'type',       {'image',              'image',       'array',    'array'},...
                     'constraint', {{'scalar','color'},   {'vector'},    [],         []},...
                     'default',    {'a',                  'b',           4,          2}),...
   'outparams',{{'Output image'}});
functionlist('dipgetimage') = struct(...
   'display','Retrieves an image',...
   'inparams',struct('description',{'Figure window'},...
                     'type',       {'handle'},...
                     'constraint', {[]},...
                     'default',    {[]}),...
   'outparams',{{'Output image'}});
functionlist('dipprofile') = struct(...
   'display','Extraction of 1D profile',...
   'inparams',struct('description',{'Figure window','Number of clicks'},...
                     'type',       {'handle',       'array'},...
                     'constraint', {'2D',           []},...
                     'default',    {[],             0}),...
   'outparams',{{'Output image'}});
functionlist('dipstackinspect') = struct(...
   'display','Inspection of the 3rd dimension',...
   'inparams',struct('description',{'Figure window','Close window','Use ROI'},...
                     'type',       {'handle',       'boolean',     'boolean'},...
                     'constraint', {'3D',           [],            []},...
                     'default',    {[],             false,         false}),...
   'outparams',{{'Output image','Coordinates'}});
functionlist('dipcrop') = struct(...
   'display','Crop image',...
   'inparams',struct('description',{'Figure window'},...
                     'type',       {'handle'},...
                     'constraint', {[]},...
                     'default',    {[]}),...
   'outparams',{{'Output image'}});
functionlist('dipgetcoords') = struct(...
   'display','Get coordinates of clicks',...
   'inparams',struct('description',{'Figure window','Number of clicks'},...
                     'type',       {'handle',       'array'},...
                     'constraint', {[],             []},...
                     'default',    {[],             1}),...
   'outparams',{{'Coordinate array'}});
functionlist('dipdrawpolygon') = struct(...
   'display','Draw polygon over image',...
   'inparams',struct('description',{'Figure window'},...
                     'type',       {'handle'},...
                     'constraint', {{'2D','3D','4D'}},...
                     'default',    {[]}),...
   'outparams',{{'Vertices'}});
functionlist('diproi') = struct(...
   'display','Create mask image',...
   'inparams',struct('description',{'Figure window','Interpolation type'},...
                     'type',       {'handle',       'option'},...
                     'constraint', {'2D',           {'polygon','spline'}},...
                     'default',    {[],             'polygon'}),...
   'outparams',{{'Mask image','Vertices'}});
functionlist('diptruesize') = struct(...
   'display','Set figure size',...
   'inparams',struct('description',{'Figure window','Size (% of original)'},...
                     'type',       {'handle',       'array'},...
                     'constraint', {[],             []},...
                     'default',    {[],             100}));
functionlist('dipclf') = struct(...
   'display','Clear all image windows');
%TODO: 'orientationplot'

% Generation
data_types = {'bin','uint8','uint16','uint32','sint8','sint16','sint32','sfloat','dfloat','scomplex','dcomplex'};
color_strings = {'grey','RGB','sRGB','CMY','CMYK','HSI','ICH','ISH','HCV','HSV','XYZ','Yxy','Lab','Luv','LCH'};
functionlist('newim') = struct(...
	'display','New image',...
   'inparams',struct('description',{'Size',   'Data type'},...
                     'type',       {'array',  'option'},...
                     'constraint', {[],       data_types},...
                     'default',    {[256,256],'sfloat'}),...
   'outparams',{{'Output image'}});
functionlist('newcolorim') = struct(...
	'display','New color image',...
   'inparams',struct('description',{'Size',   'Color space', 'Data type'},...
                     'type',       {'array',  'option',      'option'},...
                     'constraint', {[],       color_strings, data_types},...
                     'default',    {[256,256],'RGB','sfloat'}),...
   'outparams',{{'Output image'}});
functionlist('newtensorim') = struct(...
	'display','New tensor image',...
   'inparams',struct('description',{'Size',   'Tensor size', 'Data type'},...
                     'type',       {'array',  'array',      'option'},...
                     'constraint', {[],       [],            data_types},...
                     'default',    {[256,256],3,'sfloat'}),...
   'outparams',{{'Output image'}});
functionlist('deltaim') = struct(...
	'display','Discrete delta function',...
   'inparams',struct('description',{'Size',   'Data type'},...
                     'type',       {'array',  'option'},...
                     'constraint', {[],       data_types},...
                     'default',    {[256,256],'sfloat'}),...
   'outparams',{{'Output image'}});
coordinates_origin = struct('name',{'left','right','true','corner','frequency'},...
                            'description',{'Left of true center',...
                                           'Right of true center',...
                                           'True center',...
                                           'Top-left corner',...
                                           'Frequency domain'});
coordinates_options = struct('name',{'radial','math'},...
                             'description',{'Radial frequencies','Math coordinates'});
functionlist('ramp') = struct(...
	'display','Ramp',...
   'inparams',struct('description',{'Size',   'Dimension', 'Origin',          'Options'},...
                     'type',       {'array',  'array',     'option',          'optionarray'},...
                     'constraint', {[],       [],          coordinates_origin,coordinates_options},...
                     'default',    {[256,256],1,          'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('xx') = struct(...
	'display','X-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256],'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('yy') = struct(...
	'display','Y-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256],'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('zz') = struct(...
	'display','Z-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256],'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('rr') = struct(...
	'display','R-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256],'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('phiphi') = struct(...
	'display','Phi-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256],'right',           {}}),...
   'outparams',{{'Output image'}});
functionlist('thetatheta') = struct(...
	'display','Theta-coordinate',...
   'inparams',struct('description',{'Size',   'Origin',          'Options'},...
                     'type',       {'array',  'option',          'optionarray'},...
                     'constraint', {[],       coordinates_origin,coordinates_options},...
                     'default',    {[256,256,256],'right',       {}}),...
   'outparams',{{'Output image'}});
functionlist('setborder') = struct(...
	'display','Set image border',...
   'inparams',struct('description',{'Input image','Color','Size'},...
                     'type',       {'image',      'array','array'},...
                     'constraint', {[1,Inf],      [],     []},...
                     'default',    {'a',          0,      1}),...
   'outparams',{{'Output image'}});
noise_options = struct('name',{'gaussian','uniform','poisson','binary','saltpepper','brownian','pink','blue','violet'},...
                       'description',{'Gaussian noise','Uniform noise','Poisson noise','Binary noise','Salt & pepper noise',...
                                      'Brownian noise','Pink noise','Blue noise','Violet noise'});
functionlist('noise') = struct(...
   'display','Add noise',...
   'inparams',struct('description',{'Input image','Noise Type', 'Parameter 1','Parameter 2'},...
                     'type',       {'image',      'option',     'array',      'array'},...
                     'constraint', {[],           noise_options,[],           []},...
                     'default',    {'a',          'gaussian',   1,            0}),...
   'outparams',{{'Output image'}});
functionlist('drawline') = struct(...
   'display','Draw line',...
   'inparams',struct('description',{'Input image','Start Coordinates','End Coordinates','Color','Sigma'},...
                     'type',       {'image',      'array',            'array',          'array','array'},...
                     'constraint', {[2,Inf],      [],                 [],               [],     []},...
                     'default',    {'a',          [0,0],              [10,10],          255,    0}),...
   'outparams',{{'Output image'}});
functionlist('drawpolygon') = struct(...
   'display','Draw polygon',...
   'inparams',struct('description',{'Input image','Coordinates',        'Color','Mode'},...
                     'type',       {'image',      'array',              'array','option'},...
                     'constraint', {[2,Inf],      [],                   [],     {'open','closed','filled'}},...
                     'default',    {'a',          [0,0;10,0;10,10;0,10],255,    'open'}),...
   'outparams',{{'Output image'}});
functionlist('drawshape') = struct(...
   'display','Draw shape',...
   'inparams',struct('description',{'Input image','Sizes','Origin','Shape',    'Color','Sigma'},...
                     'type',       {'image',      'array','array', 'option',   'array','array'},...
                     'constraint', {[1,Inf],      [],     [],      {'ellipsoid','ball','sphere','box','box shell','diamond'},...
                                                                               [],     []},...
                     'default',    {'a',          [10,10],[5,5],   'ellipsoid',255,    0}),...
   'outparams',{{'Output image'}});
functionlist('gaussianblob') = struct(...
	'display','Add Gaussian blobs',...
   'inparams',struct('description',{'Input image','Coordinates','Sigma','Strength','Domain'},...
                     'type',       {'image',      'array',      'array','array',   'option'},...
                     'constraint', {[1,Inf],      [],           [],     [],        {'spatial','frequency'}},...
                     'default',    {'a',          [10,10],      2,      255,       'spatial'}),...
   'outparams',{{'Output image'}});

% Manipulation
interpolation_method = struct('name',{'nearest','linear','3-cubic','4-cubic','bspline','lanczos2','lanczos3','lanczos4','lanczos6','lanczos8'},...
                              'description',{'Nearest neighbor','Linear','3rd order cubic','4th order cubic','B-spline','Lanczos, a=2','Lanczos, a=3','Lanczos, a=4','Lanczos, a=6','Lanczos, a=8'});
interpolation_method_short = struct('name',{'nearest','linear','3-cubic'},...
                                    'description',{'Nearest neighbor','Linear','3rd order cubic'});
boundary_condition = struct('name',{'','mirror','asym mirror','periodic','asym periodic','add zeros','add max','add min','zero order','first order','second order','third order'},...
                            'description',{'Default (= mirror)','Mirror','Mirror and invert','Repeat periodically','Repeat periodically and invert','Add zeros','Add maximum value','Add minimum value',...
                                           'Zero order extrapolation','First order extrapolation','Second order extrapolation','Third order extrapolation'});
functionlist('mirror') = struct(...
   'display','Mirror',...
   'inparams',struct('description',{'Input image','Mirror type', 'Mirror parameter'},...
                     'type',       {'image',      'option',      'array'},...
                     'constraint', {[1,Inf],      {'x-axis','y-axis','z-axis','point','user'},[]},...
                     'default',    {'a',          'point',       []}),...
   'outparams',{{'Output image'}});
functionlist('shift') = struct(...
   'display','Shift',...
   'inparams',struct('description',{'Input image','Shift','Interpolation Method','Boundary condition'},...
                     'type',       {'image',      'array','option',              'option'},...
                     'constraint', {[1,Inf],      [],     interpolation_method,  boundary_condition},...
                     'default',    {'a',          0.5,    '3-cubic',             ''}),...
   'outparams',{{'Output image'}});
functionlist('rotation') = struct(...
   'display','Rotation around an axis',...
   'inparams',struct('description',{'Input image','Angle (rad)','Dimension 1','Dimension 2','Interpolation Method','Boundary condition'},...
                     'type',       {'image',      'array',      'array',      'array',      'option',              'option'},...
                     'constraint', {[2,Inf],      [],           [],           [],           interpolation_method,  boundary_condition},...
                     'default',    {'a',          pi/4,         1,            2,            '3-cubic',             'add zeros'}),...
   'outparams',{{'Output image'}});
functionlist('skew') = struct(...
   'display','Skew',...
   'inparams',struct('description',{'Input image','Shear','Skew', 'Axis', 'Interpolation method','Boundary condition'},...
                     'type',       {'image',      'array','array','array','option',              'option'},...
                     'constraint', {[2,Inf],      [],     [],     [],     interpolation_method,  boundary_condition},...
                     'default',    {'a',          0.4,    0,      1,      '3-cubic',             ''}),...
   'outparams',{{'Output image'}});
functionlist('affine_trans') = struct(...
   'display','Affine Transformation in 2D',...
   'inparams',struct('description',{'Input image','Zoom', 'Translation','Angle','Interpolation method'},...
                     'type',       {'image',      'array','array',      'array','option'},...
                     'constraint', {[2],          [],     [],           [],     interpolation_method_short},...
                     'default',    {'a',          1,      0,            0,      'linear'}),...
   'outparams',{{'Output image'}});
functionlist('resample') = struct(...
   'display','Resample',...
   'inparams',struct('description',{'Input image','Zoom', 'Translation','Interpolation method','Boundary condition'},...
                     'type',       {'image',      'array','array',      'option',              'option'},...
                     'constraint', {[1,Inf],      [],     [],           interpolation_method,  boundary_condition},...
                     'default',    {'a',          2,      0,            '3-cubic',             ''}),...
   'outparams',{{'Output image'}});
functionlist('subsample') = struct(...
   'display','Subsample',...
   'inparams',struct('description',{'Input image','Subsample factors'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[1,Inf],      []},...
                     'default',    {'a',          2}),...
   'outparams',{{'Output image'}});
functionlist('rebin') = struct(...
   'display','Rebin',...
   'inparams',struct('description',{'Input image','Binning'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[1,Inf],      []},...
                     'default',    {'a',          2}),...
   'outparams',{{'Output image'}});
functionlist('split') = struct(...
   'display','Split',...
   'inparams',struct('description',{'Input image','Step size'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[1,Inf],      []},...
                     'default',    {'a',          2}),...
   'outparams',{{'Output image'}});
location_options = {'symmetric','top left','top right','bottom left','bottom right'};
functionlist('extend') = struct(...
   'display','Extend/pad',...
   'inparams',struct('description',{'Input image','New size','Location', 'Value','Clip'},...
                     'type',       {'image',      'array',   'option',   'array','boolean'},...
                     'constraint', {[1,Inf],      [],        location_options,[],[]},...
                     'default',    {'a',          [256,256], 'symmetric',0,      0}),...
   'outparams',{{'Output image'}});
functionlist('cut') = struct(...
   'display','Cut/crop',...
   'inparams',struct('description',{'Input image','New size','Location'},...
                     'type',       {'image',      'array',   'option'},...
                     'constraint', {[1,Inf],      [],        location_options},...
                     'default',    {'a',          [256,256], 'symmetric'}),...
   'outparams',{{'Output image'}});
functionlist('arrangeslices') = struct(...
   'display','Arranges slices of nD image to make 2D image',...
   'inparams',struct('description',{'Input image','Number of columns'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[3,Inf],      []},...
                     'default',    {'a',          []}),...
   'outparams',{{'Output image'}});
functionlist('tile') = struct(...
   'display','Tiles tensor components',...
   'inparams',struct('description',{'Input image','Stretch?'},...
                     'type',       {'image',      'boolean'},...
                     'constraint', {[0,Inf],      []},...
                     'default',    {'a',          false}),...
   'outparams',{{'Output image'}});
functionlist('detile') = struct(...
   'display','Splits an image in subimages',...
   'inparams',struct('description',{'Input image','Tensor size'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[2,Inf],      []},...
                     'default',    {'a',          2}),...
   'outparams',{{'Output image'}});
%TODO: 'correctshift','localshift','rotation3d'

% Point
functionlist('clip') = struct(...
	'display','Grey-value clipping',...
   'inparams',struct('description',{'Input image','Minimum',   'Maximum'},...
                     'type',       {'image',      'array',     'array'},...
                     'constraint', {[],           [],          []},...
                     'default',    {'a',          0,           255}),...
   'outparams',{{'Output image'}});
functionlist('erfclip') = struct(...
   'display','Grey-value error function clipping',...
   'inparams',struct('description',{'Input image','Threshold', 'Range'},...
                     'type',       {'image',      'array',     'array'},...
                     'constraint', {[],           [],          []},...
                     'default',    {'a',          128,         64}),...
   'outparams',{{'Output image'}});
functionlist('gaussianedgeclip') = struct(...
	'display','Gaussian edge clip',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian','Truncation'},...
                     'type',       {'image',      'array',            'array'},...
                     'constraint', {[1,Inf],      [],                 []},...
                     'default',    {'a',          1,                  3}),...
   'outparams',{{'Output image'}});
functionlist('gaussianlineclip') = struct(...
   'display','Gaussian line clip',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian','Normalise to one','Truncation'},...
                     'type',       {'image',      'array',            'boolean',         'array'},...
                     'constraint', {[1,Inf],      [],                 [],                []},...
                     'default',    {'a',          1,                  0,                 3}),...
   'outparams',{{'Output image'}});
functionlist('stretch') = struct(...
   'display','Grey-value stretching',...
   'inparams',struct('description',{'Input image','Lower percentile','Upper percentile','Minimum','Maximum','Method','param1','param2'},...
                     'type',       {'image',      'array',           'array',           'array',  'array',  'option','array', 'array'},...
                     'constraint', {[],           [0 100],           [0 100],           [],       [],       {'linear','signed linear','logarithmic','signed logarithmic','erf','decade','sigmoid'},[],[]},...
                     'default',    {'a',          0,                 100,               0,        255       'linear',1,       0}),...
   'outparams',{{'Output image'}});
functionlist('hist_equalize') = struct(...
   'display','Histogram equalization',...
   'inparams',struct('description',{'Input image','Histogram to match'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          []}),...
   'outparams',{{'Output image'}});
functionlist('lut') = struct(...
   'display','Look-up table',...
   'inparams',struct('description',{'Input image','Table'},...
                     'type',       {'image',      'anytypearray'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          'parula(256)*256'}),...
   'outparams',{{'Output image'}});
functionlist('get_subpixel') = struct(...
   'display','Subpixel value extraction',...
   'inparams',struct('description',{'Input image','Points',   'method'},...
                     'type',       {'image',      'array',    'option'},...
                     'constraint', {[],           [],         {'nearest','linear','3-cubic'}},...
                     'default',    {'a',          0,          'linear'}),...
   'outparams',{{'Output values'}});

% Image Arithmetic
functionlist('plus') = struct(...
	'display','Image addition',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('minus') = struct(...
	'display','Image subtraction',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('times') = struct(...
	'display','Image element-wise multiplication',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('rdivide') = struct(...
	'display','Image element-wise division',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('mod') = struct(...
	'display','Image modulo (remainder)',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('power') = struct(...
	'display','Image element-wise power',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('select') = struct(...
	'display','Selects pixels from one image or another depending on a condition',...
   'inparams',struct('description',{'Input image 1','Input image 2','Condition image'},...
                     'type',       {'image',        'image',        'image'},...
                     'constraint', {[],             [],             []},...
                     'default',    {'a',            'b',            'c'}),...
   'outparams',{{'Output image'}});
functionlist('and') = struct(...
	'display','Image bit-wise and',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('or') = struct(...
	'display','Image bit-wise or',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('xor') = struct(...
	'display','Image bit-wise xor',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('atan2') = struct(...
	'display','Image arctangent',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('hypot') = struct(...
	'display','Image hypotenuse',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('real') = struct(...
	'display','Real component',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('imag') = struct(...
	'display','Imaginary component',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('abs') = struct(...
	'display','Absolute value or magnitude',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('phase') = struct(...
	'display','Phase of complex values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('round') = struct(...
	'display','Round samples to nearest integer',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('cos') = struct(...
	'display','Cosine of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('sin') = struct(...
	'display','Sine of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('tan') = struct(...
	'display','Tangent of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('sqrt') = struct(...
	'display','Square root of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('exp') = struct(...
	'display','Base e exponent of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('log') = struct(...
	'display','Base e logarithm of sample values',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});

% Image Comparison
functionlist('eq') = struct(...
	'display','Images are equal',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('gt') = struct(...
	'display','Image is greater than',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('ge') = struct(...
	'display','Image is greater or equal to',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('lt') = struct(...
	'display','Image is lesser than',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('le') = struct(...
	'display','Image is lesser or equal to',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('ne') = struct(...
	'display','Images are not equal',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});

% Tensor Arithmetic
functionlist('mtimes') = struct(...
	'display','Matrix multiplication',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('cross') = struct(...
	'display','Cross product',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('dot') = struct(...
	'display','Dot product',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('norm') = struct(...
	'display','Vector norm',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('trace') = struct(...
	'display','Matrix trace',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('det') = struct(...
	'display','Matrix determinant',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('inv') = struct(...
	'display','Matrix inverse',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('pinv') = struct(...
	'display','Matrix pseudoinverse',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('eig_largest') = struct(...
	'display','Largest eigenvector and value',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output eigenvector image','Output eigenvalue image'}});
functionlist('eig') = struct(...
	'display','Eigen decomposition',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output eigenvector image','Output eigenvalue image'}});
functionlist('svd') = struct(...
	'display','Singular value decomposition',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output U image','Output S image','Output V image'}});

% Filters
functionlist('convolve') = struct(...
	'display','General convolution',...
   'inparams',struct('description',{'Input image','Kernel image'},...
                     'type',       {'image',      'image'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          'b'}),...
   'outparams',{{'Output image'}});
gaussf_method = struct('name',{'fir','iir','ft','best'},...
                       'description',{'Finite impulse response','Infinite impulse response','Fourier domain filter','Best option'});
functionlist('gaussf') = struct(...
   'display','Gaussian filter',...
   'inparams',struct('description',{'Input image','Sigma','Method',     'Boundary condition','Truncation'},...
                     'type',       {'image',      'array','option',     'option',            'array'},...
                     'constraint', {[],           [],     gaussf_method,boundary_condition,  []},...
                     'default',    {'a',          1,      'best',       '',                  3}),...
   'outparams',{{'Output image'}});
filter_shape = {'rectangular','elliptic','diamond'};
functionlist('unif') = struct(...
   'display','Uniform filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('maxf') = struct(...
   'display','Maximum filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('minf') = struct(...
   'display','Minimum filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('medif') = struct(...
   'display','Median filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('percf') = struct(...
   'display','Percentile filter',...
   'inparams',struct('description',{'Input image','Percentile','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',     'array',         'option',         'option'},...
                     'constraint', {[],           [],          [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          50,          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('varif') = struct(...
   'display','Variance filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              filter_shape,     boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('gabor') = struct(...
   'display','Gabor filter',...
   'inparams',struct('description',{'Input image','Sigma','Frequency [0,0.5]','Direction [0,2*pi]'},...
                     'type',       {'image',      'array','array',            'array'},...
                     'constraint', {[],           [],     [],                 []},...
                     'default',    {'a',          5,      .1,                 pi}),...
   'outparams',{{'Output image'}});
functionlist('gabor_click') = struct(...
   'display','Interactive Gabor filter',...
   'inparams',struct('description',{'Input image','Sigma','Figure with Fourier image'},...
                     'type',       {'image',      'array','handle'},...
                     'constraint', {'2D',         [],     []},...
                     'default',    {'a',          5,      []}),...
   'outparams',{{'Output image'}});

% Filters/Differential Filters
derivative_method = struct('name',{'gaussfir','gaussiir','gaussft','finitediff','best'},...
                           'description',{'Gaussian finite impulse response','Gaussian infinite impulse response','Fourier domain Gaussian filter','Finite difference approximation','Best option'});
functionlist('derivative') = struct(...
   'display','General derivatives',...
   'inparams',struct('description',{'Input image','Order','Sigma of Gaussian','Method','Boundary condition','Truncation'},...
                     'type',       {'image',      'array','array',            'option','option',            'array'},...
                     'constraint', {[],           [],     [],                 derivative_method,...
                                                                                       boundary_condition,  []},...
                     'default',    {'a',          0,      1,                  'best',  '',                  3}),...
   'outparams',{{'Output image'}});
functionlist('dx') = struct(...
	'display','Derivative in X-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dy') = struct(...
	'display','Derivative in Y-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dz') = struct(...
	'display','Derivative in Z-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('gradientvector') = struct(...
   'display','Gradient vector',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('gradmag') = struct(...
   'display','Gradient magnitude',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('dxx') = struct(...
	'display','Second derivative in X-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dyy') = struct(...
	'display','Second derivative in Y-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dzz') = struct(...
	'display','Second derivative in Z-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dxy') = struct(...
	'display','Second derivative in XY-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dxz') = struct(...
	'display','Second derivative in XZ-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('dyz') = struct(...
	'display','Second derivative in YZ-direction',...
   'inparams',struct('description',{'Input image','Sigma of Gaussian'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('laplace') = struct(...
	'display','Laplace operator',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('hessian') = struct(...
	'display','Hessian matrix',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('dethessian') = struct(...
	'display','Det(Hessian) operator',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('dgg') = struct(...
	'display','Second derivative in gradient direction',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('dcc') = struct(...
	'display','Dcc (== Laplace - Dgg)',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('laplace_plus_dgg') = struct(...
	'display','Laplace + Dgg',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('laplace_min_dgg') = struct(...
	'display','Laplace - Dgg',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('curl') = struct(...
	'display','Vector field rotation',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('divergence') = struct(...
	'display','Vector field divergence',...
   'inparams',struct('description',{'Input image','Sigma','Method','Boundary condition','Process','Truncation'},...
                     'type',       {'image',      'array','option','option',            'array',  'array'},...
                     'constraint', {[],           [],     derivative_method,...
                                                                   boundary_condition,  [],       []},...
                     'default',    {'a',          1,      'best',  '',                  [],       3}),...
   'outparams',{{'Output image'}});
functionlist('prewittf') = struct(...
	'display','Prewitt filter',...
   'inparams',struct('description',{'Input image','Derivative dimension'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('sobelf') = struct(...
	'display','Sobel filter',...
   'inparams',struct('description',{'Input image','Derivative dimension'},...
                     'type',       {'image',      'array'},...
                     'constraint', {[],           []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});

% Filters/Adaptive Filters
functionlist('bilateralf') = struct(...
   'display','Bilateral filter',...
   'inparams',struct('description',{'Input image','Spatial sigma','Tonal sigma','Truncation','Method','Boundary condition'},...
                     'type',       {'image',      'array',        'array',      'array',     'option', 'option'},...
                     'constraint', {[],           [],             [],           [],          {'full','pwlinear','xysep','uvsep','arc'},boundary_condition},...
                     'default',    {'a',          2.0,            30.0,         2,           'xysep',  ''}),...
   'outparams',{{'Output image'}});
functionlist('kuwahara') = struct(...
   'display','Kuwahara filter',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Threshold','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'array',    'option'},...
                     'constraint', {[],           [],              filter_shape,     [],         boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       0,          ''}),...
   'outparams',{{'Output image'}});
functionlist('selectionf') = struct(...
   'display','Selection filter',...
   'inparams',struct('description',{'Input image','Control image','Size of filter','Shape of filter','Threshold','Mode',  'Boundary condition'},...
                     'type',       {'image',      'image',        'array',         'option',         'array',    'option','option'},...
                     'constraint', {[],           [],             [],              filter_shape,     [],         {'maximum','minimum'},boundary_condition},...
                     'default',    {'a',          'b',            7,               'elliptic',       0,          'minimum',''}),...
   'outparams',{{'Output image'}});
functionlist('tframehessian') = struct(...
   'display','Second derivatives driven by the structure tensor',...
   'inparams',struct('description',{'Input image','Sigma of derivative','Sigma of tensor','Sigma of Hessian'},...
                     'type',       {'image',      'array',              'array',          'array'},...
                     'constraint', {[],           [],                   [],               []},...
                     'default',    {'a',          1,                    3,                1}),...
   'outparams',{{'Output image'}});

% Filters/Binary Filters
functionlist('bdilation') = struct(...
   'display','Binary dilation',...
   'inparams',struct('description',{'Input image','Iterations','Connectivity','Edge Condition'},...
                     'type',       {'image',      'array',     'array',       'option'},...
                     'constraint', {'bin',        [],          [],            {'background','object'}},...
                     'default',    {'a',          1,           -1,            'background'}),...
   'outparams',{{'Output image'}});
functionlist('berosion') = struct(...
   'display','Binary erosion',...
   'inparams',struct('description',{'Input image','Iterations','Connectivity','Edge Condition'},...
                     'type',       {'image',      'array',     'array',       'option'},...
                     'constraint', {'bin',        [],          [],            {'background','object'}},...
                     'default',    {'a',          1,           -1,            'object'}),...
   'outparams',{{'Output image'}});
functionlist('bopening') = struct(...
   'display','Binary opening',...
   'inparams',struct('description',{'Input image','Iterations','Connectivity','Edge Condition'},...
                     'type',       {'image',      'array',     'array',       'option'},...
                     'constraint', {'bin',        [],          [],            {'special','background','object'}},...
                     'default',    {'a',          1,           -1,            'special'}),...
   'outparams',{{'Output image'}});
functionlist('bclosing') = struct(...
   'display','Binary closing',...
   'inparams',struct('description',{'Input image','Iterations','Connectivity','Edge Condition'},...
                     'type',       {'image',      'array',     'array',       'option'},...
                     'constraint', {'bin',        [],          [],            {'special','background','object'}},...
                     'default',    {'a',          1,           -1,            'special'}),...
   'outparams',{{'Output image'}});
functionlist('hitmiss') = struct(...
   'display','Hit-miss operator',...
   'inparams',struct('description',{'Input image','Structuring element'},...
                     'type',       {'image',      'image'},...
                     'constraint', {'bin',        []},...
                     'default',    {'a',          'b'}),...
   'outparams',{{'Output image'}});
functionlist('bskeleton') = struct(...
   'display','Euclidean skeleton',...
   'inparams',struct('description',{'Input image','Edge condition','End pixel condition'},...
                     'type',       {'image',      'option',        'option'},...
                     'constraint', {'bin',        {'background','object'},...
      {'loose ends away', 'natural', 'one neighbor', 'two neighbors', 'three neighbors'}},...
                     'default',    {'a',          'background',    'natural'}),...
   'outparams',{{'Output image'}});
functionlist('bpropagation') = struct(...
   'display','Binary propagation',...
   'inparams',struct('description',{'Seed image',    'Mask image',    'Iterations','Connectivity','Edge Condition'},...
                     'type',       {'image',         'image',         'array',     'array',       'option'},...
                     'constraint', {{'scalar','bin'},{'scalar','bin'},[],          [],            {'background','object'}},...
                     'default',    {'a',             'b',             0,           -1,            'object'}),...
   'outparams',{{'Output image'}});
functionlist('brmedgeobjs') = struct(...
   'display','Remove edge objects',...
   'inparams',struct('description',{'Input image','Connectivity'},...
                     'type',       {'image',      'array'},...
                     'constraint', {'bin',        []},...
                     'default',    {'a',          0}),...
   'outparams',{{'Output image'}});
functionlist('smallobjectsremove') = struct(...
   'display','Remove small objects',...
   'inparams',struct('description',{'Input image','Threshold','Connectivity'},...
                     'type',       {'image',      'array',    'array'},...
                     'constraint', {'bin',        [],         []},...
                     'default',    {'a',          10,         0}),...
   'outparams',{{'Output image'}});
functionlist('fillholes') = struct(...
   'display','Fill holes',...
   'inparams',struct('description',{'Input image','Connectivity'},...
                     'type',       {'image',      'array'},...
                     'constraint', {'bin',        []},...
                     'default',    {'a',          0}),...
   'outparams',{{'Output image'}});
functionlist('hull') = struct(...
   'display','Convex hull',...
   'inparams',struct('description',{'Input image','Fill'},...
                     'type',       {'image',      'boolean'},...
                     'constraint', {'bin',        []},...
                     'default',    {'a',          1}),...
   'outparams',{{'Output image'}});
functionlist('countneighbors') = struct(...
   'display','Count neighbours',...
   'inparams',struct('description',{'Input image','Mode',              'Connectivity','Edge condition'},...
                     'type',       {'image',      'option',            'array',       'option'},...
                     'constraint', {'bin',        {'foreground','all'},[],            {'background','object'}},...
                     'default',    {'a',          'foreground',        0,             'background'}),...
   'outparams',{{'Output image'}});
functionlist('bmajority') = struct(...
   'display','Binary majority voting',...
   'inparams',struct('description',{'Input image','Connectivity','Edge condition'},...
                     'type',       {'image',      'array',       'option'},...
                     'constraint', {'bin',        [],            {'background','object'}},...
                     'default',    {'a',          0,             'background'}),...
   'outparams',{{'Output image'}});
functionlist('getsinglepixel') = struct(...
   'display','Get single pixels from skeleton',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'bin'},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('getendpixel') = struct(...
   'display','Get end pixels from skeleton',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'bin'},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('getlinkpixel') = struct(...
   'display','Get link pixels from skeleton',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'bin'},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('getbranchpixel') = struct(...
   'display','Get branch pixels from skeleton',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'bin'},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});

% Filters/Morphology
mfilter_shape = [filter_shape,{'parabolic'}];
functionlist('dilation') = struct(...
   'display','Dilation',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('erosion') = struct(...
   'display','Erosion',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('closing') = struct(...
   'display','Closing',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('opening') = struct(...
   'display','Opening',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option'},...
                     'constraint', {[],           [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('tophat') = struct(...
   'display','Top-hat',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Edge type','Polarity','Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option',   'option',  'option'},...
                     'constraint', {[],           [],              mfilter_shape,    {'texture','object','both'},{'black','white'},boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       'texture',  'white',   ''}),...
   'outparams',{{'Output image'}});
functionlist('lee') = struct(...
   'display','Lee operator',...
   'inparams',struct('description',{'Input image','Size of filter','Shape of filter','Edge type','Sign',    'Boundary condition'},...
                     'type',       {'image',      'array',         'option',         'option',   'option',  'option'},...
                     'constraint', {[],           [],              mfilter_shape,    {'texture','object','both'},{'signed','unsigned'},boundary_condition},...
                     'default',    {'a',          7,               'elliptic',       'texture',  'unsigned',''}),...
   'outparams',{{'Output image'}});
functionlist('rankmin_closing') = struct(...
   'display','Rank-min closing',...
   'inparams',struct('description',{'Input image','Rank', 'Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array','array',         'option',         'option'},...
                     'constraint', {[],           [],     [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          2,      7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('rankmax_opening') = struct(...
   'display','Rank-max opening',...
   'inparams',struct('description',{'Input image','Rank', 'Size of filter','Shape of filter','Boundary condition'},...
                     'type',       {'image',      'array','array',         'option',         'option'},...
                     'constraint', {[],           [],     [],              mfilter_shape,    boundary_condition},...
                     'default',    {'a',          2,      7,               'elliptic',       ''}),...
   'outparams',{{'Output image'}});
functionlist('areaopening') = struct(...
   'display','Area opening or closing',...
   'inparams',struct('description',{'Input image','Size of filter','Connectivity','Polarity'},...
                     'type',       {'image',      'array',         'array',       'option'},...
                     'constraint', {[],           [],              [],            {'opening','closing'}},...
                     'default',    {'a',          7,               1,             'opening'}),...
   'outparams',{{'Output image'}});
functionlist('pathopening') = struct(...
   'display','Path opening or closing',...
   'inparams',struct('description',{'Input image','Size of filter','Polarity','Mode'},...
                     'type',       {'image',      'array',         'option',  'option'},...
                     'constraint', {[],           [],              {'opening','closing'},{'normal','constrained'}},...
                     'default',    {'a',          7,               'opening', 'normal'}),...
   'outparams',{{'Output image'}});
functionlist('hmaxima') = struct(...
   'display','H-maxima transform',...
   'inparams',struct('description',{'Input image','H',    'Connectivity'},...
                     'type',       {'image',      'array','array'},...
                     'constraint', {[],           [],     []},...
                     'default',    {'a',          10,     1}),...
   'outparams',{{'Output image'}});
functionlist('hminima') = struct(...
   'display','H-minima transform',...
   'inparams',struct('description',{'Input image','H',    'Connectivity'},...
                     'type',       {'image',      'array','array'},...
                     'constraint', {[],           [],     []},...
                     'default',    {'a',          10,     1}),...
   'outparams',{{'Output image'}});
functionlist('reconstruction') = struct(...
   'display','Reconstruction by dilation or erosion',...
   'inparams',struct('description',{'Input image','Mask',          'Size of filter','Connectivity','Polarity'},...
                     'type',       {'image',      'image',         'array',         'array',       'option'},...
                     'constraint', {[],           {'scalar','bin'},[],              [],            {'dilation','erosion'}},...
                     'default',    {'a',          'b',             7,               1,             'dilation'}),...
   'outparams',{{'Output image'}});
functionlist('asf') = struct(...
   'display','Alternating sequential filters',...
   'inparams',struct('description',{'Input image','Size range','Shape of filter','Filter type','Polarity',  'Boundary condition'},...
                     'type',       {'image',      'array',     'option',         'option',     'option',    'option'},...
                     'constraint', {[],           [],          mfilter_shape,    {'structural','reconstruction','area'},{'open-close','close-open'},boundary_condition},...
                     'default',    {'a',          [3,7,2],     'elliptic',       'structural', 'open-close',''}),...
   'outparams',{{'Output image'}});

% Filters/Diffusion
functionlist('pmd') = struct(...
   'display','Perona-Malik anisotropic diffusion',...
   'inparams',struct('description',{'Input image','Iterations','K',    'lambda','g'},...
                     'type',       {'image',      'array',     'array','array', 'option'},...
                     'constraint', {'real',       [],          [],     [],      {'Gauss','quadratic','exponential'}},...
                     'default',    {'a',          5,           10,     0.25,    'Gauss'}),...
   'outparams',{{'Output image'}});
tmp = functionlist('pmd');
tmp.display = 'Perona-Malik diffusion with Gaussian derivatives';
functionlist('pmd_gaussian') = tmp;
functionlist('aniso') = struct(...
   'display','Robust anisotropic diffusion',...
   'inparams',struct('description',{'Input image','Iterations','K',    'lambda'},...
                     'type',       {'image',      'array',     'array','array'},...
                     'constraint', {'real',       [],          [],     []},...
                     'default',    {'a',          5,           10,     0.25}),...
   'outparams',{{'Output image'}});
functionlist('ced') = struct(...
   'display','Coherence enhancing diffusion',...
   'inparams',struct('description',{'Input image','Gradient sigma','Regularization sigma','Iterations','Coefficient',       'Flavor',       'Resample'},...
                     'type',       {'image',      'array',         'array',               'array',     'option',            'option',       'boolean'},...
                     'constraint', {'real',       [],              [],                    [],          {'const','variable'},{'all','first'},[]},...
                     'default',    {'a',          1,               3,                     5,           'variable',           'first',       1}),...
   'outparams',{{'Output image'}});
%TODO: 'mcd','cpf'

% Filters/Restoration
%TODO: 'wiener','mappg','tikhonovmiller','backgroundoffset','afm_flatten'

% Segmentation
functionlist('threshold') = struct(...
	'display','Threshold',...
   'inparams',struct('description',{'Input image','Type',   'Parameter'},...
                     'type',       {'image',      'option', 'array'},...
                     'constraint', {'real',       {'isodata','otsu','minerror','triangle','background','fixed','double','volume','hysteresis'},[]},...
                     'default',    {'a',          'isodata',Inf}),...
   'outparams',{{'Output image'}});
functionlist('hist2image') = struct(...
   'display','Backmap 2D histogram to images',...
   'inparams',struct('description',{'Channel 1','Channel 2','Coordinates','Mask',          'Bins 1','Bins 2','Range 1 [min max]','Range 2 [min max]'},...
                     'type',       {'image',    'image',    'array',      'image',         'array', 'array', 'array',            'array'},...
                     'constraint', {[],         [],         [],           {'scalar','bin'},[],      [],      [],                 []},...
                     'default',    {'a',        'b',        [],           '[]',            100,     100,     -1,                 -1}),...
   'outparams',{{'Overlay on in1','Overlay on in2','ROI','Histogram mask'}});
functionlist('minima') = struct(...
	'display','Detect local minima',...
   'inparams',struct('description',{'Input image','Connectivity','Output'},...
                     'type',       {'image',      'array',       'option'},...
                     'constraint', {[],           [],            {'binary','labels'}},...
                     'default',    {'a',          1,             'binary'}),...
   'outparams',{{'Output image'}});
functionlist('maxima') = struct(...
	'display','Detect local maxima',...
   'inparams',struct('description',{'Input image','Connectivity','Output'},...
                     'type',       {'image',      'array',       'option'},...
                     'constraint', {[],           [],            {'binary','labels'}},...
                     'default',    {'a',          1,             'binary'}),...
   'outparams',{{'Output image'}});
functionlist('watershed') = struct(...
   'display','Watershed',...
   'inparams',struct('description',{'Input image','Connectivity','Maximum depth for merging','Maximum size for merging','Flags'},...
                     'type',       {'image',      'array',       'array',                    'array',                   'optionarray'},...
                     'constraint', {[],           [],            [],                         [],                        {'high first','correct','labels'}},...
                     'default',    {'a',          1,             0,                          0,                         {}}),...
   'outparams',{{'Output image'}});
functionlist('waterseed') = struct(...
   'display','Watershed initialized with a seed image',...
   'inparams',struct('description',{'Seed image',  'Grey image','Connectivity','Maximum depth for merging','Maximum size for merging','Flags'},...
                     'type',       {'image',       'image',     'array',       'array',                    'array',                   'optionarray'},...
                     'constraint', {{'bin','uint'},'real',      [],            [],                         [],                        {'high first','labels'}},...
                     'default',    {'a',           'b',         1,             0,                          0,                         {}}),...
   'outparams',{{'Output image'}});
functionlist('canny') = struct(...
   'display','Canny edge detector',...
   'inparams',struct('description',{'Input image','Sigma','lower threshold fraction','upper threshold fraction'},...
                     'type',       {'image',      'array','array',                   'array'},...
                     'constraint', {'real',       [],     [],                        []},...
                     'default',    {'a',          1.0,    0.5,                       0.9}),...
   'outparams',{{'Output image'}});
functionlist('snakeminimize') = struct(...
   'display','Minimize snake energy',...
   'inparams',struct('description',{'Input snake','External force',      'Elasticity','Rigidity','Step size','Balloon force','Iterations'},...
                     'type',       {'array',      'image',               'array',     'array',   'array',    'array',        'array'},...
                     'constraint', {[],           {'real','vector'},     [],          [],        [],         [],             []},...
                     'default',    {'s',          'gradient(gradmag(a))',0.2,         0.4,       1,          0,              20}),...
   'outparams',{{'Output snake'}});
functionlist('gvf') = struct(...
   'display','Gradient Vector Flow',...
   'inparams',struct('description',{'Input image',    'Smoothness','Iterations'},...
                     'type',       {'image',          'array',     'array'},...
                     'constraint', {{'real','scalar'},[],          []},...
                     'default',    {'a',              0.2,         80}),...
   'outparams',{{'Output image'}});
functionlist('vfc') = struct(...
   'display','Vector Field Convolution',...
   'inparams',struct('description',{'Input image',    'Kernel size','Kernel parameter'},...
                     'type',       {'image',          'array',      'array'},...
                     'constraint', {{'real','scalar'},[],           []},...
                     'default',    {'a',              41,           2}),...
   'outparams',{{'Output image'}});
functionlist('snakedraw') = struct(...
   'display','Draw snake on image',...
   'inparams',struct('description',{'Input snake', 'Image'},...
                     'type',       {'array',       'handle'},...
                     'constraint', {[],            {'2D'}},...
                     'default',    {'s',            []}),...
   'outparams',{{'Snake handle'}});
functionlist('snake2im') = struct(...
   'display','Convert snake to image',...
   'inparams',struct('description',{'Input snake', 'Image size'},...
                     'type',       {'array',       'array'},...
                     'constraint', {[],            []},...
                     'default',    {'s',           []}),...
   'outparams',{{'Output image'}});
functionlist('im2snake') = struct(...
   'display','Convert image to snake',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'bin'},...
                     'default',    {'a'}),...
   'outparams',{{'Output snake'}});
functionlist('label') = struct(...
   'display','Label objects',...
   'inparams',struct('description',{'Input image','Connectivity','Minumum object size','Maximum object size','Boundary condition'},...
                     'type',       {'image',      'array',       'array',              'array',              'option'},...
                     'constraint', {'bin',        [],            [],                   [],                   boundary_condition},...
                     'default',    {'a',          0,             0,                    0,                    ''}),...
   'outparams',{{'Output image'}});
functionlist('relabel') = struct(...
   'display','Renumber labels in a labeled image',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {'uint'},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('displaylabelnumbers') = struct(...
   'display','Overlay the label numbers on a figure window',...
   'inparams',struct('description',{'Figure window','Label image'},...
                     'type',       {'handle',       'image'},...
                     'constraint', {'2D',           'uint'},...
                     'default',    {[],             'a'}),...
   'outparams',{{}});
functionlist('traceobjects') = struct(...
   'display','Trace labeled objects',...
   'inparams',struct('description',{'Input image', 'Labels','Connectivity','Output'},...
                     'type',       {'image',       'array', 'array',       'option'},...
                     'constraint', {{'uint','bin'},[],      [],            {'chain code','polygon','convex hull'}},...
                     'default',    {'a',           [],      2,             'polygon'}),...
   'outparams',{{'Traces'}});
functionlist('countingframe') = struct(...
   'display','Apply counting frame',...
   'inparams',struct('description',{'Input image', 'Frame size'},...
                     'type',       {'image',       'array'     },...
                     'constraint', {{'uint','bin'},[]          },...
                     'default',    {'a',           []          }),...
   'outparams',{{'Output image'}});
%TODO: 'splitandmerge'

% Transforms
ft_options = struct('name',{'real','fast','corner','symmetric'},...
                    'description',{'Produce a real-valued output',...
                                   'Pad the input to a "nice" size',...
                                   'The origin is the top-left corner',...
                                   'Use symmetric normalization'});
functionlist('ft') = struct(...
   'display','Fourier transform',...
   'inparams',struct('description',{'Input image','Options',    'Process'},...
                     'type',       {'image',      'optionarray','array'},...
                     'constraint', {[],           ft_options,   []},...
                     'default',    {'a',          {},           []}),...
   'outparams',{{'Output image'}});
functionlist('ift') = struct(...
   'display','Inverse Fourier transform',...
   'inparams',struct('description',{'Input image','Options',    'Process'},...
                     'type',       {'image',      'optionarray','array'},...
                     'constraint', {[],           ft_options,   []},...
                     'default',    {'a',          {},           []}),...
   'outparams',{{'Output image'}});
functionlist('riesz') = struct(...
   'display','Riesz transform',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('dt') = struct(...
   'display','Euclidean distance transform',...
   'inparams',struct('description',{'Input image','Edge Condition','Method'},...
                     'type',       {'image',      'option',        'option'},...
                     'constraint', {'bin',        {'background','object'},{'fast', 'ties', 'true', 'brute force'}},...
                     'default',    {'a',          'object',        'fast'}),...
   'outparams',{{'Output image'}});
functionlist('vdt') = struct(...
   'display','Vector components of Euclidean distance transform',...
   'inparams',struct('description',{'Input image','Edge Condition','Method'},...
                     'type',       {'image',      'option',        'option'},...
                     'constraint', {'bin',        {'background','object'},{'fast', 'ties', 'true', 'brute force'}},...
                     'default',    {'a',          'object',        'fast'}),...
   'outparams',{{'Output image'}});
functionlist('gdt') = struct(...
   'display','Grey-weighted distance transform',...
   'inparams',struct('description',{'Input image','Weight image','Chamfer Size'},...
                     'type',       {'image',      'image',       'option'},...
                     'constraint', {'bin',        'real',        {1,3,5}},...
                     'default',    {'a',          'b',           3}),...
   'outparams',{{'Output image'}});
%TODO: 'nufft_type1','nufft_type2','radoncircle'

% Analysis
measure_options = measure('features');
functionlist('measure') = struct(...
   'display','Measure',...
   'inparams',struct('description',{'Object image','Grey-value image','Measurement',  'Object IDs','Connectivity'},...
                     'type',       {'image',       'image',           'optionarray',  'array',     'array'},...
                     'constraint', {{'bin','uint'},[],                measure_options,[],          []},...
                     'default',    {'a',           '[]',              'size',         [],          0}),...
   'outparams',{{'Output measurement data'}});
functionlist('msr2obj') = struct(...
   'display','Convert labels to measurements',...
   'inparams',struct('description',{'Label image','Measurement data','Feature name','Feature value'},...
                     'type',       {'image',      'measurement',     'measureid',   'array'},...
                     'constraint', {0,            0,                 2,             0},...
                     'default',    {'a',          'msr',             '',            1}),...
   'outparams',{{'Output image'}});
structuretensor_outputs = {'l1','l2','l3','orientation','phi1','theta1','phi2','theta2','theta3',...
                           'energy','anisotropy1','anisotropy2','cylindrical','planar'};
functionlist('structuretensor') = struct(...
   'display','Structure tensor',...
   'inparams',struct('description',{'Input image','Derivative sigma','Tensor sigma','Outputs',              'Method',     'Boundary condition','Truncation'},...
                     'type',       {'image',      'array',           'array',       'optionarray',          'option',     'option',            'array'},...
                     'constraint', {[],           [],                [],            structuretensor_outputs,gaussf_method,boundary_condition,  []},...
                     'default',    {'a',          1,                 5,             {},                     'best',       '',                  3}),...
   'outparams',{{'Output image'}}); %TODO: this doesn't work. We need as many output arguments as elements selected in Outputs. How???
findshift_method = struct('name',{'integer only','cc','ncc','cpf','mts','iter','proj'},...
                          'description',{'Cross-correlation, integer location',...
                                         'Cross-correlation, sub-pixel location',...
                                         'Normalized cross-correlation',...
                                         'Phase of normalized cross-correlation',...
                                         'Gradient based',...
                                         'Iterative ''mts''',...
                                         'Iterative ''mts'' on each projection'});
granulometry_options = {'reconstruction','shifted','interpolate','subsample','non-constrained','robust'};
functionlist('granulometry') = struct(...
	'display','Granulometry',...
   'inparams',struct('description',{'Input image','Mask image',    'Scales',           'Type',                'Polarity',           'Options'},...
                     'type',       {'image',      'image',         'array',            'option',              'option',             'optionarray'},...
                     'constraint', {[],           {'scalar','bin'},[],                 {'isotropic','length'},{'closing','opening'},granulometry_options},...
                     'default',    {'a',          '[]',            'sqrt(2).^([1:12])','isotropic',           'opening',            {}}),...
   'outparams',{{'Distribution'}});
functionlist('chordlength') = struct(...
   'display','Chord length distribution',...
   'inparams',struct('description',{'Input image','Mask image',    'Number of probes','Maximum chord length','Correlation estimator'},...
                     'type',       {'image',      'image',         'array',           'array',               'option'},...
                     'constraint', {[],           {'scalar','bin'},[],                [],                    {'random','grid'}},...
                     'default',    {'a',          '[]',            100000,            100,                   'random'}),...
   'outparams',{{'Distribution'}});
functionlist('paircorrelation') = struct(...
   'display','Pair correlation function',...
   'inparams',struct('description',{'Input image','Mask image',    'Number of probes','Maximum correlation length','Correlation estimator','Options'},...
                     'type',       {'image',      'image',         'array',           'array',                     'option',               'optionarray'},...
                     'constraint', {[],           {'scalar','bin'},[],                [],                          {'random','grid'},      {'covariance','volume_fraction','volume_fraction^2'}},...
                     'default',    {'a',          '[]',            100000,            100,                         'random',               {}}),...
   'outparams',{{'Distribution'}});
functionlist('autocorrelation') = struct(...
   'display','Auto-correlation',...
   'inparams',struct('description',{'Input image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image'}});
functionlist('crosscorrelation') = struct(...
   'display','Cross-correlation',...
   'inparams',struct('description',{'Input image 1','Input image 2'},...
                     'type',       {'image',        'image'},...
                     'constraint', {[],             []},...
                     'default',    {'a',            'b'}),...
   'outparams',{{'Output image'}});
functionlist('findshift') = struct(...
	'display','Find shift',...
   'inparams',struct('description',{'Input image 1','Input image 2','Method','Parameter','Maximum shift'},...
                     'type',       {'image',        'image',        'option','array',    'array'},...
                     'constraint', {[],             [],             findshift_method,[], []},...
                     'default',    {'a',            'b',            'integer only',  0,  []}),...
   'outparams',{{'Shift'}});
subpix_method = struct('name',{'linear','parabolic','gaussian','parabolic nonseparable','gaussian nonseparable'},...
                        'description',{'Center of gravity over 3 pixels',...
                                       'Parabolic fit over 3 pixels',...
                                       'Gaussian fit over 3 pixels',...
                                       'Parabolic fit, 2D or 3D images only',...
                                       'Gaussian fit, 2D or 3D images only'});
functionlist('findminima') = struct(...
   'display','Find local minima',...
   'inparams',struct('description',{'Input image','Sub-pixel method'},...
                     'type',       {'image',      'option'},...
                     'constraint', {[],           subpix_method},...
                     'default',    {'a',          'parabolic'}),...
   'outparams',{{'Output coordinate array'}});
functionlist('findmaxima') = struct(...
   'display','Find local maxima',...
   'inparams',struct('description',{'Input image','Sub-pixel method'},...
                     'type',       {'image',      'option'},...
                     'constraint', {[],           subpix_method},...
                     'default',    {'a',          'parabolic'}),...
   'outparams',{{'Output coordinate array'}});
functionlist('subpixlocation') = struct(...
   'display','Find sub-pixel location of extrema',...
   'inparams',struct('description',{'Input image','Integer coordinates','Sub-pixel method','Polarity'},...
                     'type',       {'image',      'array',              'option',          'option'},...
                     'constraint', {[],           [],                   subpix_method,     {'maximum','minimum'}},...
                     'default',    {'a',          [],                   'parabolic',       'maximum'}),...
   'outparams',{{'Output coordinate array'}});
%TODO: 'msr2ds','scalespace','morphscales','scale2rgb'
%TODO: 'curvature','pst','quadraturetensor'
%TODO: 'find_affine_trans','fmmatch'
%TODO: 'opticflow','findlocalshift','findlocmax'

% Statistics
functionlist('sum') = struct(...
   'display','Sum projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{},           {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('prod') = struct(...
   'display','Product projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{},           {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('mean') = struct(...
   'display','Mean projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{},           {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('median') = struct(...
   'display','Median projection',...
   'inparams',struct('description',{'Input image', 'Mask image',    'Dimensions'},...
                     'type',       {'image',       'image',         'array'},...
                     'constraint', {{'noncomplex'},{'scalar','bin'},[]},...
                     'default',    {'a',           '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('percentile') = struct(...
   'display','Percentile projection',...
   'inparams',struct('description',{'Input image', 'Percentile','Mask image',    'Dimensions'},...
                     'type',       {'image',       'array',     'image',         'array'},...
                     'constraint', {{'noncomplex'},[],          {'scalar','bin'},[]},...
                     'default',    {'a',           50,          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('max') = struct(...
   'display','Maximum projection',...
   'inparams',struct('description',{'Input image', 'Mask image',    'Dimensions'},...
                     'type',       {'image',       'image',         'array'},...
                     'constraint', {{'noncomplex'},{'scalar','bin'},[]},...
                     'default',    {'a',           '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('min') = struct(...
   'display','Minimum projection',...
   'inparams',struct('description',{'Input image', 'Mask image',    'Dimensions'},...
                     'type',       {'image',       'image',         'array'},...
                     'constraint', {{'noncomplex'},{'scalar','bin'},[]},...
                     'default',    {'a',           '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('std') = struct(...
   'display','Standard deviation projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{'real'},     {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('var') = struct(...
   'display','Variance projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{'real'},     {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('any') = struct(...
   'display','Any projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{'real'},     {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('all') = struct(...
   'display','All projection',...
   'inparams',struct('description',{'Input image','Mask image',    'Dimensions'},...
                     'type',       {'image',      'image',         'array'},...
                     'constraint', {{'real'},     {'scalar','bin'},[]},...
                     'default',    {'a',          '[]',            []}),...
   'outparams',{{'Output image'}});
functionlist('diphist') = struct(...
   'display','Histogram',...
   'inparams',struct('description',{'Input image','Range [min,max]','Number of bins','Display mode'},...
                     'type',       {'image',      'array',          'array',         'option'},...
                     'constraint', {{'noncomplex','scalar'},[],     [],              {'stem','bar','line'}},...
                     'default',    {'a',          [0,255],          256,             'stem'}));
functionlist('diphist2d') = struct(...
   'display','2D histogram',...
   'inparams',struct('description',{'Channel 1','Channel 2','Mask',          'Range 1 [min max]','Range 2 [min max]','Bins 1','Bins 2','Contour plot','Log plot','Filled contours','Labeled contours','Number of contours'},...
                     'type',       {'image',    'image',    'image',         'array',            'array',            'array', 'array', 'boolean',     'option',  'boolean',        'boolean',         'array'},...
                     'constraint', {'scalar',   'scalar',   {'scalar','bin'},[],                 [],                 [],      [],      [],            {'none','x-axis','y-axis','z-axis','xy-axes','xyz-axes'},[],[],[]},...
                     'default',    {'a',        'b',        '[]',            [],                 [],                 100,     100,     0,             'none',    0,                0,                 -1}),...
   'outparams',{{'Histogram image','Contour plot handle'}});
functionlist('getmaximumandminimum') = struct(...
   'display','Maximum and minimum sample values',...
   'inparams',struct('description',{'Input image','Mask'},...
                     'type',       {'image',      'image'},...
                     'constraint', {[],           {'scalar','bin'}},...
                     'default',    {'a',          '[]'}),...
   'outparams',{{'Extrema'}});
functionlist('getsamplestatistics') = struct(...
   'display','First four central moments of sample values',...
   'inparams',struct('description',{'Input image','Mask'},...
                     'type',       {'image',      'image'},...
                     'constraint', {[],           {'scalar','bin'}},...
                     'default',    {'a',          '[]'}),...
   'outparams',{{'Moments'}});
functionlist('bbox') = struct(...
   'display','Bounding box of an n-D binary image',...
   'inparams',struct('description',{'Input binary image'},...
                     'type',       {'image'},...
                     'constraint', {[]},...
                     'default',    {'a'}),...
   'outparams',{{'Output image','Bounding box'}});
functionlist('radialsum') = struct(...
   'display','Radial sum',...
   'inparams',struct('description',{'Input image','Mask image',    'Bin size','Maximum radius','Center'},...
                     'type',       {'image',      'image',         'array',   'option',        'option'},...
                     'constraint', {{},           {'scalar','bin'},[],        {'inner radius','outer radius'},coordinates_origin},...
                     'default',    {'a',          '[]',            1,         'outer radius',  'right'}),...
   'outparams',{{'Output image'}});
functionlist('radialmean') = struct(...
   'display','Radial mean',...
   'inparams',struct('description',{'Input image','Mask image',    'Bin size','Maximum radius','Center'},...
                     'type',       {'image',      'image',         'array',   'option',        'option'},...
                     'constraint', {{},           {'scalar','bin'},[],        {'inner radius','outer radius'},coordinates_origin},...
                     'default',    {'a',          '[]',            1,         'outer radius',  'right'}),...
   'outparams',{{'Output image'}});
functionlist('radialmin') = struct(...
   'display','Radial minimum',...
   'inparams',struct('description',{'Input image', 'Mask image',    'Bin size','Maximum radius','Center'},...
                     'type',       {'image',       'image',         'array',   'option',        'option'},...
                     'constraint', {{'noncomplex'},{'scalar','bin'},[],        {'inner radius','outer radius'},coordinates_origin},...
                     'default',    {'a',           '[]',            1,         'outer radius',  'right'}),...
   'outparams',{{'Output image'}});
functionlist('radialmax') = struct(...
   'display','Radial maximum',...
   'inparams',struct('description',{'Input image', 'Mask image',    'Bin size','Maximum radius','Center'},...
                     'type',       {'image',       'image',         'array',   'option',        'option'},...
                     'constraint', {{'noncomplex'},{'scalar','bin'},[],        {'inner radius','outer radius'},coordinates_origin},...
                     'default',    {'a',           '[]',            1,         'outer radius',  'right'}),...
   'outparams',{{'Output image'}});
error_measures = struct('name',{'MSE','RMSE','ME','MAE','IDivergence','InProduct','LnNormError','PSNR','SSIM','MutualInformation'},...
                              'description',{'Mean square error',...
                                             'Root mean square error',...
                                             'Mean error',...
                                             'Mean absolute error',...
                                             'I-divergence measure',...
                                             'Sum of product',...
                                             '2nd order norm difference',...
                                             'Peak signal-to-noise ratio (dB)',...
                                             'Structural similarity index',...
                                             'Mutual information (bits)'});
functionlist('errormeasure') = struct(...
   'display','Compare two images',...
   'inparams',struct('description',{'Input image 1','Input image 2','Mask',          'Method'},...
                     'type',       {'image',        'image',        'image',         'option'},...
                     'constraint', {[],             [],             {'scalar','bin'},error_measures},...
                     'default',    {'a',            'b',            '[]',            'MSE'}),...
   'outparams',{{'Measure'}});
functionlist('noisestd') = struct(...
	'display','Estimate standard deviation of noise',...
   'inparams',struct('description',{'Input image',    'Mask'},...
                     'type',       {'image',          'image'},...
                     'constraint', {{'scalar','real'},{'scalar','bin'}},...
                     'default',    {'a',              '[]'}),...
   'outparams',{{'Standard deviation'}});
functionlist('entropy') = struct(...
   'display','Entropy',...
   'inparams',struct('description',{'Input image',    'Number of histogram bins'},...
                     'type',       {'image',          'array'},...
                     'constraint', {{'scalar','real'},[]},...
                     'default',    {'a',              256}),...
   'outparams',{{'Entropy'}});
%TODO: 'cal_readnoise'

%
% Add the user's own functions described in LOCALDIPMENUS
%

newfuncs = [];
if exist('localdipmenus','file')
   try
      [menulist,newfuncs] = localdipmenus(menulist);
   catch exception
      warning('Evaluation of LOCALDIPMENUS failed:')
      disp(exception.message)
   end
end
if ~isempty(newfuncs)
   functionlist = [functionlist;newfuncs(:)];
end

% diff -qsr ../dipimage dip/share/dipimage | sed '/identical$/d' | sed '/^Only in/d'
% \cp dip/share/dipimage/dipmenus.m ../dipimage/
