Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Image Filter and Transformations

A filter or an image transformation takes an input image and computes an output image.

When organizing the classes in BIAS, we make a distinction between a filter (located in the Filter directory), which does a filtering based on local regions and a more global image transformation, e.g. a homography mapping. Transformations are no filters in the strict BIAS sense. Therefore such more global transformations are located in the Image directory.

Filters

Filters are double-templated in BIAS, depending on the InputImageType and the OutputImageType and must be derived from FilterBase. That means that you can do a storage type conversion while filtering with nearly no extra cost. Since all filters are derived from FilterBase, all filters have a common function, called Filter(inimage, outimage), so their usage is quite obvious. Filters can be steered either using set-functions or using the parameter object BIAS::Param. The (param object) parameters are always held in the most abstract class.

Hierarchy

Filters in BIAS are divided into groups, depending on how much separate information they generate. The more general filters are directly derived from FilterBase, while filters generating k output values for each input value are derived from special base classes called something like FilterNtokN. For instance, the Gauss filter computes for each grey pixel (or N color channels) one value in the output image (respective N color pixels), it is therefore a FilterNToN-based filter. The gradients are FilterNTo2N-based classes because they generate 2 values (the gradient) at each pixel position. The structure tensor even computes three values for each pixel (a symmetric 2 by 2 matrix). The FilterNTokN classes provide common functionality to query multiple output images for an input image, extending the simple FilterBase interface.

Convolution

There is a generic class Convolution in Filter which uses a FilterMask to convolve an InputImage and produces an OutputImage. Convolution has a function for convolving using integer arithmetics and one for doing the computation in float. FilterMask encapsulates both kernels and normalizations and also stores coefficients (vectors) for a possible separable filtering. Convolution is a FilterNToN-based class.

The normalization of filter masks is left to the user. Usually, for low pass filters like gauss, you want the filter mask to sum up to unity. However, for the sobel operator you have to be concerned about the filter mask width, because you may want to interpret the result as a gradient referring to dx=1 and not dx=2, which you compute when you use a <-1 0 1> kernel. Also you may wish to take care of overflows of your output data type (e.g. signed char). There is no automatism here. However, the class FilterMask provides functionality to compute an approximate int filter mask given the float mask, see BIAS::FilterMask. See this example on Convolution:

/*
 This file is part of the BIAS library (Basic ImageAlgorithmS).

 Copyright (C) 2003-2009    (see file CONTACT for details)
 Multimediale Systeme der Informationsverarbeitung
 Institut fuer Informatik
 Christian-Albrechts-Universitaet Kiel


 BIAS is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 BIAS is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with BIAS; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/** 
	@example ExampleConvolution.cpp
	@relates Convolution
	@brief Example for using Convolution Filter
	@ingroup g_examples 
	@author fkellner, 11/2008   
*/
// must be first:
//#include <Base/Common/LeakChecking.h> 

#include <iostream>
#include "Filter/Convolution.hh"
#include <Base/Common/BIASpragma.hh>

using namespace BIAS;
using namespace std;

int main(int argc, char *argv[])
{
  Image<unsigned char> src,dst;
  src.Init(10,10);
  dst.Init(10,10);

  Convolution<unsigned char,unsigned char> conv;
  FilterMask fm;

  unsigned char *srcdata=src.GetImageData();
  unsigned char *dstdata=dst.GetImageData();

  for(int x=0;x<100;x++)
    {
      srcdata[x]=0;
      dstdata[x]=0;
    }
  srcdata[10*5+5]=100;
  srcdata[0]=100;

  Matrix<short> kern;
  Vector<short> khor;
  Vector<short> kver;
  kern.newsize(3,3);
  kern[0][0]=1;
  kern[0][1]=2;
  kern[0][2]=1;
  kern[1][0]=2;
  kern[1][1]=4;
  kern[1][2]=2;
  kern[2][0]=1;
  kern[2][1]=2;
  kern[2][2]=1;

  khor.newsize(3);
  kver.newsize(3);
  khor[0]=1;
  khor[1]=2;
  khor[2]=1;
  kver[0]=1;
  kver[1]=2;
  kver[2]=1;

  
  fm.Init(kern,1);
  fm.CreateFloatFilter();

  conv.SetKernel(fm);
  conv.FilterInt(src,dst);
  cout <<"dst matrix:\n";
  for(int y=0;y<10;y++)
  {
      for(int x=0;x<10;x++)
          cout <<(int)dstdata[y*10+x]<<" ";
      cout <<endl;
  }

  fm.Init(khor,kver,1,0);
  conv.SetKernel(fm);
  conv.FilterInt(src,dst);
  cout <<"dst sep:\n";
  for(int y=0;y<10;y++)
    {
      for(int x=0;x<10;x++)
	cout <<(int)dstdata[y*10+x]<<" ";
      cout <<endl;
    }

  conv.SetKernel(fm);
  conv.FilterFloat(src,dst);
  cout <<"dst matrix float:\n";
  for(int y=0;y<10;y++)
    {
      for(int x=0;x<10;x++)
	cout <<(int)dstdata[y*10+x]<<" ";
      cout <<endl;
    }

  conv.SetKernel(fm);
  conv.FilterFloat(src,dst);
  cout <<"dst sep float:\n";
  for(int y=0;y<10;y++)
    {
      for(int x=0;x<10;x++)
	cout <<(int)dstdata[y*10+x]<<" ";
      cout <<endl;
    }
  
  return 0;
}

Consistent Instantiation of Filters

Sometimes one filter refers to another, and always the user wants to have an overview of what instances are there in the lib and what are not there. Template instances should be consistent and understandable. It is very complicated to control that manually. For the instantiation of filters we have a file Filterinst.hh which takes care about the cmake BUILD_IMAGE_SHORT and similar variables, read the doc of that file to understand how filters are to be instantiated.

Transformations

In the Image directory of BIAS there are some more global transformations, like the sphere and plane mapping or simply a homography mapping.

Mapping

For many applications, we need to resample an image, may it be rectification, warping, undistortion or something else. For this purpose we have the base class BIAS::BackwardMapping which handles the interpolation method, border handling and anti-aliasing in a unified way. There are several clases derived from it, e.g. BIAS::HomographyMapping, which themselves only have to implement the geometric mapping function.

Sphere Projections

This class transforms images or coordinates coming from a fisheye-lens according to different projection models. For this it needs to be initialized with a radial distortion and a radial illumination correction (vignette) curve. The class assumes circular identical distortion and illumination correction functions for all directions starting at the image focal point. With a correct calibration perspective, steriographic and equidistant transformations are possible.