/* Img.cpp Written by: Michael Götting (2004) University of Bielefeld AG Neuroinformatik mgoettin@techfak.uni-bielefeld.de */ #include namespace icl { // {{{ constructors and destructors //---------------------------------------------------------------------------- template Img::Img(const ImgParams ¶ms): // {{{ open ImgBase(icl::getDepth(),params){ FUNCTION_LOG("Img(params)"); for(int i=0;i Img::Img(const Size &s,int iChannels): // {{{ open ImgBase(icl::getDepth(),ImgParams(s,iChannels)){ FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << iChannels << ") this:" << this ); for(int i=0;i Img::Img(const Size& s, format eFormat): // {{{ open ImgBase(icl::getDepth(),ImgParams(s,eFormat)){ FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << translateFormat(eFormat) << ") this:" << this ); for(int i=0;i Img::Img(const Size &s,int iChannels, format fmt): // {{{ open ImgBase(icl::getDepth(),ImgParams(s,iChannels,fmt)){ FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << iChannels << "," << translateFormat(fmt) << ") this:" << this ); for(int i=0;i Img::Img(const Size &s, int channels, const std::vector& vptData) : // {{{ open ImgBase(icl::getDepth(),ImgParams(s,channels)) { ICLASSERT_THROW (getChannels () <= (int) vptData.size(), InvalidImgParamException("channels")); FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << channels << ",Type**) this:" << this); typename std::vector::const_iterator it = vptData.begin(); for(int i=0; i(*it,false)); } } // }}} //---------------------------------------------------------------------------- template Img::Img(const Size &s, int channels, format fmt, const std::vector& vptData) : // {{{ open ImgBase(icl::getDepth(),ImgParams(s,channels,fmt)){ ICLASSERT_THROW (getChannels () <= (int) vptData.size(), InvalidImgParamException("channels")); FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << channels << "," << translateFormat(fmt) << ",Type**) this:" << this); typename std::vector::const_iterator it = vptData.begin(); for(int i=0; i(*it,false)); } } // }}} //---------------------------------------------------------------------------- template Img::Img(const Size &s, format eFormat, const std::vector& vptData) : // {{{ open ImgBase(icl::getDepth(),ImgParams(s,eFormat)){ ICLASSERT_THROW (getChannels () <= (int) vptData.size(), InvalidImgParamException("channels")); FUNCTION_LOG("Img(" << s.width <<","<< s.height << "," << translateFormat(eFormat) << ",Type**) this:" << this); typename std::vector::const_iterator it = vptData.begin(); for(int i=0; i(*it,false)); } } // }}} //---------------------------------------------------------------------------- template Img::Img(const Img& tSrc): // {{{ open ImgBase(tSrc.getDepth(),tSrc.getParams()) { FUNCTION_LOG("this: " << this); m_vecChannels = tSrc.m_vecChannels; } // }}} //---------------------------------------------------------------------------- template Img::~Img() // {{{ open { FUNCTION_LOG("this: " << this); } // }}} // }}} // {{{ assign operator: shallow copy //---------------------------------------------------------------------------- template Img& Img::operator=(const Img& tSrc) { FUNCTION_LOG(""); //---- Assign new channels to Img ---- m_oParams = tSrc.getParams (); m_vecChannels = tSrc.m_vecChannels; //take over timestamp this->setTime(tSrc.getTime()); return *this; } // }}} // {{{ class organisation : //---------------------------------------------------------------------------- template ImgBase* Img::deepCopy(ImgBase* poDst) const // {{{ open { FUNCTION_LOG(""); if(!poDst) poDst = imgNew(getDepth()); switch (poDst->getDepth()){ case depth8u: return convertTo(poDst->asImg()); break; case depth16s: return convertTo(poDst->asImg()); break; case depth32s: return convertTo(poDst->asImg()); break; case depth32f: return convertTo(poDst->asImg()); break; case depth64f: return convertTo(poDst->asImg()); break; default: ICL_INVALID_DEPTH; break; } } // }}} //-------------------------------------------------------------------------- template ImgBase* Img::scaledCopy(ImgBase *poDst,scalemode eScaleMode) const // {{{ open { FUNCTION_LOG(""); if(!poDst || isEqual(poDst->getSize(),poDst->getChannels())){ SECTION_LOG("deep copy case"); return deepCopy(poDst); } poDst->setFormat(getFormat()); poDst->setTime(getTime()); poDst->setChannels(getChannels()); switch (poDst->getDepth()){ case depth8u: for(int c=0;c(this,c,Point::null,getSize(), poDst->asImg(),c,Point::null,poDst->getSize(),eScaleMode); } break; case depth16s: for(int c=0;c(this,c,Point::null,getSize(), poDst->asImg(),c,Point::null,poDst->getSize(),eScaleMode); } break; case depth32s: for(int c=0;c(this,c,Point::null,getSize(), poDst->asImg(),c,Point::null,poDst->getSize(),eScaleMode); } break; case depth32f: for(int c=0;c(this,c,Point::null,getSize(), poDst->asImg(),c,Point::null,poDst->getSize(),eScaleMode); } break; case depth64f: for(int c=0;c(this,c,Point::null,getSize(), poDst->asImg(),c,Point::null,poDst->getSize(),eScaleMode); } break; default: ICL_INVALID_DEPTH; break; } float fScaleX = ((float)poDst->getSize().width)/(float)(getSize().width); float fScaleY = ((float)poDst->getSize().height)/(float)(getSize().height); Rect roi = getROI(); roi.x = (int)rint(fScaleX * roi.x); roi.y = (int)rint(fScaleY * roi.y); roi.width = (int)rint(fScaleX * roi.width); roi.height = (int)rint(fScaleY * roi.height); roi = roi & Rect (Point::null, poDst->getSize()); poDst->setROI (roi); poDst->getTime() = this->getTime(); return poDst; } // }}} //-------------------------------------------------------------------------- template ImgBase* Img::deepCopyROI(ImgBase *poDst) const // {{{ open { FUNCTION_LOG(""); if(!poDst){ poDst = imgNew(getDepth(), ImgParams(getROISize(),getChannels(),getFormat())); }else{ poDst->setChannels(getChannels()); poDst->setFormat(getFormat()); } ICLASSERT_RETURN_VAL( getROISize() == poDst->getROISize() , poDst); switch (poDst->getDepth()){ case depth8u: for(int c=0;c(this, c, getROIOffset(), getROISize(), poDst->asImg(), c, poDst->getROIOffset(),poDst->getROISize()); } break; case depth16s: for(int c=0;c(this, c, getROIOffset(), getROISize(), poDst->asImg(), c, poDst->getROIOffset(),poDst->getROISize()); } break; case depth32s: for(int c=0;c(this, c, getROIOffset(), getROISize(), poDst->asImg(), c, poDst->getROIOffset(),poDst->getROISize()); } break; case depth32f: for(int c=0;c(this, c, getROIOffset(), getROISize(), poDst->asImg(), c, poDst->getROIOffset(),poDst->getROISize()); } break; case depth64f: for(int c=0;c(this, c, getROIOffset(), getROISize(), poDst->asImg(), c, poDst->getROIOffset(),poDst->getROISize()); } break; default: ICL_INVALID_DEPTH; break; } return poDst; } // }}} //---------------------------------------------------------------------------- template ImgBase* Img::scaledCopyROI(ImgBase *poDst, scalemode eScaleMode) const // {{{ open { FUNCTION_LOG(""); if(!poDst || getROISize() == poDst->getROISize()){ return deepCopyROI(poDst); } poDst->setFormat(getFormat()); poDst->setChannels(getChannels()); switch (poDst->getDepth()){ case depth8u: for(int c=0;c(this,c,getROIOffset(),getROISize(), poDst->asImg(),c,poDst->getROIOffset(), poDst->getROISize(), eScaleMode); } break; case depth16s: for(int c=0;c(this,c,getROIOffset(),getROISize(), poDst->asImg(),c,poDst->getROIOffset(), poDst->getROISize(), eScaleMode); } break; case depth32s: for(int c=0;c(this,c,getROIOffset(),getROISize(), poDst->asImg(),c,poDst->getROIOffset(), poDst->getROISize(), eScaleMode); } break; case depth32f: for(int c=0;c(this,c,getROIOffset(),getROISize(), poDst->asImg(),c,poDst->getROIOffset(), poDst->getROISize(), eScaleMode); } break; case depth64f: for(int c=0;c(this,c,getROIOffset(),getROISize(), poDst->asImg(),c,poDst->getROIOffset(), poDst->getROISize(), eScaleMode); } break; default: ICL_INVALID_DEPTH; break; } return poDst; } // }}} template ImgBase* Img::flippedCopyROI(ImgBase *poDst, axis eAxis) const // {{{ open { FUNCTION_LOG(""); if(!poDst){ poDst = imgNew(getDepth(), ImgParams(getROISize(),getChannels(),getFormat())); } else { ICLASSERT_RETURN_VAL( poDst->getROISize() == getROISize() ,poDst); poDst->setChannels(getChannels()); } if (poDst->getDepth() == this->getDepth()) { for(int c=0;casImg(), c, poDst->getROIOffset(),poDst->getROISize()); } } else { switch (poDst->getDepth()){ case depth8u:{ Img *pD = poDst->asImg(); for(int c=0;cgetROIOffset(),poDst->getROISize()); pD->mirror (eAxis, c, poDst->getROIOffset(),poDst->getROISize()); } break; } break; case depth16s:{ Img *pD = poDst->asImg(); for(int c=0;cgetROIOffset(),poDst->getROISize()); pD->mirror (eAxis, c, poDst->getROIOffset(),poDst->getROISize()); } break; } case depth32s:{ Img *pD = poDst->asImg(); for(int c=0;cgetROIOffset(),poDst->getROISize()); pD->mirror (eAxis, c, poDst->getROIOffset(),poDst->getROISize()); } break; } case depth32f:{ Img *pD = poDst->asImg(); for(int c=0;cgetROIOffset(),poDst->getROISize()); pD->mirror (eAxis, c, poDst->getROIOffset(),poDst->getROISize()); } break; } case depth64f:{ Img *pD = poDst->asImg(); for(int c=0;cgetROIOffset(),poDst->getROISize()); pD->mirror (eAxis, c, poDst->getROIOffset(),poDst->getROISize()); } break; } default: ICL_INVALID_DEPTH; break; } } return poDst; } // }}} //---------------------------------------------------------------------------- template void Img::detach(int iIndex) // {{{ open { FUNCTION_LOG("detach(" << iIndex << ")"); ICLASSERT_RETURN(iIndex < getChannels()); //---- Make the whole Img independent ---- for(int i=getStartIndex(iIndex),iEnd=getEndIndex(iIndex);i void Img::removeChannel(int iChannel) // {{{ open { FUNCTION_LOG("removeChannel(" << iChannel << ")"); ICLASSERT_RETURN(validChannel(iChannel)); m_vecChannels.erase(m_vecChannels.begin()+iChannel); m_oParams.setChannels(m_vecChannels.size()); } // }}} //---------------------------------------------------------------------------- template void Img::append(Img *poSrc, int iIndex) // {{{ open { FUNCTION_LOG(""); ICLASSERT_RETURN( poSrc ); // iIndex < 0 is ok and means all channels ICLASSERT_RETURN( iIndex < poSrc->getChannels() ); ICLASSERT_RETURN( poSrc->getSize() == getSize() ); std::copy (poSrc->m_vecChannels.begin() + poSrc->getStartIndex(iIndex), poSrc->m_vecChannels.begin() + poSrc->getEndIndex(iIndex), back_inserter(m_vecChannels)); m_oParams.setChannels(m_vecChannels.size()); } // }}} template void Img::append(Img *poSrc, const std::vector& vChannels) // {{{ open { FUNCTION_LOG(""); ICLASSERT_RETURN( poSrc ); ICLASSERT_RETURN( poSrc->getSize() == getSize() ); const int iMaxChannels = poSrc->getChannels(); for (std::vector::const_iterator it=vChannels.begin(), end=vChannels.end(); it != end; ++it) { if (*it < 0 || *it >= iMaxChannels) { ERROR_LOG ("channel index out of range: " << *it); } else { m_vecChannels.push_back (poSrc->m_vecChannels[*it]); } } m_oParams.setChannels(m_vecChannels.size()); } // }}} //---------------------------------------------------------------------------- template void Img::swapChannels(int iIndexA, int iIndexB) // {{{ open { FUNCTION_LOG("swapChannels("< void Img::scale(const Size &size, scalemode eScaleMode) // {{{ open { FUNCTION_LOG(""); ICLASSERT_RETURN (size.width > 0 && size.height > 0); if (!isEqual(size,getChannels())) { Img oTmp(size,getChannels(),getFormat()); scaledCopy(&oTmp,eScaleMode); (*this)=oTmp; } } // }}} //---------------------------------------------------------------------------- template void Img::mirror(axis eAxis, bool bOnlyROI) // {{{ open { FUNCTION_LOG(""); const Point& oOffset = bOnlyROI ? getROIOffset() : Point::null; const Size& oSize = bOnlyROI ? getROISize() : getSize(); for (int c=0; c < getChannels(); ++c) { this->mirror (eAxis, c, oOffset, oSize); } } // }}} static inline void* getPointerOffset (const void* begin, int x, int y, int iByteSize, int iLineLen) { // {{{ open FUNCTION_LOG(""); return ((char*)begin) + iByteSize * (x + y*iLineLen); } // }}} static bool getMirrorPointers (axis eAxis, bool bInplace, const void* srcBegin, const void* dstBegin, int iByteSize, const Point& oSrcOffset, int iSrcLineStep, const Point& oDstOffset, int iDstLineStep, const Size& oSize, void** pS, void** pD, void** pE, void** pELine, int& iLineWarpS, int& iLineWarpD) { // {{{ open FUNCTION_LOG(""); void *&s=*pS, *&d=*pD, *&e=*pE, *&eLine=*pELine; int iRows=0, iCols=0; int iSrcLineLen = iSrcLineStep / iByteSize; int iDstLineLen = iDstLineStep / iByteSize; switch (eAxis) { case axisHorz: /* ..................... ....s->++++++++++l... ....+++++++++++++.... ....e------------.... ....*************.... ....d->**********.... ..................... */ iRows = bInplace ? oSize.height/2 : oSize.height; iCols = oSize.width; iLineWarpS = iSrcLineLen - iCols; iLineWarpD = -(iDstLineLen+iCols); s = getPointerOffset (srcBegin, oSrcOffset.x, oSrcOffset.y, iByteSize, iSrcLineLen); d = getPointerOffset (dstBegin, oDstOffset.x, oDstOffset.y + oSize.height - 1, iByteSize, iDstLineLen); e = ((char*)s) + iRows * iSrcLineStep; break; case axisVert: /* ..................... ....s->++++|l*<-d.... ....+++++++|*****.... ....+++++++|*****.... ....+++++++|*****.... ....+++++++|*****.... ....e................ */ iRows = oSize.height; iCols = bInplace ? oSize.width/2 : oSize.width; iLineWarpS = iSrcLineLen - iCols; iLineWarpD = iDstLineLen + iCols; s = getPointerOffset (srcBegin, oSrcOffset.x, oSrcOffset.y, iByteSize, iSrcLineLen); d = getPointerOffset (dstBegin, oDstOffset.x + oSize.width - 1, oDstOffset.y, iByteSize, iDstLineLen); e = ((char*)s) + iRows * iSrcLineStep; break; case axisBoth: /* ..................... ....s->++++++++++l... ....+++++++++++++.... ....+++++++e*****.... ....*************.... ....**********<-d.... ..................... */ iRows = bInplace ? oSize.height/2 : oSize.height; iCols = oSize.width; iLineWarpS = iSrcLineLen - iCols; iLineWarpD = iCols - iDstLineLen; s = getPointerOffset (srcBegin, oSrcOffset.x, oSrcOffset.y, iByteSize, iSrcLineLen); d = getPointerOffset (dstBegin, oDstOffset.x + oSize.width - 1, oDstOffset.y + oSize.height - 1, iByteSize, iDstLineLen); e = ((char*)s) + iRows * iSrcLineStep; if (bInplace && oSize.height % 2) { // odd ROI height iRows++; e = (char*)e + iByteSize * (oSize.width/2); } break; } eLine = ((char*)s) + iCols * iByteSize; return (iRows != 0 && iCols != 0); } // }}} template void Img::mirror(axis eAxis, int iChannel, const Point& oOffset, const Size& oSize) // {{{ open { FUNCTION_LOG(""); static const int aiDstStep[] = {1,-1,-1}; int iLineWarpS, iLineWarpD; register Type *s=0, *d=0, *e=0, *eLine=0; /* source pointer, destination pointer, end pointer, line end pointer */ if (!getMirrorPointers (eAxis, true, getData(iChannel), getData(iChannel), sizeof(Type), oOffset, getLineStep(), oOffset, getLineStep(), oSize, (void**) &s, (void**) &d, (void**) &e, (void**) &eLine, iLineWarpS, iLineWarpD)) return; do { std::swap (*s, *d); ++s; d += aiDstStep[eAxis]; if (s == eLine) { eLine += getWidth(); // end of line pointer jumps whole image width s += iLineWarpS; // source pointer jumps iLineWarpS d += iLineWarpD; } } while (s != e); } // }}} //---------------------------------------------------------------------------- template void Img::setSize(const Size &s) // {{{ open { FUNCTION_LOG(""); Size oNewSize(s.width<0?getSize().width:s.width, s.height<0?getSize().height:s.height); //---- estimate destination values in respect to defaults ---- if (oNewSize != getSize()) { m_oParams.setSize(oNewSize); for(int i=0;i void Img::setChannels(int iNumNewChannels) // {{{ open { FUNCTION_LOG(""); ICLASSERT_RETURN(iNumNewChannels >= 0); if (iNumNewChannels == getChannels()) return; if(iNumNewChannels < getChannels()) { //---- reduce number of channels ---- m_vecChannels.erase(m_vecChannels.begin() + iNumNewChannels, m_vecChannels.end()); }else{ //---- Extend number of channels ---- m_vecChannels.reserve (iNumNewChannels); for(int i=getChannels();i < iNumNewChannels; ++i) m_vecChannels.push_back(createChannel()); } m_oParams.setChannels(m_vecChannels.size()); } // }}} //---------------------------------------------------------------------------- template inline void Img::replaceChannel(int iThisIndex, Img* poSrc, int iOtherIndex) // {{{ open { FUNCTION_LOG(""); ICLASSERT_RETURN(validChannel(iThisIndex)); ICLASSERT_RETURN(poSrc->validChannel(iOtherIndex)); m_vecChannels[iThisIndex] = poSrc->m_vecChannels[iOtherIndex]; } // }}} // }}} // {{{ Get Min/Max functions: // {{{ getMax template Type Img::getMax() const { FUNCTION_LOG(""); if (getChannels() == 0) return 0; Type tMax = getMax(0); for(int i=1;i Type Img::getMax(int iChannel) const { FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN_VAL( validChannel(iChannel), 0 ); const_iterator it = getROIIterator(iChannel); if (!it.inRegion()) return 0; // empty region Type vMax = *it; ++it; for (; it.inRegion(); ++it) { vMax = std::max (vMax, *it); } return vMax; } #ifdef WITH_IPP_OPTIMIZATION template template inline Type Img::ippGetMax(int iChannel) const { FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN_VAL( validChannel(iChannel), 0 ); Type vMax = 0; ippiFunc (getROIData(iChannel),getLineStep(),getROISize(),&vMax); return vMax; } #define ICL_INSTANTIATE_DEPTH(T) \ template<> icl ## T \ Img::getMax(int iChannel) const {return ippGetMax(iChannel);} ICL_INSTANTIATE_DEPTH(8u) ICL_INSTANTIATE_DEPTH(16s) ICL_INSTANTIATE_DEPTH(32f) #undef ICL_INSTANTIATE_DEPTH #endif // }}} // {{{ getMin template Type Img::getMin() const { FUNCTION_LOG(""); if (getChannels() == 0) return 0; Type tMin = getMin(0); for(int i=1;i Type Img::getMin(int iChannel) const { FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN_VAL( validChannel(iChannel), 0 ); const_iterator it = getROIIterator(iChannel); if (!it.inRegion()) return 0; // empty region Type vMin = *it; ++it; for (; it.inRegion(); ++it) { vMin = std::min (vMin, *it); } return vMin; } #ifdef WITH_IPP_OPTIMIZATION template template inline Type Img::ippGetMin(int iChannel) const { FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN_VAL( validChannel(iChannel), 0 ); Type vMin = 0; ippiFunc (getROIData(iChannel),getLineStep(),getROISize(),&vMin); return vMin; } #define ICL_INSTANTIATE_DEPTH(T) \ template<> icl ## T \ Img::getMin(int iChannel) const {return ippGetMin(iChannel);} ICL_INSTANTIATE_DEPTH(8u) ICL_INSTANTIATE_DEPTH(16s) ICL_INSTANTIATE_DEPTH(32f) #undef ICL_INSTANTIATE_DEPTH #endif // }}} // {{{ getMinMax template void Img::getMinMax(Type &rtMin, Type &rtMax) const { FUNCTION_LOG(""); if (getChannels() == 0) { rtMin=rtMax=0; return; } Type tMin, tMax; getMinMax(rtMin, rtMax, 0); for(int i=1;i void Img::getMinMax(Type &rtMin, Type &rtMax, int iChannel) const { rtMin = rtMax = 0; FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN (validChannel(iChannel)); const_iterator it = getROIIterator(iChannel); if (!it.inRegion()) return; // empty region: return with 0, 0 rtMin = rtMax = *it; ++it; for (; it.inRegion(); ++it) { rtMin = std::min (rtMin, *it); rtMax = std::max (rtMax, *it); } } #ifdef WITH_IPP_OPTIMIZATION template template inline void Img::ippGetMinMax(Type& rtMin, Type& rtMax, int iChannel) const { rtMin = rtMax = 0; FUNCTION_LOG("iChannel: " << iChannel); ICLASSERT_RETURN( validChannel(iChannel) ); ippiFunc (getROIData(iChannel),getLineStep(),getROISize(), &rtMin, &rtMax); } #define ICL_INSTANTIATE_DEPTH(T) \ template<> void \ Img::getMinMax(icl ## T& rtMin, icl ## T& rtMax, int iChannel) const \ {ippGetMinMax(rtMin, rtMax, iChannel);} ICL_INSTANTIATE_DEPTH(8u) ICL_INSTANTIATE_DEPTH(16s) ICL_INSTANTIATE_DEPTH(32f) #undef ICL_INSTANTIATE_DEPTH #endif // }}} // }}} // {{{ Auxillary functions template SmartPtr Img::createChannel(Type *ptDataToCopy) const // {{{ open { FUNCTION_LOG(""); int dim = getDim(); if(!dim){ return SmartPtr(); } Type *ptNewData = new Type[dim]; if(ptDataToCopy){ memcpy(ptNewData,ptDataToCopy,getDim()*sizeof(Type)); }else{ std::fill(ptNewData,ptNewData+dim,0); } return SmartPtr(ptNewData); } // }}} // sub-pixel access using linear interpolation template float Img::subPixelLIN(float fX, float fY, int iChannel) const { // {{{ open float fX0 = fX - floor(fX), fX1 = 1.0 - fX0; float fY0 = fY - floor(fY), fY1 = 1.0 - fY0; int xll = (int) fX; int yll = (int) fY; Type* pLL = getData(iChannel) + xll + yll * getWidth(); float a = *pLL; // a b float b = *(++pLL); // c d pLL += getWidth(); float d = *pLL; float c = *(--pLL); // return fX1*fY1*a + fX0*fY1*b + fX0*fY0*d + fX1*fY0*c; return fX1 * (fY1*a + fY0*c) + fX0 * (fY1*b + fY0*d); } // }}} // sub-pixel access using region average interpolation template float Img::subPixelRA(float fX, float fY, int iChannel) const { // {{{ open ERROR_LOG ("region average interpolation is not yet implemented!"); return subPixelLIN (fX, fY, iChannel); } // }}} template Type Img::operator()(float fX, float fY, int iChannel, scalemode eScaleMode) const { // {{{ open switch(eScaleMode) { case 0: return Cast::cast (subPixelNN (fX, fY, iChannel)); case 1: return Cast::cast (subPixelLIN (fX, fY, iChannel)); default: ERROR_LOG ("interpolation method not yet implemented!"); return Cast::cast (subPixelLIN (fX, fY, iChannel)); } } // }}} // }}} // {{{ Basic image manipulation functions // {{{ normalize wrappers template void Img::normalizeAllChannels(Type tDstMin, Type tDstMax) { for (int c=0;c void Img::normalizeChannel(int iChannel, Type tSrcMin, Type tSrcMax, Type tDstMin, Type tDstMax) { normalize(iChannel, tSrcMin, tSrcMax, tDstMin, tDstMax); } template void Img::normalizeChannel(int iChannel, Type tDstMin, Type tDstMax) { Type tMin, tMax; getMinMax(tMin,tMax,iChannel); normalize(iChannel, tMin, tMax, tDstMin, tDstMax); } template void Img::normalizeImg(Type tSrcMin, Type tSrcMax, Type tDstMin, Type tDstMax) { for (int c=0;c void Img::normalizeImg(Type tDstMin, Type tDstMax) { Type tMin, tMax; getMinMax(tMin, tMax); for (int c=0;c void Img::normalize(int iChannel, Type tSrcMin, Type tSrcMax, Type tDstMin, Type tDstMax) { printf("Ohne IPP\n"); float fPixel; float fScale = (float)(tDstMax - tDstMin) / (float)(tSrcMax - tSrcMin); float fShift = (float)(tSrcMax * tDstMin - tSrcMin * tDstMax) / (float)(tSrcMax - tSrcMin); for(iterator p=getROIIterator(iChannel); p.inRegion(); ++p) { fPixel = fShift + (float)(*p) * fScale; if (fPixel <= tDstMin) { fPixel=tDstMin; } else if(fPixel >= tDstMax) { fPixel=tDstMax; } *p = Cast::cast (fPixel); } } #ifdef WITH_IPP_OPTIMIZATION template <> void Img::normalize(int iChannel, icl32f tSrcMin, icl32f tSrcMax, icl32f tDstMin, icl32f tDstMax) { icl32f tScale = (tDstMax - tDstMin) / (tSrcMax - tSrcMin); icl32f tShift = (tSrcMax * tDstMin - tSrcMin * tDstMax)/(tSrcMax - tSrcMin); ippiMulC_32f_C1IR (tScale, getROIData(iChannel), getLineStep(), getROISize()); if (tShift != 0) { ippiAddC_32f_C1IR (tShift, getROIData(iChannel), getLineStep(), getROISize()); } } #endif // }}} // --------------------------------------------------------------------- template void Img::clear(int iIndex, Type tValue, bool bROIOnly) // {{{ open { //---- Log Message ---- FUNCTION_LOG("clear(" << iIndex << "," << tValue << ")"); ICLASSERT_RETURN( iIndex < getChannels() ); Point offs = bROIOnly ? getROIOffset() : Point::null; Size size = bROIOnly ? getROISize() : getSize(); for(int i=getStartIndex(iIndex),iEnd=getEndIndex(iIndex);i void scaledCopyChannelROI(const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize, scalemode eScaleMode) { FUNCTION_LOG(""); ICLASSERT_RETURN( src && dst ); float fSX = ((float)srcSize.width)/(float)(dstSize.width); float fSY = ((float)srcSize.height)/(float)(dstSize.height); float (Img::*subPixelMethod)(float fX, float fY, int iChannel) const; switch(eScaleMode) { case interpolateNN: subPixelMethod = &Img::subPixelNN; break; case interpolateLIN: fSX = ((float)srcSize.width-1)/(float)(dstSize.width); fSY = ((float)srcSize.height-1)/(float)(dstSize.height); subPixelMethod = &Img::subPixelLIN; break; default: ERROR_LOG("unknown interpoation method!"); subPixelMethod = &Img::subPixelNN; break; } ImgIterator itDst(dst->getData(dstC),dst->getSize().width,Rect(dstOffs,dstSize)); int xD = 0; int yD = 0; float yS = srcOffs.y + fSY * yD; for(; itDst.inRegion(); ++itDst) { *itDst = Cast::cast ((src->*subPixelMethod)(srcOffs.x + fSX * xD, yS, srcC)); if (++xD == dstSize.width) { yS = srcOffs.y + fSY * ++yD; xD = 0; } } } // explicit template instantiation #ifndef WITH_IPP_OPTIMIZATION template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); #endif template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); #ifndef WITH_IPP_OPTIMIZATION template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); #endif template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); template void scaledCopyChannelROI(const Img*,int,const Point&,const Size&,Img*,int,const Point&,const Size&,scalemode); // }}} // {{{ flippedCopyChannelROI // mirror copy ROI of one image to the ROI of the other (for selected channel) template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize) { FUNCTION_LOG(""); ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( srcSize == dstSize ); static const int aiDstStep[] = {1,-1,-1}; int iLineWarpS, iLineWarpD; register T *s=0, *d=0, *e=0, *eLine=0; /* source pointer, destination pointer, end pointer, line end pointer */ if (!getMirrorPointers (eAxis, false, src->getData(srcC), dst->getData(dstC), sizeof(T), srcOffs, src->getLineStep(), dstOffs, dst->getLineStep(), srcSize, (void**)&s, (void**)&d, (void**) &e, (void**) &eLine, iLineWarpS, iLineWarpD)) return; if (eAxis == axisHorz) { int iSrcStep = src->getSize().width, iDstStep = dst->getSize().width; int nBytes = sizeof(T) * srcSize.width; // line-wise memcpy is possible for (; s != e; s += iSrcStep, d -= iDstStep) memcpy (d, s, nBytes); return; } do { *d = *s; ++s; d += aiDstStep[eAxis]; if (s == eLine) { eLine += src->getSize().width; // end of line pointer jumps whole image width s += iLineWarpS; // source pointer jumps iLineWarpS d += iLineWarpD; } } while (s != e); } // falls ndef ipp alle // sonst alle bis auf icl8u und icl32f #ifndef WITH_IPP_OPTIMIZATION // explicit template instantiation ** only for this two are optimized using ipp template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize); template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize); #endif template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize); template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize); template void flippedCopyChannelROI(axis eAxis, const Img *src, int srcC, const Point &srcOffs, const Size &srcSize, Img *dst, int dstC, const Point &dstOffs, const Size &dstSize); // }}} // }}} template class Img; template class Img; template class Img; template class Img; template class Img; } //namespace icl