/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLCV/src/ICLCV/CV.cpp ** ** Module : ICLCV ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #ifdef ICL_HAVE_IPP #include #endif #include //#include namespace icl{ using namespace core; using namespace utils; using namespace math; using namespace filter; using namespace io; namespace cv{ // this function is only used here to ensure that // libICLCV.so links against libICLIO.so void enshure_linkage_against_iclio(){ icl::io::FileList l; } template inline void apply_inplace_threshold(Img8u &image,int dim, icl8u thresh, BinaryCompare cmp){ int threshN = N*thresh; icl8u *pc[N]; for(int j=0;j inline void apply_inplace_threshold_roi(Img8u &image, icl8u thresh, BinaryCompare cmp){ const Rect &r = image.getROI(); int xStart = r.x; int xEnd = r.right(); int yStart = r.y; int yEnd = r.bottom(); int w = image.getWidth(); int threshN = N*thresh; icl8u *pc[N]; for(int j=0;j matchTemplate(const Img8u &src, const Img8u &templ, float significance, Img8u *bufferGiven, bool clipBuffersToROI, RegionDetector *rdGiven, bool useCrossCorrCoeffInsteadOfSqrDistance){ //DEBUG_LOG("src:" << src << "\ntempl:" << templ); Size bufSize = src.getROISize()-templ.getROISize()+Size(1,1); ICLASSERT_RETURN_VAL(bufSize.width > 0 && bufSize.height > 0, std::vector()); Img8u *useBuffer = bufferGiven ? bufferGiven : new Img8u; RegionDetector *useRD = rdGiven ? rdGiven : new RegionDetector; useBuffer->setChannels(src.getChannels()); if(clipBuffersToROI){ useBuffer->setSize(bufSize); }else{ useBuffer->setSize(src.getSize()); Point bufOffs = src.getROIOffset(); bufOffs.x += templ.getROISize().width/2; bufOffs.y += templ.getROISize().height/2; useBuffer->setROI(Rect(bufOffs,bufSize)); } for(int i=0;igetROIData(i), useBuffer->getLineStep(),-8); }else{ ippiSqrDistanceValid_Norm_8u_C1RSfs(src.getROIData(i),src.getLineStep(), src.getROISize(), templ.getROIData(i), templ.getLineStep(),templ.getROISize(), useBuffer->getROIData(i), useBuffer->getLineStep(),-8); } #else ERROR_LOG("not supported without IPP"); #endif } Img8u &m = *useBuffer; // show(cvt(m)); icl8u t = useCrossCorrCoeffInsteadOfSqrDistance ? (icl8u)(float(255)*significance) : 255 - (icl8u)(float(255)*significance); if(m.hasFullROI()){ if(!useCrossCorrCoeffInsteadOfSqrDistance){ switch(m.getChannels()){ case 1: apply_inplace_threshold<1,std::less >(m,m.getDim(),t,std::less()); break; case 2: apply_inplace_threshold<2,std::less >(m,m.getDim(),t,std::less()); break; case 3: apply_inplace_threshold<3,std::less >(m,m.getDim(),t,std::less()); break; default: ERROR_LOG("this function is only supported for 1,2 and 3 channel images (channel count was " << m.getChannels() << ")"); return std::vector(); } }else{ switch(m.getChannels()){ case 1: apply_inplace_threshold<1,std::greater >(m,m.getDim(),t,std::greater()); break; case 2: apply_inplace_threshold<2,std::greater >(m,m.getDim(),t,std::greater()); break; case 3: apply_inplace_threshold<3,std::greater >(m,m.getDim(),t,std::greater()); break; default: ERROR_LOG("this function is only supported for 1,2 and 3 channel images (channel count was " << m.getChannels() << ")"); return std::vector(); } } }else{ if(!useCrossCorrCoeffInsteadOfSqrDistance){ switch(m.getChannels()){ case 1: apply_inplace_threshold_roi<1,std::less >(m,t,std::less()); break; case 2: apply_inplace_threshold_roi<2,std::less >(m,t,std::less()); break; case 3: apply_inplace_threshold_roi<3,std::less >(m,t,std::less()); break; default: ERROR_LOG("this function is only supported for 1,2 and 3 channel images (channel count was " << m.getChannels() << ")"); return std::vector(); } }else{ switch(m.getChannels()){ case 1: apply_inplace_threshold_roi<1,std::greater >(m,t,std::greater()); break; case 2: apply_inplace_threshold_roi<2,std::greater >(m,t,std::greater()); break; case 3: apply_inplace_threshold_roi<3,std::greater >(m,t,std::greater()); break; default: ERROR_LOG("this function is only supported for 1,2 and 3 channel images (channel count was " << m.getChannels() << ")"); return std::vector(); } } } Img8u c0 = p2o(useBuffer->selectChannel(0)); // show(norm(cvt(c0))); useRD->setConstraints(0,2<<20,1,255); const std::vector &blobData = useRD->detect(&c0); std::vector resultVec(blobData.size()); Point halfTemplROI(templ.getROISize().width/2,templ.getROISize().height/2); Point offs = src.getROIOffset()+halfTemplROI+Point(1,1); Rect templRect(halfTemplROI * (-1),templ.getROISize()); templRect += offs; for(unsigned int i=0;i matchTemplate(const Img8u &src, const Img8u *srcMask, const Img8u &templ, const Img8u *templMask, float significance, Img8u *srcBuffer, Img8u *templBuffer, Img8u *buffer, bool clipBuffersToROI, RegionDetector *rd, bool useCrossCorrCoeffInsteadOfSqrDistance){ Img8u *useSrcBuffer = 0; Img8u *useTemplBuffer = 0; if(srcMask){ useSrcBuffer = srcBuffer ? srcBuffer : new Img8u; Img8u srcMaskRepChannel(ImgParams(srcMask->getSize(),0,srcMask->getROI())); for(int i=0;igetChannels();i++){ srcMaskRepChannel.append(const_cast(srcMask)); } BinaryLogicalOp binop(BinaryLogicalOp::andOp); binop.setClipToROI(clipBuffersToROI); binop.apply(&src,&srcMaskRepChannel,bpp(useSrcBuffer)); }else{ useSrcBuffer = const_cast(&src); } if(templMask){ useTemplBuffer = templBuffer ? templBuffer : new Img8u; Img8u templMaskRepChannel(ImgParams(templMask->getSize(),0,templMask->getROI())); for(int i=0;igetChannels();i++){ templMaskRepChannel.append(const_cast(templMask)); } BinaryLogicalOp binop(BinaryLogicalOp::andOp); binop.setClipToROI(clipBuffersToROI); binop.apply(&templ,&templMaskRepChannel,bpp(useTemplBuffer)); }else{ useTemplBuffer = const_cast(&templ); } std::vector results = matchTemplate(*useSrcBuffer, *useTemplBuffer, significance, buffer, clipBuffersToROI, rd, useCrossCorrCoeffInsteadOfSqrDistance); if(clipBuffersToROI && srcMask){ DEBUG_LOG(""); for(unsigned int i=0;i