Image Component Library (ICL)
Classes | Functions
Image Classes and Support Functions

Classes

class  icl::core::Channel< T >
 Utility helper class for faster and more convenient access to single channel image data. More...
 
class  icl::core::Img< Type >
 The Img class implements the ImgBase Image interface with type specific functionalities . More...
 
struct  icl::core::ImgBasePtrPtr< T >
 utility class that helps for an implicit conversion between Img<T>* to ImgBase** More...
 
class  icl::core::ImgBase
 ImgBase is the Image-Interface class that provides save access to underlying Img-template . More...
 
class  icl::core::ImgIterator< Type >
 Iterator class used to iterate through an Images ROI-pixels. More...
 
class  icl::core::ImgParams
 The ImgParams class stores all image parameters . More...
 

Functions

ICLCore_API ImgBase * icl::core::imgNew (depth d=depth8u, const ImgParams &params=ImgParams::null)
 create a new image instance of the given depth type and with given parameters More...
 
ImgBase * icl::core::imgNew (depth d, const utils::Size &size, format fmt, const utils::Rect &roi=utils::Rect::null)
 creates a new Img (see the above function for more details) More...
 
ImgBase * icl::core::imgNew (depth d, const utils::Size &size, int channels=1, const utils::Rect &roi=utils::Rect::null)
 creates a new Img (see the above function for more details) More...
 
ImgBase * icl::core::imgNew (depth d, const utils::Size &size, int channels, format fmt, const utils::Rect &roi=utils::Rect::null)
 creates a new Img (see the above function for more details) More...
 
ICLCore_API ImgBase * icl::core::ensureDepth (ImgBase **ppoImage, depth eDepth)
 ensures that an image has the specified depth More...
 
ICLCore_API ImgBase * icl::core::ensureCompatible (ImgBase **dst, depth d, const ImgParams &params)
 ensures that an image has given depth and parameters More...
 
ImgBase * icl::core::ensureCompatible (ImgBase **dst, depth d, const utils::Size &size, int channels, const utils::Rect &roi=utils::Rect::null)
 ensures that an image has given depth, size, number of channels and ROI More...
 
ImgBase * icl::core::ensureCompatible (ImgBase **dst, depth d, const utils::Size &size, format fmt, const utils::Rect &roi=utils::Rect::null)
 ensures that an image has given depth, size, format and ROI More...
 
ICLCore_API ImgBase * icl::core::ensureCompatible (ImgBase **dst, depth d, const utils::Size &size, int channels, format fmt, const utils::Rect &roi=utils::Rect::null)
 ensures that an image has given parameters More...
 
ICLCore_API ImgBase * icl::core::ensureCompatible (ImgBase **dst, const ImgBase *src)
 ensures that the destination image gets same depth, size, channel count, depth, format and ROI as source image More...
 
template<class T >
ImgBasePtrPtr< T > icl::core::bpp (Img< T > *image)
 utility function to cast an Img<T> implicitly into an ImgBase ** More...
 
template<class T >
ImgBasePtrPtr< T > icl::core::bpp (Img< T > &image)
 utility function to cast an Img<T>* implicitly into an ImgBase ** More...
 
template<class ImgType >
const ImgType * icl::core::combineImages (const std::vector< const ImgType * > &vec)
 Combine several images using shallow copy. More...
 
template<class ImgType >
ImgType * icl::core::combineImages (const std::vector< ImgType * > &vec)
 Combine several images using shallow copy. Non-const version. More...
 
template<class T >
void icl::core::deepCopyChannel (const Img< T > *src, int srcC, Img< T > *dst, int dstC)
 Copies the channel from one image to another. More...
 
template<class S , class D >
void icl::core::convertChannel (const Img< S > *src, int srcC, Img< D > *dst, int dstC)
 copies/converts the data from one image to another image (IPP-OPTIMIZED) More...
 
template<class T >
void icl::core::clearChannelROI (Img< T > *im, int c, T clearVal, const utils::Point &offs, const utils::Size &size)
 sets an arbitrary image ROI to a given value More...
 
