%\documentstyle[manual]{report}
\documentclass[12pt]{report}
\usepackage{manual,epsf,url}

%\usepackage{epsf}


\def\QI{{\sc QuantIm}}
\def\VQ{{\sc 4}}
\def\PC{Paper coordinates}    \def\WC{World coordinates}

%\textheight250mm
%------------------------------------------------------------------------
\setcounter{page}{-2}\pagestyle{empty}

\begin{document}
\ \vskip4cm
{\centering\huge QuantIm\par}
\vskip1cm
{\LARGE\sc\centering C/C++ Library\\ for Scientific image processing\par}

\vskip15mm
\begin{center}
 \epsfysize105mm \epsffile{Por2_120-opened_double_3Dview-c.eps}\par
\end{center}

\vfill
{\sf Copyright \copyright H.~J.~Vogel, 1999-2008
\hfill Version 4.01$\beta$ 20.10.2008}

\break

%------------------------------------------------------------------------
\begingroup\leftskip=30mm\parindent=0mm\sf\ \vfill

{\large\sc Legal Considerations\par}
\smallskip

\QI\ is free software; which means that you are free to use it and to redistribute free and verbatim copies of the source code. \QI\ is not in the public domain, however, it is protected by copyright.

$\bullet$ You are free to modify the source of \QI\ for your own, private use.

$\bullet$ You may distribute modified, non-commercial versions which retain the name ``\QI'', provided that (i)~you indicate these modifications clearly in the file ``quantim4.h'' under ``modifications'' as well as at the beginning of every single file that you modified or added, (ii)~you distribute it under the same legal terms as \QI\ is distributed, and (iii)~you include the copyright notice and the first paragraph of the file ``quantim4.h'' without any change.

$\bullet$ You may incorporate parts or all of \QI\ into your own non-commercial software and distribute it, provided that (i)~you incorporate the \QI\ copyright notice at a prominent place in your software and documentation, and (ii)~you distribute it under the same legal terms as \QI\ is distributed.

$\bullet$ You are not allowed to include \QI\ nor any part of it in any product that is sold commercially, i.e.~whose cost exceeds that of media, shipping and handling, without prior written consent of Hans-J\"org Vogel.

\vskip5mm

{\sc
\QI\ is licensed free of charge. Therefore all the files which in their entirety constitute \QI, are provided ``as is'', without warranty of any kind, whether expressed or implied. You are responsible for ascertaining the fitness of \QI\ for any specific use, and consequently you assume all the responsibilities and cost that may arise from using it.
}

\vskip10mm

Hans-J\"org Vogel\\
UFZ - Helmhotz Center for Environmental Research\\
Department Soil Physics\\
Theodor-Lieser-Str.~4\\
D-06120 Halle\\
GERMANY\\
{\smallskip \small \par \tt e-mail: hans-joerg.vogel@ufz.de\\}



\endgroup\break

\tableofcontents\pagestyle{empty}

\vfill\break



\setcounter{page}{1}\pagestyle{plain}




\chapter{Introduction and concepts}

\QI\ was created for analyzing 2-dimensional and 3-dimensional images. When using commercial or free software, it is often hard to understand what is going on exactly when pushing buttons which is unacceptable from a scientific point of view and is why the \QI\ project was started. An other motivation for the ongoing development of \QI\ is that it can be used on any computer system, the only requirement is a C/C++ compiler. There is no fancy GUI so you will need some basic knowledge of C/C++ - which actually is not too difficult. 

To communicate with the rest of the world, the input and output format of \QI\ is TIFF which is the most common bitmap format. This is established in \QI\ by using the standard library {\tt libtiff} and the development files {\tt libtiff-dev} which are available for any computer platform using a standard package manager or an external file server. It should be installed somewhere in the search path of your computer. 3D-images are handled by \QI\ as grey level or binary data using an own format but can be converted to vgi or dx (data explorer).
The only restriction for the size of images is the RAM of your system.

The few routines to produce eps-graphics are based on the excellent library {\tt PSgraf3} of Kurt Roth which which is automatically installed alongside \QI.

\bigskip
The main features of \QI\ are:
\begin{itemize}
\item Algorithms for 2D/3D grey scale image processing for image filtering and segmentation.
\item Algorithms for the quantification of 2D/3D binary images, including methods of mathematical morphology, topological analysis and image intersection.
\item Tools to generate 2D/3D random fields with predefined properties. 
\end{itemize}

\bigskip
{\bf Contributors:} \quad Thanks to Uli Weller and Steffen Schl\"uter for adding some highly useful functions. 

\chapter{Installation and Use in a LINUX/UNIX Environment}
To use the functions of \QI\ in your own programs, you may directly include the corresponding source files. The preferable way, however, is to link the \QI\ library to your programs.

\section{Creating the \QI\ Library}
\begingroup\leftskip=5mm\parindent=-5mm

$\bullet$\quad Copy the directory {\tt quantim\VQ\_distribution.tgz} from the distribution medium to a convenient place in your file system. 

$\bullet$\quad Extract the archive using\\ 
$>$ {\tt tar -xvzf quantim\VQ\_distribution.tgz}

$\bullet$\quad Make sure that the {\tt libtiff} and {\tt libtiff-\tt dev} packages are installed. These are standard package that you can retrieve from your prefered package manager or directly in a terminal (Debian or Ubuntu) by:\\
$>$ {\tt sudo apt-get install libtiff4 libtiff4-dev}


$\bullet$\quad Create the library by\\
$>$ {\tt cd quantim\_distribution}\\
$>$ {\tt sh install.sh }

\hskip5mm This will create the file {\tt libQuantim4.a} in your source directory and move the library {\tt libQuantim4.a} and the header file {\tt quantim4.h} to the standard search path directories {\tt /usr/local/lib} and {\tt /usr/local/include}. This step requires root privileges.


$\bullet$ \quad Good luck! 

\endgroup


\section{Using \QI}
To use \QI\, include the header {\tt quantim\VQ.h} into your program. Then, if the library {\tt libQuantim\VQ.a} has been copied to a place in the search path of the compiler, compile the program with the option {\tt -lQuantim\VQ~-ltiff -lPSgraf3 -lm}, for example

\qquad{\tt g++ -o program myProgram.c -lQuantim4 -ltiff -lPSgraf3 -lm}

If the compiler cannot find the library and/or the header file, you must include the paths explicitly. Assuming that you have copied the library to {\tt /a/b/c/d}, and the header file to {\tt /x/y} the program can be compiled as

\qquad{\tt g++ myProgram.c -L/a/b/c/d -I/x/y -lQuantim4 -ltiff -lPSgraf3 -lm}


\section{New features of the actual \QI~version}

\QI\VQ\ has been modified substantially so that programs written for previous versions may not compile with this version of \QI. This has been sacrificed for a more intuitive structure of image variables, the possibility to handle 16-bit images and the usage of the same functions for different image types (2D, 3D, grey scale, color-rgb). Especially {\tt GetImage} and {\tt SaveImage} is now {\tt LoadImage} and {\tt StoreImage}, while most of the old function are still included.



%------------------------------------------------------------------------
\chapter{Reference Manual}


\section{Basic image structure}
All images are identified by a structure of variables defined in {\tt quantim\VQ.h}:

\smallskip
typedef struct\\
       \{\\
       char             name[127];\\
       char             itype[5];\\
       unsigned char    *pix;\\
unsigned int	ndim;\\
unsigned int nchannel;\\
unsigned int *dim;\\
double *res;\\
unsigned int numbits;\\
unsigned int numbytes;\\ 	
       \} image\_cc;\\[1mm]

