#include #include #include #include namespace icl { namespace{ template void apply_median (const Img *src, Img *dst, const Size &oMaskSize,const Point &roiOffset, const Point &oAnchor) { // {{{ open std::vector oList(oMaskSize.getDim()); typename std::vector::iterator itList = oList.begin(); typename std::vector::iterator itMedian = oList.begin()+((oMaskSize.width * oMaskSize.height)/2); for (int c=0;cgetChannels();c++){ ConstImgIterator s(src->getData(c),src->getWidth(), Rect(roiOffset, dst->getROISize())); ImgIterator d= dst->getROIIterator(c); for(;s.inRegion();++s,++d){ for(ConstImgIterator sR(s,oMaskSize,oAnchor); sR.inRegion(); ++sR, ++itList){ *itList = *sR; } std::sort(oList.begin(),oList.end()); *d = *itMedian; itList = oList.begin(); } } } // }}} #ifdef WITH_IPP_OPTIMIZATION template void ippMedian(const Img* src, Img *dst, const Size& maskSize,const Point &roiOffset, const Point &oAnchor) { // {{{ open for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData (c,roiOffset), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), maskSize, oAnchor); } } // }}} template void ippMedianFixed(const Img*src, Img *dst,const Point &roiOffset, int maskSize) { // {{{ open for(int c=0; c < src->getChannels(); c++) { ippiFunc(src->getROIData(c,roiOffset), src->getLineStep(), dst->getROIData(c), dst->getLineStep(), dst->getROISize(), maskSize == 3 ? ippMskSize3x3 : ippMskSize5x5); } } // }}} template<> void apply_median(const Img8u *src, Img8u *dst, const Size &maskSize,const Point &roiOffset, const Point &anchor){ // {{{ open if(maskSize == Size(3,3)){ ippMedianFixed(src,dst,roiOffset,3); }else if(maskSize == Size(5,5)){ ippMedianFixed(src,dst,roiOffset,5); }else{ ippMedian(src,dst,maskSize,roiOffset,anchor); } } // }}} template<> void apply_median(const Img16s *src, Img16s *dst, const Size &maskSize,const Point &roiOffset, const Point &anchor){ // {{{ open if(maskSize == Size(3,3)){ ippMedianFixed(src,dst,roiOffset,3); }else if(maskSize == Size(5,5)){ ippMedianFixed(src,dst,roiOffset,5); }else{ ippMedian(src,dst,maskSize,roiOffset,anchor); } } // }}} #endif } // end of anonymous namespace void MedianOp::apply(const ImgBase *poSrc, ImgBase **ppoDst){ // {{{ open FUNCTION_LOG(""); if (!prepare (ppoDst, poSrc)) return; switch(poSrc->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D: \ apply_median(poSrc->asImg(), \ (*ppoDst)->asImg(), \ getMaskSize(), \ getROIOffset(), \ getAnchor()); \ break; ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } } // }}} }