Image Component Library (ICL)
Public Member Functions | Static Public Member Functions | List of all members
icl::core::ImgIterator< Type > Class Template Reference

Iterator class used to iterate through an Images ROI-pixels. More...

#include <ImgIterator.h>

Inheritance diagram for icl::core::ImgIterator< Type >:
icl::math::MatrixSubRectIterator< Type >

Public Member Functions

 ImgIterator ()
 Default Constructor. More...
 
 ImgIterator (Type *data, int imageWidth, const utils::Rect &roi)
 
 ImgIterator (const ImgIterator< Type > &origin, const utils::Size &s, const utils::Point &a)
 3rd Constructor to create sub-regions of an Img-image More...
 
bool inRegionSubROI () const
 to check if iterator is still inside the ROI More...
 
ImgIterator< Type > & operator= (const math::MatrixSubRectIterator< Type > &other)
 Allows to assign const instances. More...
 
const ImgIterator< Type > & operator= (const math::MatrixSubRectIterator< Type > &other) const
 Allows to assign const instances. More...
 
int getROIWidth () const
 returns ROIS width More...
 
int getROIHeight () const
 returns ROIS width More...
 
- Public Member Functions inherited from icl::math::MatrixSubRectIterator< Type >
 MatrixSubRectIterator ()
 Default Constructor. More...
 
 MatrixSubRectIterator (Type *ptData, int matrixWidth, int subRectX, int subRectY, int subRectWidth, int subRectHeight)
 
MatrixSubRectIteratorassign (const MatrixSubRectIterator &other)
 
const MatrixSubRectIteratoroperator= (const MatrixSubRectIterator &other) const
 
const Type & operator * () const
 retuns a reference of the current pixel value (const) More...
 
Type & operator * ()
 retuns a reference of the current pixel value More...
 
MatrixSubRectIteratoroperator++ ()
 moves to the next iterator position (Prefix ++it) More...
 
const MatrixSubRectIteratoroperator++ () const
 const version of pre increment operator More...
 
MatrixSubRectIterator operator++ (int)
 
const MatrixSubRectIterator operator++ (int) const
 const version of post increment operator More...
 
bool inSubRect () const
 to check if iterator is still inside the ROI More...
 
