#include #include namespace icl { #ifdef WITH_IPP_OPTIMIZATION // {{{ Constructor / Destructor MorphologicalOp::MorphologicalOp (const Size& maskSize, char* pcMask, optype eOptype) { if (maskSize.width <= 0 || maskSize.height<=0) { ERROR_LOG("illegal width/height: " << maskSize.width << "/" << maskSize.height); //???? } else setMask (maskSize,pcMask); m_pcMask=(icl8u*)pcMask; m_sMasksize=maskSize; m_eType=eOptype; m_bMorphState8u=false; m_bMorphState32f=false; m_bMorphAdvState8u=false; m_bMorphAdvState32f=false; m_bHas_changed=true; m_bHas_changedAdv=true; } MorphologicalOp::~MorphologicalOp(){ deleteMorphStates(); } // }}} void MorphologicalOp::setMask (Size maskSize, char* pcMask) { // make maskSize odd: maskSize.width = (maskSize.width/2)*2 + 1; maskSize.height = (maskSize.height/2)*2 + 1; NeighborhoodOp::setMask (maskSize); m_pcMask=(icl8u*)pcMask; m_sMasksize=maskSize; m_bHas_changed=true; m_bHas_changedAdv=true; } //ippiMorphologyFree(m_pState8u); void MorphologicalOp::deleteMorphStates(){ if (m_bMorphState8u){ ippiMorphologyFree(m_pState8u); m_bMorphState8u=false; } if (m_bMorphAdvState8u){ ippiMorphAdvFree(m_pAdvState8u); m_bMorphAdvState8u=false; } if (m_bMorphState32f){ ippiMorphologyFree(m_pState32f); m_bMorphState32f=false; } if (m_bMorphAdvState32f){ ippiMorphAdvFree(m_pAdvState32f); m_bMorphAdvState32f=false; } } void MorphologicalOp::checkMorphAdvState8u(const Size roiSize){ if (m_bHas_changedAdv){ deleteMorphStates(); ippiMorphAdvInitAlloc_8u_C1R(&m_pAdvState8u, roiSize, m_pcMask, m_oMaskSize, m_oAnchor); m_bMorphAdvState8u=true; m_bHas_changedAdv=false; } } void MorphologicalOp::checkMorphState8u(const Size roiSize){ if (m_bHas_changed){ deleteMorphStates(); ippiMorphologyInitAlloc_8u_C1R(roiSize.width, m_pcMask, m_oMaskSize, m_oAnchor,&m_pState8u); m_bMorphState8u=true; m_bHas_changed=false; } } void MorphologicalOp::checkMorphAdvState32f(const Size roiSize){ if (m_bHas_changedAdv){ deleteMorphStates(); ippiMorphAdvInitAlloc_32f_C1R(&m_pAdvState32f, roiSize, m_pcMask, m_oMaskSize, m_oAnchor); m_bMorphAdvState32f=true; m_bHas_changedAdv=false; } } void MorphologicalOp::checkMorphState32f(const Size roiSize){ if (m_bHas_changed){ deleteMorphStates(); ippiMorphologyInitAlloc_32f_C1R(roiSize.width, m_pcMask, m_oMaskSize, m_oAnchor,&m_pState32f); m_bMorphState32f=true; m_bHas_changed=false; } } void MorphologicalOp::apply (const ImgBase *poSrc, ImgBase **ppoDst){ FUNCTION_LOG(""); if (!prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ case depth8u: switch (m_eType){ case dilate:ippiMorphologicalCall (poSrc->asImg(),(*ppoDst)->asImg());break; case erode:ippiMorphologicalCall (poSrc->asImg(),(*ppoDst)->asImg());break; case dilate3x3:ippiMorphologicalCall3x3 (poSrc->asImg(),(*ppoDst)->asImg());break; case erode3x3:ippiMorphologicalCall3x3 (poSrc->asImg(),(*ppoDst)->asImg());break; case dilateBorderReplicate:checkMorphState8u(poSrc->getROISize());ippiMorphologicalBorderReplicateCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pState8u);break; case erodeBorderReplicate:checkMorphState8u(poSrc->getROISize());ippiMorphologicalBorderReplicateCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pState8u);break; case openBorder:checkMorphAdvState8u(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState8u);break; case closeBorder:checkMorphAdvState8u(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState8u);break; case tophatBorder:checkMorphAdvState8u(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState8u);break; case blackhatBorder:checkMorphAdvState8u(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState8u);break; case gradientBorder:checkMorphAdvState8u(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState8u);break; } break; case depth32f: switch (m_eType){ case dilate:ippiMorphologicalCall (poSrc->asImg(),(*ppoDst)->asImg());break; case erode:ippiMorphologicalCall (poSrc->asImg(),(*ppoDst)->asImg());break; case dilate3x3:ippiMorphologicalCall3x3 (poSrc->asImg(),(*ppoDst)->asImg());break; case erode3x3:ippiMorphologicalCall3x3 (poSrc->asImg(),(*ppoDst)->asImg());break; case dilateBorderReplicate:checkMorphState32f(poSrc->getROISize());ippiMorphologicalBorderReplicateCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pState32f);break; case erodeBorderReplicate:checkMorphState32f(poSrc->getROISize());ippiMorphologicalBorderReplicateCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pState32f);break; case openBorder:checkMorphAdvState32f(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState32f);break; case closeBorder:checkMorphAdvState32f(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState32f);break; case tophatBorder:checkMorphAdvState32f(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState32f);break; case blackhatBorder:checkMorphAdvState32f(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState32f);break; case gradientBorder:checkMorphAdvState32f(poSrc->getROISize());ippiMorphologicalBorderCall (poSrc->asImg(),(*ppoDst)->asImg(),m_pAdvState32f);break; } break; default: ICL_INVALID_FORMAT; break; } } icl8u* MorphologicalOp::getMask() const{ return m_pcMask; } Size MorphologicalOp::getMaskSize() const{ return m_sMasksize; } void MorphologicalOp::setOptype(optype type){ m_eType=type; } MorphologicalOp::optype MorphologicalOp::getOptype() const{ return m_eType; } template void MorphologicalOp::ippiMorphologicalCall (const Img *src, Img *dst) { for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData (c, this->m_oROIOffset), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), m_pcMask,m_oMaskSize, m_oAnchor ); }; } template void MorphologicalOp::ippiMorphologicalCall3x3 (const Img *src, Img *dst) { for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData (c, this->m_oROIOffset), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize() ); }; } template void MorphologicalOp::ippiMorphologicalBorderReplicateCall (const Img *src, Img *dst,IppiMorphState* state) { for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData (c, this->m_oROIOffset), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), ippBorderRepl, state ); }; } template void MorphologicalOp::ippiMorphologicalBorderCall (const Img *src, Img *dst, IppiMorphAdvState* advState) { for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData (c, this->m_oROIOffset), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), ippBorderRepl, advState ); }; } // }}} #endif }