\argu{name}{Image name without any extension.}
\argu{itype}{Image type {\tt gry}=grey scale, {\tt gry16}=16bit/pixel grey scale, {\tt rgb}=RGB-image, {\tt ddd}= 3D grey scale, {\tt ddd16}= 3D grey scale 16bit/pixel, {\tt btd}= 3D binary, {\tt doub}= double precision 2D (only for internal use), {\tt doub3}= double precision 3D (only for internal use).}
\argu{*pix}{Pointer to the image data stored sequentially row by row.}
\argu{ndim}{Number of dimensions.} 
\argu{nchannel}{Number of channels per pixel.}
\argu{*dim}{Array of {\tt ndim} elements containing the size of the image in each dimension.}
\argu{*res}{Array of {\tt ndim} elements containing the size of a pixel in each dimension.}
\argu{numbits}{Number of bits per pixel.} 
\argu{numbytes}{Number of bytes per pixel.}

Note that \QI\ can only handle data in little Endian byte order (Intel byte order), i.e. where the most significant bit arrives last. Moreover, \QI\ assumes an index order in which x changes fastest. 16-bit data has to be unsigned, i.e. the gray values are only allowed to be in the range [0;65535].
\section{Image types}
\QI\ handles the following types of images:
\begin{itemize}
\item {\bf 2D grey-scale *.tif} \quad 8 bits/pixels or 16 bits/pixels
\item {\bf 2D binary *.tif} \quad also 8 bit/pixels but the pixel values are typically only 0 (black) or 255 (white).
\item {\bf 2D rgb-images *.tif} \quad 3 channels \'a 8 bit/pixels, byte1=red, byte2=green, byte3=blue.
\item {\bf 3D grey scale *.ddd} \quad 8 bit/voxel [0,255] (internal format of \QI -- 64 byte header followed by binary raw data written with little endian byte order). 
\item {\bf 3D grey scale *.ddd16} \quad 16 bit/voxel [0,65535] (internal format of \QI -- 64 byte header followed by binary raw data written with little endian byte order). 
\item {\bf 3D grey scale *.raw} \quad 16 bit/voxel {\tt unsigned int} with *.vgi or \quad 8 and 16 bit/voxel with *.mhd description file. 
\item {\bf 3D grey scale *.vol} \quad 32 bit/voxel {\tt float} with *.vgi description file. This type is internally converted to 16-bit integer.  
%\item {\bf multi-dimensional grey scale *.xxd} \quad 8 bits or 16 bits/pixel. 
\item {\bf 3D binary *.btd}    \quad 1 bit/voxel [0,1] (internal format of \QI )
\end{itemize}


\section{Basic image handling (all types)}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *LoadImage(char *buf)}{ 
Loads images of any type.}
\argu{buf}{Name of the image to be loaded (with or without extension).}
\return{pointer to the loaded image.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *LoadMetaImage(char *buf)}{ 
Loads 3D images in the standard file format of ITK, where *.mhd contains the meta data and *.raw contains the binary block of raw data.}
\argu{buf}{Name of the image to be loaded (with or without .mhd extension).}
\return{pointer to the loaded image.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *LoadRaw(char *buf, int cols, int rows, int layers, int offset, int nbyte)}{ 
Loads 3D raw images, where the meta information is given by arguments. Little Endian byte order and unsigned data required.}
\argu{buf}{Name of the image to be loaded (with extension).}
\argu{cols}{Number of columns (voxels in x dimension).}
\argu{rows}{Number of rows (voxels in y dimension).}
\argu{layers}{Number of layers (voxels in z dimension).}
\argu{offset}{Byte offset to the first voxel, e.g. 64 for *.ddd images.}
\argu{nbytes}{Number of bytes per voxel (1 for 8-bit, 2 for 16-bit).}
\return{pointer to the loaded image.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void StoreImage(image\_cc *im, char *buf)\par
void StoreImage(image\_cc *im)}{
Saves the images of any type.}
\argu{im} {Pointer to the image.}
\argu{buf} {Name of the image to be saved. When the function is used without {\tt *buf}, {\tt im-$>$name} is used as file name instead.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void StoreMetaImage(image\_cc *im, char *buf)\par
void StoreMetaImage(image\_cc *im)}{
Saves a 3D image of any type in ITK MetaImage format (*.mhd and *.raw). Images with btd format (1-bit) are converted into ddd images (8-bit).}
\argu{im} {Pointer to the image.}
\argu{buf} {Name of the image to be saved. When the function is used without {\tt *buf}, {\tt im-$>$name} is used as file name instead. }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void StoreRaw(image\_cc *im, char *buf)\par
void StoreRaw(image\_cc *im)}{
Saves a 3D image of any type in raw format (*.mhd and *.raw). Images with btd format (1-bit) are converted into ddd images (8-bit). Important meta information is stored in a textfile with the same name.}
\argu{im} {Pointer to the image.}
\argu{buf} {Name of the image to be saved. When the function is used without {\tt *buf}, {\tt im-$>$name} is used as file name instead.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void SavePaletteImage(image\_cc *im, char *buf)}{
Saves an 8-bit image (only 2D grey scale) to a Palette Color TIFF-file.}
\argu{im} {Pointer to the image.}
\argu{buf} {Name of the tiff-image to be saved.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void SavePrinciplePlanes(image\_cc *im, char * name)}{
Saves the central 2D planes (xy, xz, yz) of a 3D image using the given {\tt name}.}
\argu{im} {Pointer to the 3D image.}
\argu{name} {Name of resulting 2D images:  'plane\_[xy,xz,yz]\_name'}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *InitImage(int x, int y, int val, char *type)\par
image\_cc *InitImage(int x, int y, int z, int val, char *type)\par
image\_cc *InitImage(image\_cc *im, int val)\par
image\_cc *InitImage(image\_cc *im)
}{
Initiates a new image and allocates the required memory.}
\argu{x,y,(z)}{Number of pixels in x, y, and z direction.}
\argu{val}{Initial value of each pixels.}
\argu{im}{image whose structure (dimensions aso) is copied.}
\argu{type}{Type of image (optional): {\tt gry}=grey scale, {\tt gry16}=16 bits grey scale, {\tt rgb}=RGB-image, {\tt ddd}= 3D grey scale, , {\tt xxd}= multi-dimensional grey scale, {\tt btd}= 3D binary. The default type is 8-bit grey scale for 2D and 3D.}
\return{Pointer to the new image.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *InitRandImage(int col, int row, double rx, double ry, double cx, double cy, int mode, double *cdf)\par 
image\_cc *InitRandImage(int col, int row, int dep, double rx, double ry, double rz, double cx, double cy, double cz, int mode, double *cdf)\par
}{              % DESCRIPTION
Returns a random 2D or 3D image optionally with defined grey distribution function (equal distribution, Gauss or predefined by a given {\tt cdf}), defined correlation length and defined correlation model (Gauss, Lorentz, Exponential, von Karman).} 
%To get different realzations you have to change the \QI\ varialbe {\tt IDUM} (default is -1). 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{col, row, dep}{dimensions of the generated image} 
\argu{rx, ry, rz}{size of pixel in x, y, z}
\argu{cx, cy, cz}{correlation lengths (number of pixel) in x, y, z}
\argu{mode} {0: equal distribution without any correlation (cx,cy,cz and cdf have no meaning here)\\
     1: equal grey distribution with  gaussian correlation\\  
     2: predefined grey distribution (cdf) and gaussian correlation\\   
     3: Gaussian correlation (cdf have no meaning here)\\
     4: Lorentz-Correlation model (cdf have no meaning here)\\
     5: Exponential-Correlation model (cdf have no meaning here)\\
     6: von Karman-Correlation model (cdf have no meaning here)\\
 }
\argu{*cdf}{cdf of grey levels}
\return{pointer to the generated image}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *CopyImage(image\_cc *im)
}{
Makes a copy of an image.}
\argu{*im}{Pointer to the original image.}
\return{Pointer to the copy.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void DeleteImage(image\_cc *im)
}{
Delete an image and deallocate memory.}
\argu{im} {Pointer to the image.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
int rPixel(unsigned long i, image\_cc *im)\par
int rPixel(int x, int y, image\_cc *im)\par
int rPixel(int x, int y, image\_cc *im, unsigned char *value, unsigned char *value, unsigned char *value)\par
int rPixel(int x, int y, image\_cc *im, unsigned char *value)\par
int rPixel(int x, int y, int z, image\_cc *im)
}{
Reads the value of a pixel.}
\argu{i}{offset of the pixel within the stored 1-D array of image data (for 2d and 3d images).}
\argu{x, y, z}{Coordinates of the pixel.}
\argu{im} {Pointer to the image.}
\argu{*value} {Address to which the pixel values are written. For RGB images a pointer to a 3-element array containing the RGB values is also possible.}
\return{Value of the pixel, or 1/3(R+G+B) for rgb-images.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void wPixel(unsigned long i, image\_cc *im, int value)\par
void wPixel(int x, int y, image\_cc *im, int value)\par
void wPixel(int x, int y, image\_cc *im, int value, int value, int value)\par
void wPixel(int x, int y, image\_cc *im, int *value)\par
void wPixel(int x, int y, int z, image\_cc *im, int value)
}{
Write a value to a pixel.}
\argu{i}{offset of the pixel within the stored 1-D array of image data (for 2d and 3d images).}
\argu{x, y, z}{Coordinates of the pixel.}
\argu{im} {Pointer to the image.}
\argu{value}{value(s) to be written, number of given values corresponds to the number of channels per pixel} 
\argu{*value} {For RGB images a pointer to a 3 element array containing the RGB values.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void InvertImage(image\_cc *im)
}{ 
Inverts an image.}
\argu{im} {Pointer to the image.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void FlipImage(image\_cc *im, int mode)
}{ 
Flips an image (only 2D).}
\argu{im} {Pointer to the image.}
\argu{mode} {0=horizontal, 1= vertical flip.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void RotateImage(image\_cc *im, int mode)
}{ 
Rotates an image (only 2D) by 90$^\circ$ or 180$^\circ$.}
\argu{im} {Pointer to the image.}
\argu{mode} {-1= 90$^\circ$ counter clock wise, 1= 90$^\circ$ clock wise, 0=180$^\circ$.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void TurnImage(image\_cc *im, double grad)
}{ 
Rotates an image (only 2D) by a given angle.}
\argu{im} {Pointer to the image.}
\argu{grad} {angle in degrees.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *ImageSegment(image\_cc *image, int ulx, int uly, int dx, int dy)\par
image\_cc *ImageSegment(image\_cc *image, int ulx, int uly, int ulz, int dx, int dy, int dz)
}{ 
Cut a rectangular segment out of an image.}
\argu{image} {Pointer to the image.}
\argu{ulx,uly,(ulz)} {x,y,z coordinates of the upper left corner of the segment.}
\argu{dx,dy,(dz)} {size of the segment in x,y,z  direction (number of pixels).}
\return{Pointer to the segment.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *GetPlane(image\_cc *im, int plane, int mode)
}{ 
Extracts a 2D plane from a 3D image}
\argu{im} {Pointer to the 3D image.}
\argu{plane} {x,y or z coordinate of the plane.}
\argu{mode} {direction of the plane 0=xy, 1=yz, 2=xz.}
\return{Pointer to the 2D image.}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void SetFrame(image\_cc *im, int value)}{
Writes the edges of an image to a certain value.}
\argu{*im} {Pointer to the image.}
\argu{value} {Value to be written at the edges}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *ChangeResolution(image\_cc *image, int newx, int newy)
}{
Rescales an image to the new dimensions {\tt newx} and {\tt newy}. (Only for 2D images, rgb and grey).}
\argu{*image}{Pointer to the original image}
\argu{ newx, newy}{new dimensions in x and y direction}
\return{pointer to a rescaled image}


%--------------------------------- ok
\command{
image\_cc *Diff(image\_cc *wnd1,image\_cc *wnd2)
}{          
Returns an image of the absolute differences between two images.}
\argu{*wnd1,*wnd2}{\quad Pointer to the original images of any type.}
\return{Pointer to the resulting image.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Image conversions}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *bit16to8(image\_cc *image)
}{
Converts a 16-bit grey scale image to a 8-bit image

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the original image.}
\return{Pointer to the resulting image.}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *Btd2Ddd(image\_cc *image)
}{              % DESCRIPTION
Converts a btd-image (1 bit/voxel) to a ddd-image (1 byte/voxel). 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\return{Pointer to the corresponding ddd-image}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *RGBtoGray(image\_cc *image)
}{              % TEXT
Converts a RGB-3byte-color image to a 8bit-grey scale image.

\medskip        % ARGUMENTS AND RETURN VALUE
\argu{image} {Pointer to the RGB-image}
\return{pointer to the converted grey scale image.}
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
void DDD2Dx(image\_cc *image, char *buf);
}{              % DESCRIPTION
Generates a description file for DX named toto.general. The file name (toto) which is provided through {\tt buf} must be the same name as was used to save the ddd image using StoreImage(). Note that the image resolution should be set correctly.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the ddd-image}
\argu{*buf}{name of the ddd images (without extension)}
\return{no return value, a dx description file *.general is produced.}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *Ddd2Btd(image\_cc *im);
}{              % DESCRIPTION
Converts a ddd-image to a btd-image. All non-zero voxels are set to 1 the others stay at 0.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the ddd-image}
\return{pointer to the resulting btd-image.}
}


\pagebreak 
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Image filtering}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void Mean(image\_cc *im, int size)
}{ 
Mean filter using a squared window}
\argu{im} {Pointer to the image.}
\argu{size} {sidelength of squared filter: 2$\cdot$size+1 pixel.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *MeanVar(image\_cc *im, int size)
}{ 
Same as Mean but the variance within the squared window is returned as a new image}
\argu{im} {Pointer to the image.}
\argu{size} {sidelength of squared filter: 2$\cdot$size+1 pixel.}
\return{Pointer to the image of variances}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void Gauss(image\_cc *im, int size, double sig)
}{ 
Gauss filter using a squared window with side length 2$\cdot${\tt size}+1 pixel.}
\argu{im} {Pointer to the image.}
\argu{size} {Sidelength of squared filter: 2$\cdot$size+1 pixel.}
\argu{sig} {Variance of Gauss filter.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void DiffGauss(image\_cc *im, int size, double sig, double sig2)
}{ 
Difference of Gaussian (DoG) filter using a squared window with side length 2$\cdot${\tt size}+1 pixel. At the same time the image is smoothed by a Gauss filter with low {\tt sig} while edges are enhanced by adding the difference to a strongly smoothed image {\tt sig2} at each location (The difference is highest at edges).}
\argu{im} {Pointer to the image.}
\argu{size} {Sidelength of squared filter: 2$\cdot$size+1 pixel.}
\argu{sig} {Small variance of Gauss filter.}
\argu{sig2} {Big variance of Gauss filter.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void UnsharpMask(image\_cc *im, int size, double sig)
}{ 
Edge enhancement filter using a squared window with side length 2$\cdot${\tt size}+1 pixel. Same rationale as a Difference of Gaussian filter (see above) but here the local grey value difference due to convolution with Gaussian kernel of {\tt sig} is directly added to the image. This is faster but may enhance noise at the same time.}
\argu{im} {Pointer to the image.}
\argu{size} {Sidelength of squared filter: 2$\cdot$size+1 pixel.}
\argu{sig} {Variance of Gauss filter.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void MinMax(image\_cc *im, double size, int mode)
}{ 
Minimum-Maximum filter for grey scale images with a circular/spherical kernel where {\tt size} is in length units of the image according to im$->$res[0]. This filter corresponds to grey scale erosion/dilation}
\argu{im} {Pointer to the image.}
\argu{size} {Radius of the circular/sherical filter}
\argu{mode} {0 is minimum filter, else maximum.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void Luul(image\_cc *im, double size)
}{ 
Combined Minimum-Maximum filter: lower-upper-upper-lower for grey scale images with a circular/spherical kernel where {\tt size} is in length units of the image according to im$->$res[0]. This filter corresponds to grey-scale opening, the result is similar to the median but Luul is more efficient.}
\argu{im} {Pointer to the image.}
\argu{size} {Radius of the circular/sherical filter in pixel}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void Ullu(image\_cc *im, double size)
}{ 
Combined Minimum-Maximum filter: upper-lower-lower-upper for grey scale images with a circular/spherical kernel where {\tt size} is in length units of the image according to im$->$res[0]. This filter corresponds to grey-scale closing, the result is similar to the median but Ullu is more efficient (The result of the Median filter is between Luul and Ullu).}
\argu{im} {Pointer to the image.}
\argu{size} {Radius of the circular/sherical filter in pixel}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void pseudoMad(image\_cc *orig, double size)\par
void pseudoMad(image\_cc *orig, image\_cc **pMed, double size)
}{pseudo Median absolute deviation
The median absolute deviation is the median of the
absolute differences towards the median.
For reason of speed the median is replaced by
the luul filter.}
\argu{orig}{pointer to original image}
\argu{pMed}{pointer to pointer to image containing the luul filtered
image. If NULL, this will be created (and the pointer set to the new image).}
\argu{size}{radius of spherical window to use.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *MajorityFilter(image\_cc *im, int nr, int wnd, double maj, double rel)\par
image\_cc *MajorityFilter(image\_cc *im, image\_cc *roi, int nr, int wnd, double maj, double rel)
}{ 
The current label is replaced by the most representative label among all neighbors in a cubic kernel, if (i) the most representative label exceeds a certain majority and (ii) the number exceeds that of the current label at the central voxel by a certain percentage}
\argu{im} {Pointer to the image.}
\argu{roi} {Pointer to the binary image that represents the region of interest (optional).}
\argu{nr} {Number of labels in the image}
\argu{wnd} {sidelength of cubic window: 2$\cdot$wnd+1 pixel.}
\argu{maj} {majority [0-1]}
\argu{rel} {relative majority with respect to current label}
\return{Pointer to the filtered image}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void FastMedian(image\_cc *im, int size)
}{ 
Median filter using a cubic window with fast updating of entries when the window is moved by one position. The running median method is adapted from Ashelly and distributed under the MIT License (MIT) (\url{https://gist.github.com/ashelly/5665911})}
\argu{im} {Pointer to the image.}
\argu{size} {sidelength of cubic filter: 2$\cdot$size+1 pixel.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void TotVarFilter(image\_cc *im,  double timestep, double lambda, int maxstep, int interval, int function)$^{3D}$
}{ 
This filter minimizes the total variation while keeping a maximal fidelity to the original image (only 3D). The strength of fidelity is given by \texttt{lambda}. Method is according to Rudin, Fatemi, Osher (1992): Physica A,60,259-268.
}
\argu{im} {Pointer to the image.}
\argu{timestep}{timestep for each filtering. If negative, will be handled dynamically. -0.1 normally works well.}
\argu{lambda}{fidelity parameter. 5 is a good start.}
\argu{maxstep}{maximal number of filtering steps.}
\argu{interval}{number of steps after which the image in memory will be updated.}
\argu{function}{kernel functions for filtering. 0: classical Total variation, 1: Entropy, 2: Enhanced entropy}

\command{
void AnisoDiffFilter(image\_cc *im,  int maxstep, double threshold, double sigma)$^{3D}$
}{ 
Anisotropic (or non-linear) diffusion filter according to Catt\'e et. al (1992) SIAM Journal on Numerical Analysis, 29(1), 82-193.
}
\argu{maxstep}{maximal number of filtering steps.}
\argu{threshold}{diffusion stop criterion - gradients larger than this are conserved}
\argu{sigma}{standard deviation of the Gaussian kernel for smoothing prior to edge evaluation}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void Bin(image\_c *im, int thresh)\par 
void Bin(image\_cc *im, int thresh, int lower, int upper)
}{ 
Binarization of an image according to a threshold value. Grey values $\leq$ {\tt thresh} are set to {\tt lower} the others to {\tt upper}. If no explicite values for {\tt lower}and {\tt upper} are given, this is equivalent to {\tt lower}=0 and {\tt upper}= maximum grey level. If the value of {\tt upper} is larger than the maximum possible grey value, the original grey values above {\tt thresh} are maintained.
}
\argu{im} {Pointer to the image.}
\argu{thresh} {Threshold value}
\argu{lower} {Value written to pixel $\leq$ {\tt thresh}}
\argu{upper} {Value written to pixel $>$ {\tt thresh}}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void BinBand(image\_cc *im, int lthresh, int uthresh)
}{ 
Binarization of an image according to 2 threshold values. Values $\geq$ {\tt lthresh} and $\leq$ {\tt uthresh} are set to 0, the others to the maximum grey level.
}
\argu{im} {Pointer to the image.}
\argu{lthresh} {Lower threshold value}
\argu{uthresh} {Upper threshold value}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void BinBilevel(image\_cc *im, int lower, int upper)}
{
Segmentation of an image according to 2 thresholds which are regarded to be the limits of a fuzzy region within which the 'true' threshold is expected. The threshold is chosen locally according to the values of the neighboring pixel values.
All pixel of a grey level $\leq$ {\tt lower} are written to 0 as well as all pixel $\leq$ {\tt upper} having at least one direct neighbor $\leq$ {\tt lower}. The other pixel keep their original values. This rule is applied iteratively until no pixel has to be changed anymore.
}
\argu{im} {Pointer to the image.}
\argu{lower} {Lower threshold.}
\argu{upper} {Upper threshold.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc  *DddBin(image\_cc *im, int thresh)
}{ 
Binarization of a ddd-image according to a single threshold values. The result is converted to a btd-image voxels are set to 0 for values $\leq$ {\tt thresh} and t 1 else.
}
\argu{im} {Pointer to the ddd-image.}
\argu{thresh} {threshold value}
\return{Pointer to the binary btd-image}

%---------------------------------ok
\command{       % COMMAND
image\_cc *Sobel(image\_cc *im)\par
image\_cc *Sobel(image\_cc *im, image\_cc *maskim)
}{              % DESCRIPTION
Sobel filter (first derivative of local grey levels).  The image border is set to 0.  If an additional binary image {\tt maskim} of same dimensions is provided, the evaluation is only done for regions where {\tt maskim} is non-zero.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
\return{Pointer to the filtered image}
}
%---------------------------------ok
\command{       % COMMAND
image\_cc *Laplace(image\_cc *im, int mode)\par
image\_cc *Laplace(image\_cc *im, int mode,image\_cc *maskim)
}{              % DESCRIPTION
Laplace filter (second derivative of local grey levels). The image border is set to 0. For {\tt mode}=1 only positive Laplacians are stored, for {\tt mode}=2 only negative and for {\tt mode}=3 both. If an additional binary image {\tt maskim} of same dimensions is provided, the evaluation is only done for regions where {\tt maskim} is non-zero.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
\argu{mode}{indicates which sign is to be considered (bit1=positive, bit2=negative).}
\return{Pointer to the filtered image}
}