bool operator!= (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
bool operator== (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
bool operator< (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
bool operator> (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
bool operator<= (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
bool operator>= (const MatrixSubRectIterator< Type > &it) const
 compare two iterators More...
 
int getSubRectWidth () const
 returns the length of each row processed by this iterator More...
 
int getSubRectHeight () const
 
void incRow (int numLines=1) const
 move the pixel vertically forward More...
 
int x ()
 returns the current x position of the iterator (wrt matrix origin); More...
 
int y ()
 returns the current y position of the iterator (wrt matrix origin) More...
 

Static Public Member Functions

static const ImgIterator< Type > create_end_roi_iterator (const Type *data, int width, const utils::Rect &roi)
 
- Static Public Member Functions inherited from icl::math::MatrixSubRectIterator< Type >
static const MatrixSubRectIterator< Type > create_end_iterator (const Type *dataOrigin, int matrixWidth, int subRectX, int subRectY, int subRectWidth, int subRectHeight)
 

Additional Inherited Members

- Protected Member Functions inherited from icl::math::MatrixSubRectIterator< Type >
void init ()
 
- Protected Attributes inherited from icl::math::MatrixSubRectIterator< Type >
int m_matrixWidth
 corresponding matrix width More...
 
int m_subRectWidth
 sub rect size of the iterator More...
 
int m_subRectHeight
 
int m_lineStep
 result of m_matrixWidth - m_subRectWidth More...
 
Type * m_dataOrigin
 pointer to the upper matrix data origin (upper left element) More...
 
Type * m_dataCurr
 pointer to the current data element More...
 
Type * m_dataEnd
 pointer to the first element behind the subrect More...
 
Type * m_currLineEnd
 pointer to the first invalid element of the current line More...
 

Detailed Description

template<typename Type>
class icl::core::ImgIterator< Type >

Iterator class used to iterate through an Images ROI-pixels.

The ImgIterator is a utility to iterate line by line through all ROI-pixels of an image. The following ASCII image shows an images ROI.

  1st pixel
    |
....|....................
....+->Xoooooooo......... ---
.......ooooooooo.........  |
.......ooooooooo......... iRoiH
.......ooooooooo.........  |
.......ooooooooo......... ---
.........................
       |-iRoiW-|
|---------iImageW-------|

For image operation like thresholding or filters, it is necessary perform calculation for each ROI- pixel. To achieve that, the programmer needs to Take care about:

The following code examples demonstrate how to handle image ROIs using the ImgIterator drawing on the example of a "find-the-min-pixel"-function. The example can be found in "ICLCore/examples/img-iterator-benchmark.cpp"

IPP Acceleration

Ok, not very meaningful, but state of the art! If ICL is compiled without IPP the builtin-getMin()- function uses std::min_element instead. By the way, IPP-performance is ... legendary – it's about 20-times faster than the C++ fallback!!

icl8u find_min_ipp(const Img8u &i){
return i.getMin();
} // namespace core
}

std::min_element without ROI-iterator

Just for comparison, without roi-handling

icl8u find_min_pointer_stl(const Img8u &i){
return *std::min_element(i.begin(0),i.end(0));
}

std::min_element

Quite easy to use, but surprisingly not slower than the version above, that does not care about ROIs.

icl8u find_min_iterator_stl(const Img8u &i){
return *std::min_element(i.beginROI(0),i.endROI(0));
}

C++ pointer version

This is just a reimplementation of std::min_element, so it's performance is comparable

icl8u find_min_pointer_cpp(const Img8u &i){
const icl8u *p = i.begin(0);
const icl8u *end = p+i.getDim();
icl8u minVal = *p++;
for(;p!=end;++p){
if(*p < minVal) minVal = *p;
}
return minVal;
}

C++ Iterator Version

This is slightly slower than std::min_element because stl uses loop unrolling.

icl8u find_min_iterator_cpp(const Img8u &i){
Img8u::roi_iterator p = i.beginROI(0);
Img8u::const_roi_iterator end = i.endROI(0);
while(++p != end){
if(*p < *minIt) minIt = p;
}
return *minIt;
}

C++ Iterator Version using inRegionSubROI() (OLD-Style)

To compare performance with older iterator use, this function version is also listed here.

icl8u find_min_iterator_cpp_inRegion(const Img8u &i){
Img8u::roi_iterator p = i.beginROI(0);
icl8u minVal = *p++;
for(;p.inRegionSubROI();++p){
if(*p<minVal) minVal = *p;
}
return minVal;
}
\section PERF Performance
Ok, now let's have a look on the numbers: Here are the
results of the demo example icl-img-iterator-benchmark for
a Core-2-Duo with 2GHz and an input image of 1000x1000 pixels:

- <b>STL functions</b>: 1.4ms (iterator is just as fast as the pointer)
- <b>using icl8u* directly</b> also 1.4ms (this is no surprise)
- <b>using iterator directly</b> 1.8ms a little bit slower
- <b>using (old) inRegion()</b> 2ms another little bit slower
- <b>using IPP</b> 0.073ms (applause!)

The ImgIterator<Type> is defined in the Img<Type> as roi_iterator.
This offers an intuitive "stdlib-like" use.

<h3>Using the ImgIterator as ROW-iterator</h3>
The ImgIterator can be used as ROW-iterator too. Just
call incRow() to move the iterator in y-direction


<h3> Using Nested ImgIterators for Neighborhood operations </h3>

In addition to the above functionalities, ImgIterators can be used for
arbitrary image neighborhood operations like convolution, median or
erosion. The following example explains how to create so called sub-region
iterators, that work on a symmetrical neighborhood around a higher level
ImgIterator.

\code
template<class KernelType, class SrcType, class DstType>
void generic_cpp_convolution(const Img<SrcType> &src,
                             Img<DstType> &dst,
                             const KernelType *k,
                             ConvolutionOp &op, int c){
  const ImgIterator<SrcType> s(const_cast<SrcType*>(src.getData(c)), src.getWidth(),Rect(op.getROIOffset(), dst.getROISize()));
  const ImgIterator<SrcType> sEnd = ImgIterator<SrcType>::create_end_roi_iterator(&src,c, Rect(op.getROIOffset(), dst.getROISize()));
  ImgIterator<DstType>      d = dst.beginROI(c);
  Point an = op.getAnchor();
  Size si = op.getMaskSize();
  int factor = op.getKernel().getFactor();
  for(; s != sEnd; ++s){
    const KernelType *m = k;
    KernelType buffer = 0;
    for(const ImgIterator<SrcType> sR (s,si,an);sR.inRegionSubROI(); ++sR, ++m){
      buffer += (*m) * (KernelType)(*sR);
    }
    *d++ = clipped_cast<KernelType, DstType>(buffer / factor);
  }
}
\endcode

This code implements a single channel image convolution operation.


<h2>Performance:Efficiency</h2>
There are 3 major ways to access the pixel data of an image.
- using the (x,y,channel) -operator
- using the ImgIterator
- working directly with the channel data

Each method has its on advantages and disadvantages:
- the (x,y,channel) operator is very intuitive and it can be used
  to write code whiches functionality is very transparent to
  other programmers. The disadvantages are:
  - no implicit ROI - support
  - <b>very slow</b>
- the ImgIterator moves pixel-by-pixel, line-by-line over
  a single image channel. It is highly optimized for processing
  each pixel of an images ROI without respect to the particular
  pixel position in in the image.
  Its advantages are:
  - internal optimized ROI handling
  - direct access to sub-ROIS
  - fast (nearly 10 times faster then the (x,y,channel)-operator
    <b>if used correctly (e.g as input for STL-functions) iterators
    are just as fast as using simple pointers!</b>
- the fastest way to process the image data is work directly
  with the data pointer received from image.getData(channel).
  In this case the programmer himself needs to take care about
  The images ROI. This is only recommended, if no ROI-support
  should be provided.

\section CONST const-ness
Please note that the const-ness of an ImgIterator instance does
not say anything about the sturcture itselft. Hence also const
ImgIterators can be 'moved' using ++-operators or incRow()
method.\n
Instead, const-ness relates to the underlying image, which data
is referenced by the iterator instance. A const image provides
only const ImgIterators which do not allow to change the image data.

Constructor & Destructor Documentation

◆ ImgIterator() [1/3]

template<typename Type>
icl::core::ImgIterator< Type >::ImgIterator ( )
inline

Default Constructor.

Creates an ImgIterator object

◆ ImgIterator() [2/3]

template<typename Type>
icl::core::ImgIterator< Type >::ImgIterator ( Type *  data,
int  imageWidth,
const utils::Rect roi 
)
inline

2nd Constructor creates an ImgIterator object with Type "Type"

Parameters
datapointer to the corresponding channel data
imageWidthwidth of the corresponding image
roiROI rect for the iterator

◆ ImgIterator() [3/3]

template<typename Type>
icl::core::ImgIterator< Type >::ImgIterator ( const ImgIterator< Type > &  origin,
const utils::Size s,
const utils::Point a 
)
inline

3rd Constructor to create sub-regions of an Img-image

This 3rd constructor creates a sub-region iterator, which may be used e.g. for arbitrary neighborhood operations like linear filters, medians, ... See the ImgIterator description for more detail.

Parameters
originreference to source Iterator Object
smask size
amask anchor

Member Function Documentation

◆ create_end_roi_iterator()

template<typename Type>
static const ImgIterator<Type> icl::core::ImgIterator< Type >::create_end_roi_iterator ( const Type *  data,
int  width,
const utils::Rect roi 
)
inlinestatic

◆ getROIHeight()

template<typename Type>
int icl::core::ImgIterator< Type >::getROIHeight ( ) const
inline

returns ROIS width

◆ getROIWidth()

template<typename Type>
int icl::core::ImgIterator< Type >::getROIWidth ( ) const
inline

returns ROIS width

◆ inRegionSubROI()

template<typename Type>
bool icl::core::ImgIterator< Type >::inRegionSubROI ( ) const
inline

to check if iterator is still inside the ROI

This function was replaced by STL-like begin(), end() logic Although in some cases it might be quite useful, so we renamed it rather than deleting it

See also
operator++

◆ operator=() [1/2]

template<typename Type>
ImgIterator<Type>& icl::core::ImgIterator< Type >::operator= ( const math::MatrixSubRectIterator< Type > &  other)
inline

Allows to assign const instances.

◆ operator=() [2/2]

template<typename Type>
const ImgIterator<Type>& icl::core::ImgIterator< Type >::operator= ( const math::MatrixSubRectIterator< Type > &  other) const
inline

Allows to assign const instances.


The documentation for this class was generated from the following file: