/******************************************************************** ** 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 : ICLGeom/src/ICLGeom/RemainingPointsFeatureExtractor.cpp** ** Module : ICLGeom ** ** Authors: Andre Ueckermann ** ** ** ** ** ** 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 #include namespace icl{ namespace geom{ void RemainingPointsFeatureExtractor::apply(core::DataSegment &xyz, const core::Img32f &depthImage, core::Img32s &labelImage, core::Img8u &maskImage, std::vector > &surfaces, std::vector > &segments, int minSize, float euclideanDistance, int radius, float assignEuclideanDistance, int supportTolerance){ calculateLocalMinima(depthImage, maskImage, radius); apply(xyz, labelImage, maskImage, surfaces, segments, minSize, euclideanDistance, assignEuclideanDistance, supportTolerance); } void RemainingPointsFeatureExtractor::apply(core::DataSegment &xyz, core::Img32s &labelImage, core::Img8u &maskImage, std::vector > &surfaces, std::vector > &segments, int minSize, float euclideanDistance, float assignEuclideanDistance, int supportTolerance){ int numCluster=surfaces.size(); clusterRemainingPoints(xyz, surfaces, labelImage, maskImage, minSize, euclideanDistance, numCluster); std::vector > neighbours; std::vector > neighboursPoints; detectNeighbours(xyz, surfaces, labelImage, neighbours, neighboursPoints, numCluster, assignEuclideanDistance); ruleBasedAssignment(xyz, labelImage, surfaces, segments, neighbours, neighboursPoints, numCluster, supportTolerance); } math::DynMatrix RemainingPointsFeatureExtractor::apply(core::DataSegment &xyz, const core::Img32f &depthImage, core::Img32s &labelImage, core::Img8u &maskImage, std::vector > &surfaces, int minSize, float euclideanDistance, int radius, float assignEuclideanDistance){ calculateLocalMinima(depthImage, maskImage, radius); return apply(xyz, labelImage, maskImage, surfaces, minSize, euclideanDistance, assignEuclideanDistance); } math::DynMatrix RemainingPointsFeatureExtractor::apply(core::DataSegment &xyz, core::Img32s &labelImage, core::Img8u &maskImage, std::vector > &surfaces, int minSize, float euclideanDistance, float assignEuclideanDistance){ int numCluster=surfaces.size(); clusterRemainingPoints(xyz, surfaces, labelImage, maskImage, minSize, euclideanDistance, numCluster); std::vector > neighbours; std::vector > neighboursPoints; detectNeighbours(xyz, surfaces, labelImage, neighbours, neighboursPoints, numCluster, assignEuclideanDistance); //create Matrix math::DynMatrix remainingMatrix(surfaces.size(), surfaces.size(), false); for(unsigned int x=numCluster; x nb = neighbours[x-numCluster]; for(unsigned int y=0; y=ii && x=ii && y=ii && x=ii && y=ii && x=ii && y &xyz, std::vector > &surfaces, core::Img32s &labelImage, core::Img8u &maskImage, int minSize, float euclideanDistance, int numCluster){ //cluster remaining points by euclidean distance cv::RegionGrower rg; const core::Img32s &result = rg.applyFloat4EuclideanDistance(xyz, maskImage, euclideanDistance, minSize, numCluster+1); std::vector > regions=rg.getRegions(); surfaces.insert(surfaces.end(), regions.begin(), regions.end()); //relabel the label image utils::Size s=labelImage.getSize(); core::Channel32s labelImageC = labelImage[0]; core::Channel32s resultC = result[0]; for(int y=0; y &xyz, std::vector > &surfaces, core::Img32s &labelImage, std::vector > &neighbours, std::vector > &neighboursPoints, int numCluster, float assignEuclideanDistance){ utils::Size s = labelImage.getSize(); core::Channel32s labelImageC = labelImage[0]; //determine neighbouring surfaces for(unsigned int x=numCluster; x nb;//neighbours std::vector nbPoints;//number of connecting points for(unsigned int y=0; y=0 && p2labelImageC[p2] && labelImageC[p2]!=0){//bounds, id, value, not 0 if(checkNotExist(labelImageC[p2]-1, nb, nbPoints) && math::dist3(xyz[p1], xyz[p2]) &nb, std::vector &nbPoints){ if(zw!=0){ for(unsigned int z=0; z &xyz, core::Img32s &labelImage, std::vector > &surfaces, std::vector > &segments, std::vector > &neighbours, std::vector > &neighboursPoints, int numCluster, int supportTolerance){ std::vector assignment = segmentMapping(segments, surfaces.size()); for(unsigned int x=numCluster; x nb = neighbours[x-numCluster]; std::vector nbPoints = neighboursPoints[x-numCluster]; if(nb.size()==0){ //no neighbours -> new segment std::vector seg; seg.push_back(x); segments.push_back(seg); assignment[x] = segments.size()-1; } else if(nb.size()==1 && surfaces[x].size()<15){ //very small -> assign segments[assignment[nb[0]]].push_back(x); assignment[x]=assignment[nb[0]]; } else if(nb.size()==1){ bool supported = checkSupport(labelImage, surfaces[x], nb[0], supportTolerance); if(supported){ //new blob //if(nbPoints[0]<9){ //new blob (weak connectivity) std::vector seg; seg.push_back(x); segments.push_back(seg); assignment[x] = segments.size()-1; } else{ //assign segments[assignment[nb[0]]].push_back(x); assignment[x]=assignment[nb[0]]; } } else if(nb.size()>1){ bool same=true; for(unsigned int a=1; aassign for(unsigned int p=0; p determine best match by RANSAC int bestNeighbourID = ransacAssignment(xyz, surfaces, nb, x); //assign to neighbour with smallest error segments[assignment[nb[bestNeighbourID]]].push_back(x); assignment[x]=assignment[nb[bestNeighbourID]]; } } } } std::vector RemainingPointsFeatureExtractor::segmentMapping(std::vector > &segments, int numSurfaces){ //mapping for faster calculation std::vector assignment (numSurfaces,0); for(unsigned int i=0; i &xyz, std::vector > &surfaces, std::vector &nb, int x){ std::vector > n0; std::vector > dist; for(unsigned int i=0; i n00(10); std::vector dist0(10); PlanarRansacEstimator::calculateRandomModels(xyz, surfaces[nb[i]], n00, dist0, 10); n0.push_back(n00); dist.push_back(dist0); } float bestNeighbourScore=10000000; int bestNeighbourID=0; for(unsigned int i=0; i &surface, int neighbourID, int supportTolerance){ int count=0; utils::Size s = labelImage.getSize(); core::Channel32s labelImageC = labelImage[0]; for(unsigned int y=0; y=0 && p2