#include #include namespace icl{ namespace{ template static inline bool eqfunc(const T &a,const T&b){ return a == b; } } RegionDetector::RegionDetector(unsigned int minSize, unsigned int maxSize, icl64f minVal, icl64f maxVal): m_uiMinSize(minSize),m_uiMaxSize(maxSize),m_dMinVal(minVal),m_dMaxVal(maxVal){ } void RegionDetector::setRestrictions(unsigned int minSize, unsigned int maxSize, icl64f minVal, icl64f maxVal){ m_uiMinSize = minSize; m_uiMaxSize = maxSize; m_dMinVal = minVal; m_dMaxVal = maxVal; } void RegionDetector::setRestrictions(const Range &sizeRange, const Range &valueRange){ setRestrictions(sizeRange.minVal,sizeRange.maxVal,valueRange.minVal, valueRange.maxVal); } const std::vector &RegionDetector::detect(const ImgBase *image){ m_vecBlobData.clear(); ICLASSERT_RETURN_VAL(image,m_vecBlobData); ICLASSERT_RETURN_VAL(image->getChannels()==1,m_vecBlobData); ICLASSERT_RETURN_VAL(image->getROISize().getDim(),m_vecBlobData); switch(image->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) case depth##D: detect_intern(*image->asImg(),eqfunc); break; ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } return m_vecBlobData; } void RegionDetector::adaptLIM(int w, int h){ if((int)m_vecLIM.size() < w*h){ m_vecLIM.resize(w*h); } } void RegionDetector::resetPartList(){ std::for_each(m_vecParts.begin(),m_vecParts.end(),RegionPart::del_func); m_vecParts.clear(); } inline RegionPart *RegionDetector::newPart(){ RegionPart *p = new RegionPart; m_vecParts.push_back(p); return p; } namespace{ template class ImgChannelROI{ public: inline ImgChannelROI(const Img &image, int channel): chan(image[channel]),xOffs(image.getROI().x),yOffs(image.getROI().y){ } inline const T &operator()(int x, int y) const{ return chan(x+xOffs,y+yOffs); } private: const Channel chan; int xOffs; int yOffs; }; template struct EQFunctor{ EQFunctor(const T &ref):ref(ref){} T ref; inline bool operator()(const T &val) const{ return ref == val; } }; } template void RegionDetector::detect_intern(const Img &image, Compare cmp){ const int xOffs = image.getROI().x; const int yOffs = image.getROI().y; const int w = image.getROI().width; const int h = image.getROI().height; adaptLIM(w,h); resetPartList(); RegionPart **lim = &m_vecLIM[0]; ImgChannelROI data(image,0); // first pixel: lim[0] = newPart(); // first line register int slX = 0; for(int x=1;xadd(ScanLine(slX+xOffs,yOffs,x-slX)); slX = x; lim[x] = newPart(); } } // first line end lim[w-1]->add(ScanLine(slX+xOffs,yOffs,w-slX)); // rest pixles for(int y=1;yadd(pOld); std::replace_if(&limL[x+1],&limC[x],EQFunctor(pOld),pNew); }else{ limC[x] = limC[x-1]; } }else{ if( eqfunc( dataC[x] , dataL[x] )){ limC[x] = limL[x]; }else{ limC[x] = newPart(); } limC[x-1]->add(ScanLine(slX+xOffs,y+yOffs,x-slX)); slX = x; } } limC[w-1]->add(ScanLine(slX+xOffs,y+yOffs,w-slX)); } for(unsigned int i=0;itop){ const T &val = image(m_vecParts[i]->scanlines[0].x,m_vecParts[i]->scanlines[0].y,0); if(val >= m_dMinVal && val <= m_dMaxVal){ m_vecBlobData.push_back(Region(m_vecParts[i],m_uiMaxSize,val,&image)); Region &b = m_vecBlobData.back(); if((unsigned int)b.getSize() > m_uiMaxSize || (unsigned int)b.getSize() < m_uiMinSize){ m_vecBlobData.pop_back(); } } } } } }