\pagebreak
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Grey scale images (8 and 16 bit)$^{8,16}$ (2D and 3D)$^{2D,3D}$}
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
double *Histo(image\_cc *im)$^{8\quad 2D,3D}$\par
double *Histo(image\_cc *im, image\_cc *mask)
}{
Returns the histogram (pdf) of an image (16-bit images are converted to 8-bit prior to the evaluation). Optionally, a histogram is only calculated for locations where the mask image is white.}
\argu{*image}{Pointer to the grey image.}
\argu{*mask} {Pointer to the mask image}
\return{Pointer to the histogram (256 element array).}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double *GreyCdf(image\_cc *im)$^{8\quad 2D,3D}$\par
double *GreyCdf(image\_cc *im, image\_cc *mask)
}{              % DESCRIPTION
Returns a 256 element array containing the cdf (cumulative histogram) of grey levels. Optionally, a cdf is only calculated for locations where the mask image is white.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the grey image}
\argu{*mask} {Pointer to the mask image}
\return{cdf array (256 elements)}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{void StretchHisto(image\_cc *image, int Low, int High)\par 
void StretchHisto(image\_cc *image, double th)\par 
void StretchHisto(image\_cc *image)
}{
Scales the histogram of a grey scale images (2D and 3D, 8-bit and 16-bit).
Grey values between {\tt Low} and {\tt High} are mapped on a grey scale between 0 and the maximum value $2^8$ or $2^{16}$ for 8-bit or 16-bit images respectively.
Values lower than { Low} are set to 0, values higher than {\tt High} are set to the maximum value. If the parameters {\tt Low} and {\tt High} are replaced by {\tt th} the limits are set to lower and upper {\tt th} percent of existing values. If no additional argument is given, the histogram ist rescaled according to the minimum and maximum value of the original image (corresponding to {\tt th}=0). To match the grey values to a smooth histogram a suitable random value is added to rescaled values.
}
\argu{*image} {Pointer to the image}
\argu{Low} {lower threshold} 
\argu{High} {upper threshold} 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
void HistoMatch(double *cdf, image\_cc *image)$^8$
}{              % DESCRIPTION
Transforms the histogram of an image according to a predefined cdf, typically optained from a source image using the function {\tt GreyCdf()}.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{predefined cdf of grey levels}
\argu{*image}{Pointer to the 2D grey scale image }
\return{no return value}
}
%--------------------------------- ss 21.01.10
\command{       % COMMAND
int UnimThresh(double *histo, int mode);
}{              % DESCRIPTION
Threshold detection in a unimodal histogram typically obtained by {\tt Histo} via triangulation according to Rosin(2001):Pattern Recognition,34,2083-2096. The threshold is located at the characteristic knee of the histogram, which has the largest perpendicular distance to an imaginary line connecting the mode with the brightest grey value ({\tt mode}=1) or the darkest grey value ({\tt mode}=0).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*histo}{8bit grey value frequency distribution}
\argu{mode}{0=right tail, 1=left tail}
\return{threshold value}
}
%--------------------------------- ss 08.10.13
\command{       % COMMAND
int KMeansThresh(double *histo, int nr);
}{              % DESCRIPTION
Iterative Threshold Selection Method according to Ridler $\&$ Calvard (1978): IEEE Transactions on Systems, Man, and Cybernetics,8(8),630-632. Starting from an arbitrary set of thresholds, the arithmetic mean of adjacent class means is iteratively set as a new threshold until all thresholds converge to a stable values.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit grey value frequency distribution}
\return{threshold value}
}
%--------------------------------- ss 08.10.13
\command{       % COMMAND
int *ShapeThresh(double *cdf, int nr, double tau)\par
int *ShapeThresh(double *cdf, int nr, double tau, double perc)
}{              % DESCRIPTION
Multilevel thresholding by local minima search according to Tsai (1995): Pattern Recognition ,16(6),653-666. Local maxima of histogram curvature are detected in addition, if there are less peaks than the specified number of classes.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit cumulative grey value frequency distribution}
\argu{nr}{number of classes}
\argu{perc}{percentile that sets a fuzzy region around the optimal grey threshold}
\return{pointer to vector of nr-1 thresholds or 3(n-1) thresholds if {\tt perc} is set}
}
%--------------------------------- ss 08.10.13
\command{       % COMMAND
int *FuzzyCMeansThresh(double *cdf, int nr, double tau)\par
int *FuzzyCMeansThresh(double *cdf, int nr, double tau, double perc)
}{              % DESCRIPTION
Multilevel thresholding by fuzzy c-means clustering according to Jawahar et al. (1997): Pattern Recognition ,30(10),1605-1613.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit cumulative grey value frequency distribution}
\argu{nr}{number of classes}
\argu{tau}{fuzzyness index $[1,\infty)$. Method equals k-means clustering if $\tau=1$.}
\argu{perc}{percentile that sets a fuzzy region around the optimal grey threshold}
\return{pointer to vector of nr-1 thresholds or 3(n-1) thresholds if {\tt perc} is set}
}
%--------------------------------- ss 18.04.13
\command{       % COMMAND
int *MaxVarThresh(double *cdf, int nr);\par
int *MaxVarThresh(double *cdf, int nr, double perc)
}{              % DESCRIPTION
Multilevel thresholding by maximizing between-class variance (Otsu method) according to Liao et al. (2001):Journal of Information science and Engineering,17,713-727.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit cumulative grey value frequency distribution}
\argu{nr}{number of classes}
\argu{perc}{percentile that sets a fuzzy region around the optimal grey threshold}
\return{pointer to vector of nr-1 thresholds or 3(n-1) thresholds if {\tt perc} is set}
}
%--------------------------------- ss 18.04.13
\command{       % COMMAND
int *MaxEntroThresh(double *cdf, int nr)\par
int *MaxEntroThresh(double *cdf, int nr, double perc)
}{              % DESCRIPTION
Multilevel thresholding by maximizing the sum of histogram entropy of each class according to Kapur et al. (1985):Computer Vision, Graphics and Image Processing,29,273-285.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit cumulative grey value frequency distribution}
\argu{nr}{number of classes}
\argu{perc}{percentile that sets a fuzzy region around the optimal grey threshold}
\return{pointer to vector of nr-1 thresholds or 3(n-1) thresholds if {\tt perc} is set}
}
%--------------------------------- ss 18.04.13
\command{       % COMMAND
int *MinErrThresh(double *cdf, int nr)\par
int *MinErrThresh(double *cdf, int nr, double perc)
}{              % DESCRIPTION
Multilevel thresholding by minimizing the overlap error of fitted Gaussians according to Kittler $\&$ Illingworth (1986): Pattern Recognition ,19(1),41-47.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*cdf}{8bit cumulative grey value frequency distribution}
\argu{nr}{number of classes}
\argu{perc}{percentile that sets a fuzzy region around the optimal grey threshold}
\return{pointer to vector of nr-1 thresholds or 3(n-1) thresholds if {\tt perc} is set}
}