template<class T >
void icl::core::deepCopyChannelROI (const Img< T > *src, int srcC, const utils::Point &srcOffs, const utils::Size &srcSize, Img< T > *dst, int dstC, const utils::Point &dstOffs, const utils::Size &dstSize)
 copies the channel roi from one image to another More...
 

scaling of channel ROIs

scales an image channels ROI into another images ROI (with implicit type conversion) (IPP-OPTIMIZED)

template<class T >
ICLCore_API void icl::core::flippedCopyChannelROI (axis eAxis, const Img< T > *src, int srcC, const utils::Point &srcOffs, const utils::Size &srcSize, Img< T > *dst, int dstC, const utils::Point &dstOffs, const utils::Size &dstSize)
 mirror copy ROI data from one image to the ROI of another image (IPP-OPTIMIZED) More...
 
ICLCore_API void icl::core::flippedCopy (axis eAxis, const ImgBase *poSrc, ImgBase **ppoDst=0)
 mirror copy of an image from source to destination image (1:1 copy) More...
 
ICLCore_API void icl::core::flippedCopyROI (axis eAxis, const ImgBase *poSrc, ImgBase **ppoDst=0)
 mirror copy of an images ROI into a destination images ROI More...
 

Detailed Description

ICL is a C++ image processing library, developed in the Neuroinformatics Group at the University of Bielefeld in Germany. ICL provides a large set of features for image acquisition, image processing and image visualization. During the design and development process, the following main goals took center stage:

ICL provides all necessary building blocks for the development of complex computer-vision applications.

Simple Viewer Application for Arbitrary Camera Sources

#include <ICLQt/Common.h>
GUI gui;
GenericGrabber grabber;
void init(){
grabber.init(pa("-i"));
gui << Image().handle("image") << Show();
}
void run(){
gui["image"] = grabber.grab();
}
int main(int n, char **args){
return ICLApp(n,args,"-input|-i(2)",init,run).exec();
}

viewer.jpg

More examples for using ICL are given in the online ICL-tutorial on <a href="http://www.iclcv.org>ICL's website

Packages

ICL consists of currently 11 packages that are listed in the main menu at the left.

  • ICLUtils Contains general purpose functions and classes that are currently not part of the C++-STL (e.g. threads or matrices).
  • ICLCore basically provides class definitions for ICL's image classes Img and ImgBase and related global functions.
  • ICLCC provides functions and classes for color conversion.
  • ICLIO extends the range of functions by input and output classes. Camera grabbers different camera types (e.g. IEEE-1394 or Video-4-Linux) can be found here as well a video file grabber or a file writer class.
  • ICLCV contains classes for blob detection and tracking and for connected component analysis.
  • ICLFilter provides classes for most common image filters like linear filters and morphological operators.
  • ICLQuick provides almost 100 functions and functors for rapid prototyping (no longer exists)
  • ICLGeom contains classes for 3D-modelling and camera calibration.
  • ICLQt* contains a Qt-4 based GUI-API that facilitates creation of simple and complex GUI applications significantly. And of course a powerful image visualisation widget called ICLWidget is provided.
  • ICLMarkers contains a generic Fiducial Marker detection framework
  • ICLMath contains high level classes like a hough-transformation-based line detector or generic self organizing map (SOM) implementation.
  • ICLOpenCV* offers functions for shallow and deep copies from ICL-images types into OpenCV's images types and v.v.

(*) The packages ICLQt and ICLOpenCV depend compulsorily on the corresponding external software dependencies Qt4 and OpenCV. Consequently these packages are not available if these dependencies are missing.

icl-components.png
ICL's component collaboration diagram

The Image Classes

We use inheritance and class templates for ICL's image representation: The ImgBase class defines an abstract interface, that manages all image information except image pixel data. These abstract image features are:

  • size (in pixels)
  • channel count (see channel concept)
  • type of pixels (see data types)
  • color format (see color formats)
  • raw image data access
  • Region of Interest (see Region of Interests ROI-Support (ROI))
  • a time stamp

