/******************************************************************** ** 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/CurvatureFeatureExtractor.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 namespace icl{ namespace geom{ math::DynMatrix CurvatureFeatureExtractor::apply(const core::Img32f &depthImg, core::DataSegment &xyz, math::DynMatrix &initialMatrix, std::vector features, std::vector > &surfaces, core::DataSegment &normals, bool useOpenObjects, bool useOccludedObjects, float histogramSimilarity, int distance, float maxError, int ransacPasses, float distanceTolerance, float outlierTolerance){ int w = depthImg.getSize().width; math::DynMatrix curvature = math::DynMatrix(initialMatrix.rows(),initialMatrix.rows(), true);//result matrix //initialize for(size_t i=0; i &normals, SurfaceFeatureExtractor::SurfaceFeature feature1, SurfaceFeatureExtractor::SurfaceFeature feature2, std::vector &surface1, std::vector &surface2, int distance, int w){ //1. neighbouring in image space std::pair bBox1 = feature1.boundingBox2D; //min, max std::pair bBox2 = feature2.boundingBox2D; bool proceed=false; if(bBox1.second.x>bBox2.first.x && bBox2.second.x>bBox1.first.x){ //overlap in x proceed=true; } if(proceed){//maximum distance in y proceed=false; if(bBox1.first.y-bBox2.second.y=0 convex (front), <0 concave (back) if((direction1>=0 && direction2<0 && bBox2.second.y>bBox1.second.y) || (direction1<0 && direction2>=0 && bBox1.second.y>bBox2.second.y)){ return true; } } return false; } bool CurvatureFeatureExtractor::computeOccludedObject(const core::Img32f &depthImg, core::DataSegment &xyz, core::DataSegment &normals, SurfaceFeatureExtractor::SurfaceFeature feature1, SurfaceFeatureExtractor::SurfaceFeature feature2, std::vector &surface1, std::vector &surface2, int w, float maxError, int ransacPasses, float distanceTolerance, float outlierTolerance){ //select most populated bin (same bin for both histograms) float maxBinValue=0; utils::Point maxBin(0,0); for(int y=0; ymaxBinValue){ maxBinValue=binValue; maxBin.x=x; maxBin.y=y; } } } //backproject the points std::vector pointIDs1 = backprojectPointIDs(normals, maxBin, surface1); std::vector pointIDs2 = backprojectPointIDs(normals, maxBin, surface2); std::vector points1 = createPointsFromIDs(xyz, pointIDs1); std::vector points2 = createPointsFromIDs(xyz, pointIDs2); //fit line with RANSAC (faster than linear regression) float minError = 100000; std::pair pointPairImg; for(int i=0; i currentPointPair; std::pair currentPointPairID; currentPointPairID.first = pointIDs1[rand()%pointIDs1.size()]; currentPointPairID.second = pointIDs2[rand()%pointIDs2.size()]; currentPointPair.first = xyz[currentPointPairID.first]; currentPointPair.second = xyz[currentPointPairID.second]; for(unsigned int i=0; i &normals, SurfaceFeatureExtractor::SurfaceFeature feature, std::vector &surface, int w){ //select extremal bins in histogram std::pair histoExtremalBins = computeExtremalBins(feature); //backproject to image space and calculate mean std::pair imgBackproject = backproject(normals, histoExtremalBins, surface, w); //scalar product to determine concave and convex float direction = computeConvexity(histoExtremalBins, imgBackproject); return direction; } std::pair CurvatureFeatureExtractor::computeExtremalBins(SurfaceFeatureExtractor::SurfaceFeature feature){ //normal histogram bounding box std::pair histoBBox; histoBBox.first.x=1000; histoBBox.first.y=1000; histoBBox.second.x=-1000; histoBBox.second.y=-1000; for(int y=0; y=0.005){ if(xhistoBBox.second.x) histoBBox.second.x=x; if(y>histoBBox.second.y) histoBBox.second.y=y; } } } //normal histogram extremal bins std::pair histoExtremalBins; //min, max if(histoBBox.second.x-histoBBox.first.x>=histoBBox.second.y-histoBBox.first.y){//sample x int x1 = histoBBox.first.x; histoExtremalBins.first.x=x1; int x2 = histoBBox.second.x; histoExtremalBins.second.x=x2; for(int y=0; y=0.005){ histoExtremalBins.first.y=y; } if(feature.normalHistogramChannel(x2,y)>=0.005){ histoExtremalBins.second.y=y; } } }else{//sampleY int y1 = histoBBox.first.y; histoExtremalBins.first.y=y1; int y2 = histoBBox.second.y; histoExtremalBins.second.y=y2; for(int x=0; x=0.005){ histoExtremalBins.first.x=x; } if(feature.normalHistogramChannel(x,y2)>=0.005){ histoExtremalBins.second.x=x; } } } return histoExtremalBins; } std::pair CurvatureFeatureExtractor::backproject(core::DataSegment &normals, std::pair &histoExtremalBins, std::vector &surface, int w){ std::vector imgMinPoints=backprojectPointIDs(normals, histoExtremalBins.first, surface); std::vector imgMaxPoints=backprojectPointIDs(normals, histoExtremalBins.second, surface); std::pair imgMeans; imgMeans.first = computeMean(imgMinPoints, w); imgMeans.second = computeMean(imgMaxPoints, w); return imgMeans; } std::vector CurvatureFeatureExtractor::backprojectPointIDs(core::DataSegment &normals, utils::Point bin, std::vector &surface){ std::vector pointIDs; for(unsigned int i=0; i &imgIDs, int w){ std::vector points = createPointsFromIDs(imgIDs, w); utils::Point imgMean(0,0); for(unsigned int i=0; i CurvatureFeatureExtractor::createPointsFromIDs(std::vector &imgIDs, int w){ std::vector points(imgIDs.size()); for(unsigned int i=0; i CurvatureFeatureExtractor::createPointsFromIDs(core::DataSegment &xyz, std::vector &imgIDs){ std::vector points(imgIDs.size()); for(unsigned int i=0; i histoExtremalBins, std::pair imgBackproject){ utils::Point histoVec; utils::Point imgVec; histoVec.x=histoExtremalBins.second.x-histoExtremalBins.first.x; histoVec.y=histoExtremalBins.second.y-histoExtremalBins.first.y; float lengthHisto = sqrt(histoVec.x*histoVec.x+histoVec.y*histoVec.y);//normalize imgVec.x=imgBackproject.second.x-imgBackproject.first.x; imgVec.y=imgBackproject.second.y-imgBackproject.first.y; float lengthImg = sqrt(imgVec.x*imgVec.x+imgVec.y*imgVec.y); float direction = (histoVec.x/lengthHisto)*(imgVec.x/lengthImg)+(histoVec.y/lengthHisto)*(imgVec.y/lengthImg); return direction; } float CurvatureFeatureExtractor::linePointDistance(std::pair line, Vec point){ float d = norm3(cross(point-line.first,point-line.second))/norm3(line.second-line.first); return d; } utils::Point CurvatureFeatureExtractor::idToPoint(int id, int w){ int y = (int)floor((float)id/(float)w); int x = id-y*w; return utils::Point(x,y); } } // namespace geom }