%--------------------------------- ss 13.05.13
\command{       % COMMAND
int *GradMaskThresh(image\_cc *image, double alpha)\par
int *GradMaskThresh(image\_cc *image, double alpha, image\_cc *mask)
}{              % DESCRIPTION
Thresholding with gradient masks according to Schl\"uter et al. (2010): Computers $\&$ Geosciences,36,1246-51. Only locations along edges are taken into consideration for detection of an upper threshold. The lower threshold is calculated subsequently from simple histogram statistics.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the grey value image}
\argu{alpha}{defines the width of a fuzzy threshold range. Usually set between one and two.}
\argu{*mask}{Pointer to the mask image (optional)}
\return{pointer to vector of two thresholds (lower and upper threshold)}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *WaterShed(image\_cc *image, int conmode)$^{8\quad 2D,3D}$
}{              % DESCRIPTION
Calculates the watershed lines for a grey image (only 8-bit images). The different basins separated by the watershed lines are marked by different grey values (2D) or by a single grey value (3D) , the watershed line is 0. This may be applied to a distance map of a binary image to separate overlapping grains. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the grey image}
\argu{conmode}{Connectivity mode: either 4 or 8 (2D) and 6 or 26 (3D).}
\return{Pointer to the image containing the watershed and the basins}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double *Acov(image\_cc *im, double *corl, int lag, int mode)$^{8\quad 2D,3D}$
}{              % DESCRIPTION
Returns the autocovariance function of a 2D grey image

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image}
\argu{*corl}{address to write the correlation length as result}
\argu{lag}{maximum distance to evaluate (\# pixels)}
\argu{mode}{indicates which directions are to be considered (bit1=x, bit2=y, bit3=z)}
\return{pointer to an array of dimension {\tt lag} where the autocovariance function is stored}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double *SemiVar(image\_cc *im, int lag, int mode)$^{8\quad 2D,3D}$
}{              % DESCRIPTION
Returns the semi-variance function of a grey scale image.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image}
\argu{*corl}{address to write the correlation length as result}
\argu{lag}{maximum distance to evaluate (\# pixels)}
\argu{mode}{indicates which directions are to be considered (bit1=x, bit2=y, bit3=z)}
\return{pointer to an array of dimension {\tt lag} where the semi-variance function is stored}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
long *GreyConFunc(image\_cc *image, int mode)$^{8\quad 2D,3D}$
}{              % DESCRIPTION
Returns the connectivity function of a grey scale image. The image is binarized for all possible thresholds [0,255] and the corresponding Euler number is dermined which is returned as a vector of 255 elements. The Euler numbers are not normalized by the size of the image. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the grey image}
\argu{mode}{Connectivity mode for values $<$ grey threshold: 4 or 8 (2D), 6 or 26 (3D) }
\return{array of 255 Euler numbers}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
image\_cc *CircMask(image\_cc *im, int xmid, int ymid, int rad)$^{8,16\quad 2D,3D}$
}{              % DESCRIPTION
Cuts out a circular (2D) or cylindrical (3D) image with center {\tt xmid, ymid} and radius {\tt rad}. All pixels outside the circle are set to the maximum grey level. 
%The size of the returned image is reduced to 2*{\tt rad}+1.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the grey image}
\argu{xmid, ymid}{center coordinates of the circle}
\argu{rad}{radius of the circle}
\return{Pointer to the resulting image}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\pagebreak
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%*************************************************************************************
\section{Binary images}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *ErodeCirc(image\_cc *image, double rad, int mode)\par
image\_cc *ErodeDist(image\_cc *image, double rad, int mode)}
{
Performs an erosion or dilation of a binary image using a circular/spherical structuring element. The radius of this element is given in number of pixels in x-direction (this might be relevant for unisotropic pixel geometry). The function {\tt ErodeDist} is based on the entire distance map of the image and is more efficient for large structuring elements, while {\tt ErodeCirc} evaluates only individual structuring elements which is more efficient for small {\tt rad} 

\medskip
\argu{*image} {Pointer to the image.}
\argu{step} {radius of the structuring element {\bf (in x-pixel)}}
\argu{mode} {0 = erosion, 1 = dilation of the black phase} 
\return{Pointer to the resulting image}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
image\_cc *OpenCirc(image\_cc *im, double rad, int mode)\par
image\_cc *OpenDist(image\_cc *im, double rad, int mode)}
{
Performs a morphological opening or closing of a binary image using a circular/spherical structuring element. The radius of this element is given in number of pixels in x-direction (this might be relevant for unisotropic pixel geometry). The function {\tt OpenDist} is based on the entire distance map of the image and is more efficient for large structuring elements, while {\tt OpenCirc} evaluates only individual structuring elements which is more efficient for small {\tt rad} 

\medskip
\argu{*image} {Pointer to the image.}
\argu{step} {radius of the structuring element }
\argu{mode} {0 = opening of the black phase, 1 = closing of the black phase} 
\return{Pointer to the resulting image}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
%image\_cc *GetDistMap(image\_cc *image, double gstep)}
image\_cc *GetDistMap(image\_cc *image)}
{Generates the distance map of a binary image, which is a grey scale image where the grey value of each pixel indicates the orthogonal distance to the black-white interface. The resulting image is in 16bit grey scale. The Euclidian distance is calculated in number of pixels in x-direction and is rounded up to the next integer x. Hence the distance map has values of 32768+/-x while the value 32768 representing the black-white interface does not exist. This function can also be used for anisotropic pixel geometry (different resolution in x,y,z). In this case the calculated distances are always in units of number of pixel in x-direction.

\medskip
\argu{*image} {Pointer to the binary image.}
%\argu{gstep} {scaling of the grey levels of the distance map}
\return{Pointer to the resulting image (16bit grey)}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
%image\_cc *GetOpenMap(image\_cc *distmap, double gstep)}
image\_cc *GetOpenMap(image\_cc *distmap, int smax)}
{Generates the 'opening map' for the black phase of a binary image. This is a grey scale image where the grey value of each pixel indicates the maximum size of a circle (2D) or a sphere (3D) which is a complete subset of the black phase. The size of the circle/sphere is in number of pixels in x-direction. As input the distance map is used which is generated by {\tt GetDistMap()}. The generated opening map can be used to calculate the 'opening size distribution' using the function {\tt MinkowskiOpenFunctions} 

\medskip
\argu{*distmap} {Pointer to the distance map (16bit grey).}
\argu{smax} {number of opening steps}
\return{Pointer to the resulting opening map}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void MinkowskiFunctions(image\_cc *image, char *outfile)}
{
Calculates all Minkowski-Functions, i.e.~Minkowski functionals in dependency of the grey threshold. All possible thresholds are evaluated. This function is typically used for the evaluation of distance maps generated by {\tt GetDistMap}. The results are written to the file {\tt outfile}.

\medskip
\argu{*image} {Pointer to the input image.}
\argu{outfile} {file name where the results are written to}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void MinkowskiOpenFunctions(image\_cc *image, char *outfile)\par 
void MinkowskiOpenFunctions(image\_cc *image, image\_cc *maskim, char *outfile)
}{
Calculates all Minkowski-Functions for an opening map generated by {\tt GetOpenMap}, i.e.~Minkowski functionals in dependency of the opening size. If an additional binary image {\tt maskim} of same dimensions is provided, the evaluation is only done for regions where {\tt maskim} is non-zero. The results are written to the file {\tt outfile}.

\medskip
\argu{*image} {Pointer to the input image.}
\argu{gstep} {scaling of the grey levels of the opening maps}
\argu{pixstep} {evaluated sizes in unit of pixel}
\argu{outfile} {file name where the results are written to}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
long int *m2Quant(image\_cc *image)\par
long int *m2Quant(image\_cc *image, image\_cc *maskim)}
{              % DESCRIPTION
Calculates the frequency distribution of 16 different pixel configurations in a 2x2 square. 
The returned pointer is input for the routines to calculate Minkowski functionals: volume density, surface density, length density, and Euler number. If another binary 'mask' is provided ({\tt maskim}) having the same dimensions as {\tt image}, the evaluation is done only for regions where {\tt maskim} is not zero.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the binary 2D-image.}
\argu{*maskim}{Pointer to the image containing a mask.}
\return{Pointer to the 16-element array containing frequencies of pixel configurations}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
long int *m3Quant(image\_cc *image)\par 
long int *m3Quant(image\_cc *image, image\_cc *maskim)}
{              % DESCRIPTION
Calculates the frequency distribution of 256 different voxel configurations in a 2x2x2 cube. 
The returned pointer is input for the routines to calculate Minkowski functionals: volume density, surface density, curvature density and Euler number. If another binary 'mask' is provided ({\tt maskim}) having the same dimensions as {\tt image}, the evaluation is done only for regions where {\tt maskim} is not zero. NOTE THAT 3-dimenional Minkowski functionals treat the white phase (btd values = 1) as foreground which is in contrast to the 2-dimensional version (just to keep you flexible).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the binary 3D-image in btd-format.}
\return{Pointer to the 256-element array containing frequencies of voxel configurations}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m2areadens(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the area density of a 2D binary structure (black phase) which corresponds to the volume density of a 3D structure as estimated from the 2-dimensional section.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m2Quant()}
\return{Volume density [L$^2$/L$^2$] }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m2lengthdens(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the length density $B_A$ [L/L$^2$] of the boundary per area of a 2D binary structure. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of voxel configurations obtained by m2Quant()}
\argu{*image}{Pointer to a 2D binary image (0=black, 255=white)}
\return{Length density [L/L$^2$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m2surfdens(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the  surface density $S_V$ [L$^2$/L$^3$] of the black-white interface of a 3D binary structure. The evaluated image is considered to be a 2-dimensional section through that 3D structure. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m2Quant()}
\argu{*image}{Pointer to a 2D binary image (0=black, 255=white)}
\return{Surface density [L$^2$/L$^3$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m2euler4(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the  Euler number $\chi_A$ [1/L$^2$]  of a 2D binary structure considering 4-connectivity of the black phase. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m2Quant()}
\argu{*image}{Pointer to a 2D binary image (0=black, 255=white)}
\return{Euler number [1/L$^2$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m2euler8(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the Euler number $\chi_A$ [1/L$^2$] of a 2D binary structure considering 8-connectivity of the black phase. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m2Quant()}
\argu{*image}{Pointer to a 2D binary image (0=black, 255=white)}
\return{Euler number [1/L$^2$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m3voldens(long int *h);
}{              % DESCRIPTION
Returns the volume density of a 3D binary structure (white phase).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of voxel configurations obtained by m3Quant()}
\argu{*image}{Pointer to a 3D binary image in btd-format (0=black, 1=white)}
\return{Volume density [L$^3$/L$^3$] }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m3surfdens(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the  surface density $S_V$ [L$^2$/L$^3$] of the black-white interface of a 3D binary structure. The units of L are given in the units of image resolution (image$->$res[i]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m3Quant()}
\argu{*image}{Pointer to a 3D binary image in btd-format (0=black, 1=white)}
\return{Surface density [L$^2$/L$^3$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m3meancurv(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the mean curvature density $C_V$ [L/L$^3$] of the black-white interface of a 3D binary structure. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of pixel configurations obtained by m3Quant()}
\argu{*image}{Pointer to a 3D binary image in btd-format (0=black, 1=white)}
\return{Curvature density [L/L$^3$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m3euler6(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the  Euler number $\chi_V$ [1/L$^3$]  of a 3D binary structure considering 6-connectivity of the white phase. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of voxel configurations obtained by m3Quant()}
\argu{*image}{Pointer to a 3D binary image in btd-format (0=black, 1=white)}
\return{Euler number [1/L$^3$]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double m3euler26(image\_cc *image, long int *h);
}{              % DESCRIPTION
Returns the  Euler number $\chi_V$ [1/L$^3$]  of a 3D binary structure considering 26-connectivity of the white phase. The units of L are given in the units of image resolution (image$->$res[]).

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*h}{Pointer to the array of voxel configurations obtained by m3Quant()}
\argu{*image}{Pointer to a 3D binary image in btd-format (0=black, 1=white)}
\return{Euler number [1/L$^3$]}
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *LogAnd(image\_cc *wnd1, image\_cc *wnd2)}{
Logical AND relation (intersection) of two binary images.

\medskip
\argu{wnd1} {Pointer to the first image description structure.} 
\argu{wnd2} {Pointer to the second image description structure.}
\return{Pointer to the resulting image}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *LogOr(image\_cc *wnd1, image\_cc *wnd2)}{
Logical OR relation (unification) of two binary images.

\medskip
\argu{wnd1} {Pointer to the first image description structure.} 
\argu{wnd2} {Pointer to the second image description structure.}
\return{Pointer to the resulting image}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{image\_cc *Intersection(image\_cc *wnd1, image\_cc *wnd2, int gv1, int gv2)}{
Intersection of two binary images. The black phase of the two images is set to {\tt gv1} and {\tt gv2} respectively, their intersection is set to black.

\medskip
\argu{wnd1} {Pointer to the first image description structure.} 
\argu{wnd2} {Pointer to the second image description structure.}
\argu{gv1} {grey level to be set for phase in wnd1.}
\argu{gv2} {grey level to be set for phase in wnd2.}
\return{Pointer to the resulting image}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{
void bThinning(image\_cc *im);
}{Thinning of 0-phase of a binary image, considering 4-connectivity.
}
\argu{*im}{Pointer to the image.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
void bThinning8(image\_cc *im);
}{              % DESCRIPTION
Thinning of 0-phase of a binary image, considering 8-connectivity .

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
void bConCom(image\_cc *im,int xv,int yv,int val)
}{              % DESCRIPTION
Marking of th connected component which includes the seed point {\tt xv yv} in a binary image.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
\argu{xv yv}{Seed point of the component.}
\argu{val}{Grey value to mark the conected component.}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
int bConCom2(image\_cc *image,int xv,int yv);
}{              % DESCRIPTION
Determines the size of the  connected object identified by greylevel 0 around point xv/yv considering 8-connectivity. Return value is the number of pixels attributed to the object. The original image is not changed.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\argu{xv, yv}{coordinates for seed point of the connected component}
\return{number of pixels attributed to the object considering 8-connectivity}
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
int isPercol(image\_cc *image, int backbone, int mode);
}{              % DESCRIPTION
returns 1 if the 0-values of a binary structure percolate in the directions indicated by {\tt mode} (bit1=x, bit2=y, bit3=z). if {\tt backbone} is not 0 the backbone  (or in case of no percolation the continuous part with respect to plane x/y/z=0 indicated by {\tt mode}) is stored as additional image named 'backbone' if {\tt backbone} is 0 the calculation is interupted as soon as percolation was detected (which is faster).
 
\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\argu{backbone}{if not 0 an image of the continuous part is stored (file name 'backbone')}
\argu{mode}{direction in which percolation is tested}
\return{1 if the structure percolates, 0 else}
}
\command{       % COMMAND
image\_cc *Cluster(image\_cc *image, int *nr)
}{             % DESCRIPTION
Fast object detection with the Hoshen-Kopelman algorithm, as implemented by Tobin Fricke and distributed under GNU public license (\url{http://www.ocf.berkeley.edu/~fricke/projects/hoshenkopelman/hoshenkopelman.html}). Each isolated white objects gets a different grey value label and the label image is returned. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\argu{*nr}{Pointer to integer where number of objects is written}
\return{image with object labels}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
void RemoveObjects(image\_cc *image, int size, int mode)\par
void RemoveObjects(image\_cc *image, image\_cc *mask, int size, int mode)
}{              % DESCRIPTION
Removes objects or fills holes smaller than a certain size limit. Objects are internally labeled with the Hoshen-Kopelman algorithm.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\argu{*mask}{Pointer to the binary mask for region of interest (optional)}
\argu{size}{size limit in number of voxels}
\argu{mode}{fill holes [0] or remove objects[1]}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\command{       % COMMAND
double ConLength(image\_cc *image, int phase, int every, char *outfile);
}{              % DESCRIPTION
Calculates the pair connectivity as a function of distance considering 8-connectivity. Return value is the mean connectivity length. The step size has be higher than one, especially in 3D, because the evaluation of voxel pairs is rather slow.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the binary image}
\argu{phase}{black [0] or white[1]}
\argu{every}{step size}
\argu{*outfile}{file name where the pair connectivity data is written to}
\return{mean connectivity length}
}

\pagebreak 
%************************************************************
\section{RGB color images}



%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
unsigned char Red(image\_cc *image, int x, int y);
}{              % DESCRIPTION
Reads the red value at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\return{red value}
}

%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
unsigned char Green(image\_cc *image, int x, int y);
}{              % DESCRIPTION
Reads the green value at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\return{green value}
}

%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
unsigned char Blue(image\_cc *image, int x, int y);
}{              % DESCRIPTION
Reads the blue value at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\return{blue value}
}

%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
void WRed(image\_cc *in, int x, int  y, unsigned char val);
}{              % DESCRIPTION
Writes the red value {\tt val} at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\argu{val}{written red value}
\return{no return}
}

%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
void WGreen(image\_cc *in, int x, int  y, unsigned char val);
}{              % DESCRIPTION
Writes the green value {\tt val} at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\argu{val}{written green value}
\return{no return}
}

%--------------hj 21.05.03-------------------------------------------------
\command{       % COMMAND
void WBlue(image\_cc *in, int x, int  y, unsigned char val);
}{              % DESCRIPTION
Writes the blue value {\tt val} at given coordinates.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*image}{Pointer to the image}
\argu{x, y}{coordinates}
\argu{val}{written blue value}
\return{no return}
}


%--------------------------------------------------------------------------
\command{       % COMMAND
void StretchRGBHisto(image\_cc *in, int Rlow, int Rhigh, int Glow, int Ghigh, int Blow, int Bhigh)
}{              % TEXT
Stretches the color histogram according the given limits. The source-image is overwritten.

\medskip        % ARGUMENTS AND RETURN VALUE
\argu{in} {Pointer to the RGB-image.}
\argu{Rlow, Rhigh} {Lower and upper limit for the red channel.}
\argu{Glow, Ghigh} {Lower and upper limit for the green channel.}
\argu{Blow, Bhigh} {Lower and upper limit for the blue channel.}
}

%--------------------------------------------------------------------------
\command{       % COMMAND
void StretchRGBBright(image\_cc *in, int Low, int High)
}{              % TEXT
Stretches the brightness of a RGB-color image between {\tt Low and {\tt High}} $\in [0, 255]$. The source-image is overwritten.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{Low,High} {Lower und upper limit of brightness}
}


\pagebreak 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Graphics}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The following routines use the library {\tt PS\_graf} to generate nice postscript graphics.

\medskip
%--------------------------------- hj 18.9.98
\command{       % COMMAND
void psPlot(char *fname, int n, double *xdat, double *ydat, int mode)
}{              % DESCRIPTION
Draws a x-y graphic and stores it to {\tt fname}.eps.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*fname}{Name of output file.}
\argu{n}{Number of data points.}
\argu{*xdat, *ydat}{Arrays of x- and y-data.}
\argu{mode}{Draws symbols for {\tt mode}=0 and lines else.}
}

%--------------------------------- hj 18.9.98
\command{       % COMMAND
void psPlotTit(char *fname,char *xtitle,char *ytitle, int n, double *xdat, double *ydat, int mode)
}{              % DESCRIPTION
Draws a x-y graphic and stores it to {\tt fname}.eps.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*fname}{Name of output file.}
\argu{*xtitle}{title for x axis.}
\argu{*ytitle}{title for y-axis.}
\argu{n}{Number of data points.}
\argu{*xdat, *ydat}{Arrays of x- and y-data.}
\argu{mode}{Draws symbols for {\tt mode}=0 and lines else.}
}

%--------------------------------- hj 24.9.98
\command{       % COMMAND
void psMultiPlot(char *fname, int *ndat, int nplot, double **xdat, double **ydat, int mode)
}{              % DESCRIPTION
Draws a x-y graphic of multiple data sets and stores it to {\tt fname}.eps.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*fname}{Name of output file.}
\argu{*ndat}{Array of size {\tt nplot} containing the number of data points of each data set.}
\argu{nplot}{Number of data sets.}
\argu{**xdat, **ydat}{Arrays of size {\tt nplot} of pointers to the x- and y-data sets.}
\argu{mode}{Draws symbols for {\tt mode}=0 and lines else.}
}
%--------------------------------- hj 24.9.98
\command{       % COMMAND
void psMultiPlotTit(char *fname,char *xtitle,char *ytitle, int *ndat, int nplot, double **xdat, double **ydat, int mode)
}{              % DESCRIPTION
Draws a x-y graphic of multiple data sets and stores it to {\tt fname}.eps.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*fname}{Name of output file.}
\argu{*xtitle}{title for x axis.}
\argu{*ytitle}{title for y-axis.}
\argu{*ndat}{Array of size {\tt nplot} containing the number of data points of each data set.}
\argu{nplot}{Number of data sets.}
\argu{**xdat, **ydat}{Arrays of size {\tt nplot} of pointers to the x- and y-data sets.}
\argu{mode}{Draws symbols for {\tt mode}=0 and lines else.}
}

 
%--------------------------------- hj 18.9.98
\command{       % COMMAND
void psDddCircHisto(image\_cc *im, char *buf, int prec);
}{              % DESCRIPTION
Draws the histogram of a 3D greylevel image considering only the central cylinder of the image.

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
\argu{*buf}{Name of output file.}
\argu{*prec}{Only a fraction (1/{\tt prec}) of the total number of voxels are considered.}
}

%--------------------------------- hj 30.4.99
\command{       % COMMAND
void psHisto(image\_cc *im, char *buf, int prec);
}{              % DESCRIPTION
Draws the histogram of a 2D greylevel image. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*im}{Pointer to the image.}
\argu{*buf}{Name of output file (eps format).}
\argu{*prec}{Only a fraction (1/{\tt prec}) of the total number of voxels are considered.}
}

%--------------------------------- hj 14.04.04
\command{       % COMMAND
void ps3Dview(char *fname, image\_cc *image, double min, double max);
}{              % DESCRIPTION
Draws a 3D colored view of a ddd-image and write an eps-file. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*fname}{name of the resulting eps-file}
\argu{*image}{Pointer to the ddd-image.}
\argu{min, max}{miniumum and maximum greylevel inbetween which the color is scaled.}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



\input{specials}

\input{usefullstuff}




\input{oldstuff}

\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%--------------------------------- hj 18.9.98
\command{       % COMMAND
image\_cc *CreateDDDImage(char *buf, int z1, int z2,double rx,double ry,double rz)
}{              % DESCRIPTION
Creates a 3D grey scale image from a stack of 2D-images. The names of the 2D-images must have the format totoX.tiff, where 'X' is the continious number of the image within the stack. 

\medskip        %ARGUMENTS AND RETURN VALUE
\argu{*buf}{Basic name 'toto' of the 2D images.}
\argu{z1, z2}{Number 'X' of the first and last 2D image.}
\argu{rx, ry, rz}{resolution (size of voxels) in different dimensions (x,y,z).}
\return{pointer to the created 3D-image.}
}
