Image Component Library (ICL)
|
Iterator class used to iterate through an Images ROI-pixels. More...
#include <ImgIterator.h>
Public Member Functions | |
ImgIterator () | |
Default Constructor. | |
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 | |
bool | inRegionSubROI () const |
to check if iterator is still inside the ROI | |
ImgIterator< Type > & | operator= (const math::MatrixSubRectIterator< Type > &other) |
Allows to assign const instances. | |
const ImgIterator< Type > & | operator= (const math::MatrixSubRectIterator< Type > &other) const |
Allows to assign const instances. | |
int | getROIWidth () const |
returns ROIS width | |
int | getROIHeight () const |
returns ROIS width | |
Static Public Member Functions | |
static const ImgIterator< Type > | create_end_roi_iterator (const Type *data, int width, const utils::Rect &roi) |
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"
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!!
Just for comparison, without roi-handling
Quite easy to use, but surprisingly not slower than the version above, that does not care about ROIs.
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; }
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); Img8u::roi_iterator minIt = p; while(++p != end){ if(*p < *minIt) minIt = p; } return *minIt; }
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; }
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:
The ImgIterator<Type> is defined in the Img<Type> as roi_iterator. This offers an intuitive "stdlib-like" use.
The ImgIterator can be used as ROW-iterator too. Just call incRow() to move the iterator in y-direction
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.
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); } }
This code implements a single channel image convolution operation.
There are 3 major ways to access the pixel data of an image.
Each method has its on advantages and disadvantages:
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.
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.
icl::core::ImgIterator< Type >::ImgIterator | ( | ) | [inline] |
Default Constructor.
Creates an ImgIterator object
icl::core::ImgIterator< Type >::ImgIterator | ( | Type * | data, |
int | imageWidth, | ||
const utils::Rect & | roi | ||
) | [inline] |
2nd Constructor creates an ImgIterator object with Type "Type"
data | pointer to the corresponding channel data |
imageWidth | width of the corresponding image |
roi | ROI rect for the iterator |
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.
origin | reference to source Iterator Object |
s | mask size |
a | mask anchor |
static const ImgIterator<Type> icl::core::ImgIterator< Type >::create_end_roi_iterator | ( | const Type * | data, |
int | width, | ||
const utils::Rect & | roi | ||
) | [inline, static] |
int icl::core::ImgIterator< Type >::getROIHeight | ( | ) | const [inline] |
returns ROIS width
int icl::core::ImgIterator< Type >::getROIWidth | ( | ) | const [inline] |
returns ROIS width
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
ImgIterator<Type>& icl::core::ImgIterator< Type >::operator= | ( | const math::MatrixSubRectIterator< Type > & | other | ) | [inline] |
Allows to assign const instances.
Reimplemented from icl::math::MatrixSubRectIterator< Type >.
const ImgIterator<Type>& icl::core::ImgIterator< Type >::operator= | ( | const math::MatrixSubRectIterator< Type > & | other | ) | const [inline] |
Allows to assign const instances.
Reimplemented from icl::math::MatrixSubRectIterator< Type >.