The ImgBase interface is implemented by the template class Img<T> which implements all abstract ImgBase-functions and aggregates a vector of planar image channel data pointers. Internally, these channel data pointers use reference counting to allow shallow image copies.
Img's copy-constructor and assignment operator use shallow copy on default!

The Img<T> template also adds functions for type-safe data access:

  • access to channel data pointers (using getData(channel) or begin(channel))
  • extraction of single image channels (using operator [](int))
  • extraction of single image pixels (using operator()(x,y,channel-index) for single values or operator()(x,y) to obtain a pixel vector)
  • iterator based access to data of a given channel (using begin(channel) and end(channel))
  • iterator based access to the ROI-pixels of a given channel (using beginROI(channel) and endROI(channel))

image-sketch.png
A sketch of ICL's image type Img<T>

Data Origin

As most common image formats image processing use the upper left image corner as data origen, ICL follows this convention as well. Howerver, many image operation like filtering or thresholding works without regarding the image contents at all. Nonetheless, we suggest to use this standard, as it is particularly important for I/O-routines or image visualization and - not at least - whenever discussing about ICL images.

Channel-Concept

The Img treats images as a stack of image slices – channels. Channels can be shared by multiple Img instances, which is especially important for fast shallow images copies. Actually, it is possible to freely compose existing channels (within several "parent images") to another new image.

Attention: The newly composed image shares its channel data with the original images, such that modifications will effect all images equally. In order to get an independent image a deep-copy as well as a so called detach method are provided. The latter replaces the "shared" image channel(s) with new independent ones. Shared channel data are stored using the boost-like shared pointer class SmartPtr, which uses reference counting for autonomous garbage collection in order to realease unused image channels.

Data-Types

The Img template is not implemented completely inline to reduce compilation expense. Therefore, the Img template is instantiated for the following types T

Derived from this types, Img-classes are predefined as follows

Each of these data types has several advantages/disadvantages. The greatest disadvantage of the integer types, is their bounded range (e.g. 0-255 for icl8u), which has the effect, that all information has to be scaled to this range, and all image processing functions must take care that no range-overflow occurs during calculation. Furthermore the limited range may cause loss of information - particular in complex systems. However integer types can often be processed significantly faster. In particular the use of 8-bit unsigned integer images relieves the the memory interface due to it's lower memory usage.

A nice rule of thumb is: If processing speed matters, use Img8u images whenever it's possible and avoid Img64f because double processing is much slower on (still common) 32 bit machines (as long as you do not really need double precision)

ROI-Support

Each image can be set up with a rectangular region of interest. Nearly all algorithms work only on the pixels within the ROI. If a function does not support ROI handling it will be noticed in the documentation. There are several ways to realize ROI handling in functions. The most common way is to use the ImgIterator with can be accessed using the STL-style functions beginROI(channel) and endROI(channel).

Formats

An ImgBase image provides information about the (color) format, that is associated with the image data represented by the images channels. Color is written in brackets, as not all available formats imply color-information. The most known color space is probably the RGB color space. If an ImgBase image has the format formatRGB, than this implies the following:

All additional implemented functions and classes regard this information. The currently available Img formats are member of the enum Format. A special format: formatMatrix can be used for arbitrary purpose.

Const-Concept

ICL Images use the const concept of C++ to ensure pixel data of const Images (of type const ImgBase or more precisely const Img<T>) is not changed, i.e. it is only accessible for reading. Unfortunately this leads to a conflict with the "shallow-copy" concept of ICL images.

void func(const Img8u &image){
// given image is const -> data must not be changed
Img8u x = image;
// x is a shallow copy of image (data is shared)
x.clear();
// this affects also the data of image (which shall not
// be permitted
}

To avoid this conflict, we tried to forbid creating un-const shallow copies of const images by implementing no default copy constructor:

Img<T>(const Img<T> &other) {... }

but an un-const version of this:

Img<T>(Img<T> &other) {... }

Here we face some GCC related problem, because gcc is not able for an implicit cast of an Img<T> to an Img<T>& in constructor calls:

template<class T> class Img<T>{ ... };
Img8u create_image(){
return Img8u();
}
int main(){
Img8u a = create_image();
}

Here, the compiler gives error: "Can't find constructor Img<T>(Img<T>)". In fact, this constructor can not exist: it must have the following syntax: Img<T>(Img<T>&)

Probably further gcc versions will fix this problem!

Until then, we accept the const leak at constructor and assignment operator and reimplemented them as ..(const Img<T> &other)

IPP/MKL-optimization

The Intel Integrated Performance Primitives (Intel IPP) and the Intel Math Kernel Library (Intel MKL) are assembler libraries that provide a C-interface to a large set of highly optimized and hardware accelerated functions for image processing, and other numerical problems for all processors providing MMX and SSE instruction sets, i.e. most common Intel and AMD processors. As far as we know, Intel IPP and Intel MKL can be used freely for non-commercial use, but not for research. Fortunately, IPP/MKL support is purely optional. Therefore you can simply develop your application with an ICL-build without IPP/MKL-optimization and re-link it against an optimized ICL-build lateron.

IPP Acceleration

If Intel IPP is available, it is highly integrated into ICL:

We tuned the Img-class to facilitate the use of IPP functions.

Intel MKL

In contrast to the matrix package for small matrices, which is optimized for matrices up to dimensions of 6x6, Intel MKL is optimized for larger matrices. As under certain conditions, MKL is more then 100 times faster, we decided to add MKL support as well. However, MKL is currently only used in the implementation of some DynMatrix multiplication functions in the ICLUtils package.

Modules

If you like to explore the ICLCore documentation by your own, take a look a the following sub modules:

  1. Vector Types
  2. General Information
  3. Image Classes and Support Functions
  4. String Manipuation Functions

Optional 3rd Party Dependencies

The list of 3rd party dependencies is given on <a href="http://www.iclcv.org>ICL's website

Function Documentation

template<class T >
ImgBasePtrPtr<T> icl::core::bpp ( Img< T > *  image)

utility function to cast an Img<T> implicitly into an ImgBase **

This function may be useful, whenever you are working with Img<T> objects are Pointers. As some functions expect ImgBase** arguments to ensure, that the destination image can be adapted even in its depth, this function can be used to get an ImgBase** that points to a pointer of the given image. This is a necessary concept, but mutch additional work, if you are just want to try out some algorithm on your Img<T>. If you are shure, that the result image will not be adapted by the function you can easily use the bpp-function, which will additionally warn you if this assumption was wrong. The following code example demonstrates this:

void apply_func(ImageBase **dst){
...
// this function may realloc dst
}
Img8u src;
Img8u dst;
// without bpp function
ImgBase *pDst= &Dst;
apply_func(&src,&pDst); // this will cause an error if pDst is reallocated
// because stack objects may not be released
// with bpp function
apply_func(&src,bpp(dst)); // this will cause a warning at maxinum
template<class T >
ImgBasePtrPtr<T> icl::core::bpp ( Img< T > &  image)

utility function to cast an Img<T>* implicitly into an ImgBase **

see the above function for more details

template<class T >
void icl::core::clearChannelROI ( Img< T > *  im,
int  c,
clearVal,
const utils::Point offs,
const utils::Size size 
)
inline

sets an arbitrary image ROI to a given value

This function is used as basic operation for higher level image operation like Img<T>::clear(T value).

Parameters
imimage
cchannel
clearValvalue for the cleared pixels
offslower left point for the to-be-cleared region
sizesize of the to-be-cleared region
template<class ImgType >
const ImgType* icl::core::combineImages ( const std::vector< const ImgType * > &  vec)

Combine several images using shallow copy.

template<class ImgType >
ImgType* icl::core::combineImages ( const std::vector< ImgType * > &  vec)

Combine several images using shallow copy. Non-const version.

template<class S , class D >
void icl::core::convertChannel ( const Img< S > *  src,
int  srcC,
Img< D > *  dst,
int  dstC 
)
inline

copies/converts the data from one image to another image (IPP-OPTIMIZED)

The deepCopyChannel function is a higher lever wrapper for the icl::copy(..) function. It extracts the data pointers and data dimension from the source- and destination image to call icl::copy(..)

Parameters
srcsource image
srcCsource images channel
dstdestination image
dstCdestination image channel
template<class T >
void icl::core::deepCopyChannel ( const Img< T > *  src,
int  srcC,
Img< T > *  dst,
int  dstC 
)
inline

Copies the channel from one image to another.

template<class T >
void icl::core::deepCopyChannelROI ( const Img< T > *  src,
int  srcC,
const utils::Point srcOffs,
const utils::Size srcSize,
Img< T > *  dst,
int  dstC,
const utils::Point dstOffs,
const utils::Size dstSize 
)
inline

copies the channel roi from one image to another

{{{ check function }}}Essential deep copy function.

Parameters
srcsource image
srcCsource channel
srcOffssource images ROI offset
srcSizesource images ROI size
dstdestination image
dstCdestination channel
dstOffsdestination images ROI offset
dstSizedestination images ROI size (must be equal to srcSize)
ICLCore_API ImgBase* icl::core::ensureCompatible ( ImgBase **  dst,
depth  d,
const ImgParams params 
)

ensures that an image has given depth and parameters

ImgBase* icl::core::ensureCompatible ( ImgBase **  dst,
depth  d,
const utils::Size size,
int  channels,
const utils::Rect roi = utils::Rect::null 
)
inline

ensures that an image has given depth, size, number of channels and ROI

If the given pointer to the destination image is 0, a new image with appropriate properties is created. Else the image properties are checked and adapted to the new values if neccessary.

Parameters
dstpoints the destination ImgBase*. If the images depth hasa to be converted, then a new Img<T>* is created at (*dst).
ddesired image depth
sizedesired image size
channelsdesired number of channels, if eFormat == formatMatrix for other format, the number of channels is determined by the format
roidesired ROI rectangle. If the ROI parameters are not given, the ROI will comprise the whole image.
ImgBase* icl::core::ensureCompatible ( ImgBase **  dst,
depth  d,
const utils::Size size,
format  fmt,
const utils::Rect roi = utils::Rect::null 
)
inline

ensures that an image has given depth, size, format and ROI

ICLCore_API ImgBase* icl::core::ensureCompatible ( ImgBase **  dst,
depth  d,
const utils::Size size,
int  channels,
format  fmt,
const utils::Rect roi = utils::Rect::null 
)

ensures that an image has given parameters

The given format must be compatible to the given channel count. If not: The format is set to "formatMatrix" and an exception is thrown.

ICLCore_API ImgBase* icl::core::ensureCompatible ( ImgBase **  dst,
const ImgBase src 
)

ensures that the destination image gets same depth, size, channel count, depth, format and ROI as source image

If the given pointer to the destination image is 0, a new image is created as a deep copy of poSrc. Else the image properties are checked and adapted to the new values if neccessary. Note: If the destination images depth differs from the source images depth, it is adapted by deleting the old destination pointer by calling delete *ppoDst and creating a brand new Img<T> where T is the destination images depth.

Parameters
dstpoints the destination ImgBase*. If the images depth has to be converted, then a new Img<T>* is created, at (*ppoDst).
srcsource image. All params of this image are extracted to define the destination parameters for *ppoDst.
ICLCore_API ImgBase* icl::core::ensureDepth ( ImgBase **  ppoImage,
depth  eDepth 
)

ensures that an image has the specified depth

This function will delete the original image pointed by (*ppoImage) and create a new one with identical parameters, if the given depth parameter is not the images depth. If the given image pointer (*ppoImage) is NULL, then an empty image of specified depth es created at *ppoImage. If ppoImage is NULL a new Image is created and returned. call:

void func(ImgBase **ppoDst){
   ImgBase *poDst = ensureDepth(ppoDst,anyDepth);
}

to ensure that an image is valid.

Parameters
ppoImagepointer to the image-pointer
eDepthdestination depth of the image
Returns
the new image (this can be used e.g. if ppoImage is NULL)
ICLCore_API void icl::core::flippedCopy ( axis  eAxis,
const ImgBase poSrc,
ImgBase **  ppoDst = 0 
)

mirror copy of an image from source to destination image (1:1 copy)

This function creates a flipped instance of this image. Even the ROI is flipped internally. Example:

  ......                    ......     r = roi
  ..rrrr  -> flipped x ->   rrrr..
  ..rrrr                    rrrr..
Parameters
eAxisaxis to flip
poSrcsource image
ppoDstimage. This image is exploited if possible. It is adjusted to the source image in depth, size,channels,format,and time
template<class T >
ICLCore_API void icl::core::flippedCopyChannelROI ( axis  eAxis,
const Img< T > *  src,
int  srcC,
const utils::Point srcOffs,
const utils::Size srcSize,
Img< T > *  dst,
int  dstC,
const utils::Point dstOffs,
const utils::Size dstSize 
)

mirror copy ROI data from one image to the ROI of another image (IPP-OPTIMIZED)

This function is used by flippedCopyROI and Mirror operator.

Parameters
eAxismirror axis (axisHorz, axisVert or axisBoth)
srcsource image
srcCsource image channel
srcOffssource images ROI-offset (src->getROIOffset() is not regarded)
srcSizesource images ROI-size (src->getROISize() is not regarded)
dstdestination image
dstCdestination image channel
dstOffsdestination images ROI-offset (dst->getROIOffset() is not regarded)
dstSizedestination images ROI-size (dst->getROISize() is not regarded)
dstSizedestination images ROI-size (dst->getROISize() is not regarded)
ICLCore_API void icl::core::flippedCopyROI ( axis  eAxis,
const ImgBase poSrc,
ImgBase **  ppoDst = 0 
)

mirror copy of an images ROI into a destination images ROI

Example:

  ......                    ......    R,r = roi
  ..RRrr  -> flipped x ->   rrRR..
  ..RRrr                    rrRR..
Parameters
eAxisaxis to flip
poSrcsource image
ppoDstdestination image (expoited if possible). This images ROI size must be equal to ppoDst's ROI size otherwise an errormessage is shown, and the function returns 0. If ppoDst is null, a new image is created with size of this images ROI size. If ppoDst points to NULL, the new image is created at *ppoDst.
Returns
flippedCopy
ICLCore_API ImgBase* icl::core::imgNew ( depth  d = depth8u,
const ImgParams params = ImgParams::null 
)

create a new image instance of the given depth type and with given parameters

This function provides a common interface to instantiate images of arbitrary depth, selecting the appropriate constructor of the derived class Img<T>.

Instead of selecting the correct constructor by yourself, you can simply call this common constructor function. To illustrate the advantage, look at the following example:

  class Foo{
     public:
     Foo(...,Depth eDepth,...):
         poImage(eDepth==depth8u ? new Img8u(...) : new Img32f(...)){
     }
     private:
     ImgBase *poImage;         
  };

This will work, but the "?:"-statement makes the code hardly readable. The following code extract will show the advantage of using the imgNew instantiator:

  class Foo{
     public:
     Foo(...,Depth eDepth,...):
         poImage(imgNew(eDepth,...)){
     }
     private:
     ImgBase *poImage;         
  };

The readability of the code is much better.

Parameters
ddepth of the image that should be created
paramsstruct containing all neccessary parameters like: size: size of the new image fmt: format of the new image channels: number of channels (of an formatMatrix-type image) roi: ROI rectangle of the new image
Returns
the new ImgBase* with underlying Img<Type>, where Type is depending on the first parameter eDepth
ImgBase* icl::core::imgNew ( depth  d,
const utils::Size size,
format  fmt,
const utils::Rect roi = utils::Rect::null 
)
inline

creates a new Img (see the above function for more details)

ImgBase* icl::core::imgNew ( depth  d,
const utils::Size size,
int  channels = 1,
const utils::Rect roi = utils::Rect::null 
)
inline

creates a new Img (see the above function for more details)

ImgBase* icl::core::imgNew ( depth  d,
const utils::Size size,
int  channels,
format  fmt,
const utils::Rect roi = utils::Rect::null 
)
inline

creates a new Img (see the above function for more details)