/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLGeom/src/Segmentation3D.cpp ** ** Module : ICLGeom ** ** Authors: Andre Ueckermann ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** 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. ** ** ** *********************************************************************/ #define __CL_ENABLE_EXCEPTIONS //enables openCL error catching #ifdef HAVE_OPENCL #include #endif #include #include #include namespace icl{ namespace geom{ #ifdef HAVE_OPENCL //OpenCL kernel code static char segmentationKernel[] = " #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable \n" "__kernel void \n" "calculatePointAssignment(__global float4 const * xyz, __global bool * elements, __global int const * assignment, int const radius, int const numFaces, __global bool * neighbours, __global int * assignmentOut, int const w, int const h, float const maxDist) \n" "{ \n" " size_t id = get_global_id(0); \n" " int y = (int)floor((float)id/(float)w); \n" " int x = id-y*w; \n" " float dist=100000; \n" " int ass=0; \n" " bool assigned=false; \n" " if(elements[id]==true && assignment[id]==0){ \n" " bool adj[100]; \n" " for(int a=0; a=0 && x+xx=0 && y+yy=-RANSACeucl && s1<=RANSACeucl)){ \n" " atomic_inc(&countOn[pass]); \n" " }else if(s1>RANSACeucl){ \n" " atomic_inc(&countAbove[pass]); \n" " }else if(s1<-RANSACeucl){ \n" " atomic_inc(&countBelow[pass]); \n" " } \n" "} \n" "__kernel void \n" "assignRANSAC(__global float4 const * xyz, __global bool * elements, __global int * assignment, float4 const n0, float const d, int const euclDist, __global int * oldAssignment, int maxID) \n" "{ \n" " size_t id = get_global_id(0); \n" " if(oldAssignment[id]==maxID) \n" " { \n" " assignment[id]=1; \n" " elements[id]=false; \n" " } \n" " else \n" " { \n" " float4 xyzD=xyz[id]; \n" " float s1 = (xyzD.x*n0.x+xyzD.y*n0.y+xyzD.z*n0.z)-d; \n" " if((s1>=-euclDist && s1<=euclDist) && elements[id]==true) \n" " { \n" " assignment[id]=1; \n" " elements[id]=false; \n" " } \n" " } \n" "} \n" "__kernel void \n" "segmentColoring(__global int const * assignment, __global uchar * colorR, __global uchar * colorG, __global uchar * colorB) \n" "{ \n" " size_t id = get_global_id(0); \n" " if(assignment[id]==0) \n" " { \n" " colorR[id]=128; \n" " colorG[id]=128; \n" " colorB[id]=128; \n" " } \n" " else \n" " { \n" " int H=(int)(assignment[id]*35.)%360; \n" " float S=1.0-assignment[id]*0.01; \n" " float hi=floor((float)H/60.); \n" " float f=((float)H/60.)-hi; \n" " float pp=1.0-S; \n" " float qq=1.0-S*f; \n" " float tt=1.0-S*(1.-f); \n" " float newR=0; \n" " float newG=0; \n" " float newB=0; \n" " if((int)hi==0 || (int)hi==6){ \n" " newR=1.0; \n" " newG=tt; \n" " newB=pp; \n" " }else if((int)hi==1){ \n" " newR=qq; \n" " newG=1.0; \n" " newB=pp; \n" " }else if((int)hi==2){ \n" " newR=pp; \n" " newG=1.0; \n" " newB=tt; \n" " }else if((int)hi==3){ \n" " newR=pp; \n" " newG=qq; \n" " newB=1.0; \n" " }else if((int)hi==4){ \n" " newR=tt; \n" " newG=pp; \n" " newB=1.0; \n" " }else if((int)hi==5){ \n" " newR=1.0; \n" " newG=pp; \n" " newB=qq; \n" " } \n" " colorR[id]=(unsigned char)(newR*255.); \n" " colorG[id]=(unsigned char)(newG*255.); \n" " colorB[id]=(unsigned char)(newB*255.); \n" " } \n" "} \n" ; #endif Segmentation3D::Segmentation3D(Size size){ //set default values clReady=false; useCL=true; w=size.width; h=size.height; dim=w*h; s=size; minClusterSize=25; useFastGrowing=false; assignmentRadius=5; assignmentMaxDistance=15; RANSACeuclDistance=15; RANSACpasses=20; RANSACtolerance=30; RANSACsubset=2; BLOBSeuclDistance=15; useROI=false; xMinROI=0, xMaxROI=0, yMinROI=0; yMaxROI=0; elements=new bool[w*h]; assignment=new int[w*h]; assignmentRemaining=new int[w*h]; elementsBlobs=new bool[w*h]; assignmentBlobs=new int[w*h]; normalEdgeImage.setSize(Size(w,h)); normalEdgeImage.setChannels(1); depthImage.setSize(Size(w,h)); depthImage.setChannels(1); segmentColorImage.setSize(Size(w,h)); segmentColorImage.setChannels(3); region=new RegionDetector(25, 4000000, 254, 255, false); #ifdef HAVE_OPENCL //create openCL context segmentColorImageRArray = new cl_uchar[w*h]; segmentColorImageGArray = new cl_uchar[w*h]; segmentColorImageBArray = new cl_uchar[w*h]; std::vector platformList;//get number of available openCL platforms int selectedDevice=0;//initially select platform 0 try{ if(cl::Platform::get(&platformList)==CL_SUCCESS){ std::cout<<"openCL platform found"< deviceList; if(platformList.at(i).getDevices(CL_DEVICE_TYPE_GPU, &deviceList)==CL_SUCCESS){ std::cout<<"GPU-DEVICE(S) FOUND"<(); std::cout<<"selected devices: "< xyz, const Img8u &edgeImg, const Img32f &depthImg){ xyzData=xyz; normalEdgeImage=edgeImg; depthImage=depthImg; clearData(); regionGrow(); calculatePointAssignmentAndAdjacency(); calculateCutfreeMatrix(); greedyComposition(); calculateRemainingPoints(); colorPointcloud(); return segmentColorImage; } Img8u Segmentation3D::segmentationBlobs(DataSegment xyz, const Img8u &edgeImg, const Img32f &depthImg){ xyzData=xyz; normalEdgeImage=edgeImg; depthImage=depthImg; clearData(); regionGrow(); blobSegmentation(); colorPointcloud(); return segmentColorImage; } void Segmentation3D::setUseCL(bool use){ useCL=use; } void Segmentation3D::setUseROI(bool use){ useROI=use; } void Segmentation3D::setROI(float xMin, float xMax, float yMin, float yMax){ xMinROI=xMin; xMaxROI=xMax; yMinROI=yMin; yMaxROI=yMax; } void Segmentation3D::setMinClusterSize(unsigned int size){ minClusterSize=size; } void Segmentation3D::setUseFastGrowing(bool use){ useFastGrowing=use; } void Segmentation3D::setAssignmentRadius(int radius){ assignmentRadius=radius; } void Segmentation3D::setAssignmentMaxDistance(float maxDistance){ assignmentMaxDistance=maxDistance; } void Segmentation3D::setRANSACeuclDistance(int distance){ RANSACeuclDistance=distance; } void Segmentation3D::setRANSACpasses(int passes){ RANSACpasses=passes; } void Segmentation3D::setRANSACtolerance(int tolerance){ RANSACtolerance=tolerance; } void Segmentation3D::setRANSACsubset(int subset){ RANSACsubset=subset; } void Segmentation3D::setBLOBSeuclDistance(int distance){ BLOBSeuclDistance=distance; } bool Segmentation3D::isCLReady(){ return clReady; } bool Segmentation3D::isCLActive(){ return useCL; } Img8u Segmentation3D::getSegmentColorImage(){ return segmentColorImage; } std::vector > Segmentation3D::getCluster(){ return cluster; } std::vector > Segmentation3D::getBlobs(){ return blobs; } DynMatrix Segmentation3D::getNeigboursMatrix(){ return neighbours; } DynMatrix Segmentation3D::getProbabilityMatrix(){ return probabilities; } void Segmentation3D::setXYZH(DataSegment xyz){ xyzData=xyz; } void Segmentation3D::setEdgeImage(const Img8u &edgeImage){ normalEdgeImage=edgeImage; } void Segmentation3D::setDepthImage(const core::Img32f &depth){ depthImage=depth; } void Segmentation3D::clearData(){ cluster.clear(); blobs.clear(); if(useROI){ for(int y=0;yxMaxROI || xyzData[i][1]yMaxROI){ elements[i]=false; assignment[i]=0; assignmentRemaining[i]=0; elementsBlobs[i]=false; assignmentBlobs[i]=0; }else{ elements[i]=true; assignment[i]=0; assignmentRemaining[i]=0; elementsBlobs[i]=true; assignmentBlobs[i]=0; } } } }else{ for(int y=0;ysetConstraints (minClusterSize, 4000000, 254, 255); std::vector > remove; std::vector regions; regions = region->detect(&normalEdgeImage); for(unsigned int i=0; i ps = regions.at(i).getPixels(); std::vector data; for(unsigned int j=0; j > remove; for(int y=0;y data; data.push_back(i); checkNeighbourGrayThreshold(x,y,assignment[i], 255, &data); if(data.size() newMatrix(numFaces,numFaces,false); neighbours=newMatrix; neighboursBuffer = cl::Buffer( context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, numFaces*numFaces * sizeof(bool), (void *) &neighbours[0]); xyzBuffer = cl::Buffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, w*h * sizeof(cl_float4), (void *) &xyzData[0]); elementsBuffer = cl::Buffer( context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, w*h * sizeof(bool), (void *) &elements[0]); assignmentBuffer = cl::Buffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, w*h * sizeof(int), (void *) &assignment[0]); assignmentOutBuffer = cl::Buffer( context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, w*h * sizeof(int), (void *) &assignment[0]); kernelPointAssignment.setArg(0, xyzBuffer);//set parameter for kernel kernelPointAssignment.setArg(1, elementsBuffer); kernelPointAssignment.setArg(2, assignmentBuffer); kernelPointAssignment.setArg(3, assignmentRadius); kernelPointAssignment.setArg(4, numFaces); kernelPointAssignment.setArg(5, neighboursBuffer); kernelPointAssignment.setArg(6, assignmentOutBuffer); kernelPointAssignment.setArg(7, w); kernelPointAssignment.setArg(8, h); kernelPointAssignment.setArg(9, assignmentMaxDistance); queue.enqueueNDRangeKernel(//run kernel kernelPointAssignment, cl::NullRange, cl::NDRange(w*h), //input size for get global id cl::NullRange); queue.enqueueReadBuffer(//read output from kernel neighboursBuffer, CL_TRUE, // block 0, numFaces*numFaces * sizeof(bool), (bool*) neighbours.data()); queue.enqueueReadBuffer(//read output from kernel assignmentOutBuffer, CL_TRUE, // block 0, w*h * sizeof(int), (int*) assignment); queue.enqueueReadBuffer(//read output from kernel elementsBuffer, CL_TRUE, // block 0, w*h * sizeof(bool), (bool*) elements); for(int i=0; i(int)cluster.size()){ cluster.resize(assignment[x]); } cluster.at(assignment[x]-1).push_back(x); } } }catch (cl::Error err) {//catch openCL errors std::cout<< "ERROR: "<< err.what()<< "("<< err.err()<< ")"< newMatrix(numFaces,numFaces,false); neighbours=newMatrix; int assignmentOut[w*h]; for(int x=0; x=0 && x+xx=0 && y+yy newMatrix(neighbours.rows(),neighbours.cols(),false); cutfree=newMatrix; for(unsigned int a=0; acountNAcc){ cutfree(a,b)=true; }else{ cutfree(a,b)=false; } #endif } else{ for(int p=0; p=-RANSACeuclDistance && s1<=RANSACeuclDistance)){ countOn++; }else if(s1>RANSACeuclDistance){ countAbove++; }else if(s1<-RANSACeuclDistance){ countBelow++; } } if(countAbovecountNAcc){ cutfree(a,b)=true; }else{ cutfree(a,b)=false; } } } } #ifdef HAVE_OPENCL clReleaseMemObject(RANSACpointsMem); #endif } } void Segmentation3D::greedyComposition(){ DynMatrix combinable=DynMatrix(cluster.size(),cluster.size(),false); probabilities=DynMatrix(cluster.size(),cluster.size(),0.0); for(unsigned int a=0; a W = probabilities; std::vector > facesCom; std::vector probsCom; for(unsigned int a=0; a0){ std::vector add; add.push_back(a); add.push_back(b); facesCom.push_back(add); probsCom.push_back(W(a,b)); } } } for(unsigned int a=0; a add; for(unsigned int c=0; c0){ float maxProb=0; int maxProbPos=0; for(unsigned int a=0; amaxProb) || (probsCom.at(a)==maxProb && facesCom.at(a).size()>facesCom.at(maxProbPos).size())){ maxProb=probsCom.at(a); maxProbPos=a; } } std::vector faces; faces=facesCom.at(maxProbPos); blobs.push_back(faces); for(unsigned int a=0; a f; f.push_back(i); blobs.push_back(f); } } int comp[cluster.size()]; for(unsigned int x=0; x0){ assignment[i]=comp[assignment[i]-1]; } } } void Segmentation3D::calculateRemainingPoints(){ int numCluster=cluster.size(); int currentClusterSize=cluster.size(); for(int y=0;y data; data.push_back(i); checkNeighbourDistanceRemaining(x,y,assignmentRemaining[i], &data); cluster.push_back(data); } } } for(unsigned int x=currentClusterSize; x nb; for(unsigned int y=0; y=0){ if(checkNotExist(assignment[cluster.at(x).at(y)-1], nb) && dist3(xyzData[cluster.at(x).at(y)], xyzData[cluster.at(x).at(y)-1])=0){ if(checkNotExist(assignment[cluster.at(x).at(y)-w], nb) && dist3(xyzData[cluster.at(x).at(y)], xyzData[cluster.at(x).at(y)-w])=0){ if(checkNotExist(assignment[cluster.at(x).at(y)-w-1], nb) && dist3(xyzData[cluster.at(x).at(y)], xyzData[cluster.at(x).at(y)-w-1])=0){ if(checkNotExist(assignment[cluster.at(x).at(y)-w+1], nb) && dist3(xyzData[cluster.at(x).at(y)], xyzData[cluster.at(x).at(y)-w+1]) new blob std::vector blob; blob.push_back(x); blobs.push_back(blob); for(unsigned int i=0; i assign blobs.at(nb.at(0)-1).push_back(x); for(unsigned int p=0; pw*h-w-1){ } else{ if(assignment[cluster.at(x).at(a)-1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)-1]!=(int)x+1 && depthImage(xx-1,yy,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)+1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)+1]!=(int)x+1 && depthImage(xx+1,yy,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)-w]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)-w]!=(int)x+1 && depthImage(xx,yy-1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)+w]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)+w]!=(int)x+1 && depthImage(xx,yy+1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)-w-1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)-w-1]!=(int)x+1 && depthImage(xx-1,yy-1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)-w+1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)-w+1]!=(int)x+1 && depthImage(xx+1,yy-1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)+w-1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)+w-1]!=(int)x+1 && depthImage(xx-1,yy+1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } if(assignment[cluster.at(x).at(a)+w+1]!=nb.at(0) && assignmentRemaining[cluster.at(x).at(a)+w+1]!=(int)x+1 && depthImage(xx+1,yy+1,0)!=2047){ if(tol<9){ tol++; }else{ assignElement=true; break; } } } } if(assignElement==false){ //new blob std::vector blob; blob.push_back(x); blobs.push_back(blob); for(unsigned int i=0; i1){ int zuws[nb.size()]; for(unsigned int a=0; aassign blobs.at(nb.at(0)-1).push_back(x); for(unsigned int p=0; p determine best match //ToDo: find better solution /*float zuwsSize[nb.size()]; for(unsigned int a=0; amaxSize){ maxID=i; maxSize=cluster.at(i).size(); } } #ifdef HAVE_OPENCL int numPoints=cluster.at(maxID).size(); int cAbove[RANSACpasses]; int cBelow[RANSACpasses]; int cOn[RANSACpasses]; int cAboveRead[RANSACpasses]; int cBelowRead[RANSACpasses]; #endif Vec n0[RANSACpasses]; float dist[RANSACpasses]; int cOnRead[RANSACpasses]; for(int i=0; i=-RANSACeuclDistance/2 && s1<=RANSACeuclDistance/2)){ cOnRead[p]++; } } } } int maxMatch=0; int maxMatchID=0; for(int i=0;imaxMatch){ maxMatch=cOnRead[i]; maxMatchID=i; } } if(useCL==true && clReady==true){ #ifdef HAVE_OPENCL try{ elementsBlobsBuffer = cl::Buffer( context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, w*h * sizeof(bool), (void *) &elementsBlobs[0]); assignmentBlobsBuffer = cl::Buffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, w*h * sizeof(int), (void *) &assignmentBlobs[0]); assignmentBuffer = cl::Buffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, w*h * sizeof(int), (void *) &assignment[0]); kernelAssignRANSAC.setArg(0, xyzBuffer);//set parameter for kernel kernelAssignRANSAC.setArg(1, elementsBlobsBuffer); kernelAssignRANSAC.setArg(2, assignmentBlobsBuffer); kernelAssignRANSAC.setArg(3, n0[maxMatchID]); kernelAssignRANSAC.setArg(4, dist[maxMatchID]); kernelAssignRANSAC.setArg(5, RANSACeuclDistance); kernelAssignRANSAC.setArg(6, assignmentBuffer); kernelAssignRANSAC.setArg(7, maxID+1); queue.enqueueNDRangeKernel(//run kernel kernelAssignRANSAC, cl::NullRange, cl::NDRange(w*h), //input size for get global id cl::NullRange); queue.enqueueReadBuffer(//read output from kernel assignmentBlobsBuffer, CL_TRUE, // block 0, w*h * sizeof(int), (int*) assignmentBlobs); queue.enqueueReadBuffer(//read output from kernel elementsBlobsBuffer, CL_TRUE, // block 0, w*h * sizeof(bool), (bool*) elementsBlobs); }catch (cl::Error err) {//catch openCL errors std::cout<< "ERROR: "<< err.what()<< "("<< err.err()<< ")"<=-RANSACeuclDistance && s1<=RANSACeuclDistance) && elementsBlobs[i]==true){ assignmentBlobs[i]=1; elementsBlobs[i]=false; } } } } regionGrowBlobs(); assignment=assignmentBlobs; } void Segmentation3D::colorPointcloud(){ if(useCL==true && clReady==true){ #ifdef HAVE_OPENCL try{ assignmentBuffer = cl::Buffer( context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, w*h * sizeof(int), (void *) &assignment[0]); kernelSegmentColoring.setArg(0, assignmentBuffer);//set parameter for kernel kernelSegmentColoring.setArg(1, segmentColorImageRBuffer); kernelSegmentColoring.setArg(2, segmentColorImageGBuffer); kernelSegmentColoring.setArg(3, segmentColorImageBBuffer); queue.enqueueNDRangeKernel(//run kernel kernelSegmentColoring, cl::NullRange, cl::NDRange(w*h), //input size for get global id cl::NullRange); queue.enqueueReadBuffer(//read output from kernel segmentColorImageRBuffer, CL_TRUE, // block 0, w*h * sizeof(cl_uchar), (cl_uchar*) segmentColorImageRArray); queue.enqueueReadBuffer(//read output from kernel segmentColorImageGBuffer, CL_TRUE, // block 0, w*h * sizeof(cl_uchar), (cl_uchar*) segmentColorImageGArray); queue.enqueueReadBuffer(//read output from kernel segmentColorImageBBuffer, CL_TRUE, // block 0, w*h * sizeof(cl_uchar), (cl_uchar*) segmentColorImageBArray); std::vector data(3); data[0] = segmentColorImageRArray; data[1] = segmentColorImageGArray; data[2] = segmentColorImageBArray; segmentColorImage = Img8u(Size(w,h),3,data,false); }catch (cl::Error err) {//catch openCL errors std::cout<< "ERROR: "<< err.what()<< "("<< err.err()<< ")"< *data){ std::vector toProcessX; std::vector toProcessY; bool process=true; unsigned int index=0; toProcessX.push_back(x); toProcessY.push_back(y); while(process==true){ int i = toProcessX.at(index)+w*toProcessY.at(index); x = toProcessX.at(index); y = toProcessY.at(index); if(elements[i+1]==true && x+1push_back(i+1); } if(elements[i-1]==true && x-1>=0 && normalEdgeImage(x-1,y,0)==threshold){ elements[i-1]=false; assignment[i-1]=zuw; toProcessX.push_back(toProcessX.at(index)-1); toProcessY.push_back(toProcessY.at(index)); data->push_back(i-1); } if(elements[i+w]==true && y+1push_back(i+w); } if(elements[i+w-1]==true && x-1>=0 && y+1push_back(i+w-1); } if(elements[i+w+1]==true && x+1push_back(i+w+1); } if(elements[i-w]==true && y-1>=0 && normalEdgeImage(x,y-1,0)==threshold){ elements[i-w]=false; assignment[i-w]=zuw; toProcessX.push_back(toProcessX.at(index)); toProcessY.push_back(toProcessY.at(index)-1); data->push_back(i-w); } if(elements[i-w-1]==true && x-1>=0 && y-1>=0 && normalEdgeImage(x-1,y-1,0)==threshold){ elements[i-w-1]=false; assignment[i-w-1]=zuw; toProcessX.push_back(toProcessX.at(index)-1); toProcessY.push_back(toProcessY.at(index)-1); data->push_back(i-w-1); } if(elements[i-w+1]==true && x+1=0 && normalEdgeImage(x+1,y-1,0)==threshold){ elements[i-w+1]=false; assignment[i-w+1]=zuw; toProcessX.push_back(toProcessX.at(index)+1); toProcessY.push_back(toProcessY.at(index)-1); data->push_back(i-w+1); } index++; if(index>=toProcessX.size()){ process=false; } } } void Segmentation3D::checkNeighbourDistanceRemaining(int x, int y, int zuw, std::vector *data){ std::vector toProcessX; std::vector toProcessY; bool process=true; unsigned int index=0; toProcessX.push_back(x); toProcessY.push_back(y); while(process==true){ int i = toProcessX.at(index)+w*toProcessY.at(index); x = toProcessX.at(index); y = toProcessY.at(index); if(elements[i+1]==true && x+1push_back(i+1); } if(elements[i-1]==true && x-1>=0 && dist3(xyzData[i],xyzData[i-1])push_back(i-1); } if(elements[i+w]==true && y+1push_back(i+w); } if(elements[i+w-1]==true && x-1>=0 && y+1push_back(i+w-1); } if(elements[i+w+1]==true && x+1push_back(i+w+1); } if(elements[i-w]==true && y-1>=0 && dist3(xyzData[i],xyzData[i-w])push_back(i-w); } if(elements[i-w-1]==true && x-1>=0 && y-1>=0 && dist3(xyzData[i],xyzData[i-w-1])push_back(i-w-1); } if(elements[i-w+1]==true && x+1=0 && dist3(xyzData[i],xyzData[i-w+1])push_back(i-w+1); } index++; if(index>=toProcessX.size()){ process=false; } } } void Segmentation3D::regionGrowBlobs(){ int numCluster=1; std::vector > remove; for(int y=0;y data; data.push_back(i); checkNeighbourDistance(x,y,assignmentBlobs[i], &data); if(data.size() *data){ std::vector toProcessX; std::vector toProcessY; bool process=true; unsigned int index=0; toProcessX.push_back(x); toProcessY.push_back(y); while(process==true){ int i = toProcessX.at(index)+w*toProcessY.at(index); x = toProcessX.at(index); y = toProcessY.at(index); if(elementsBlobs[i+1]==true && x+1push_back(i+1); } if(elementsBlobs[i-1]==true && x-1>=0 && fabs(depthImage(x,y,0)-depthImage(x-1,y,0))push_back(i-1); } if(elementsBlobs[i+w]==true && y+1push_back(i+w); } if(elementsBlobs[i+w-1]==true && x-1>=0 && y+1push_back(i+w-1); } if(elementsBlobs[i+w+1]==true && x+1push_back(i+w+1); } if(elementsBlobs[i-w]==true && y-1>=0 && fabs(depthImage(x,y,0)-depthImage(x,y-1,0))push_back(i-w); } if(elementsBlobs[i-w-1]==true && x-1>=0 && y-1>=0 && fabs(depthImage(x,y,0)-depthImage(x-1,y-1,0))push_back(i-w-1); } if(elementsBlobs[i-w+1]==true && x+1=0 && fabs(depthImage(x,y,0)-depthImage(x+1,y-1,0))push_back(i-w+1); } index++; if(index>=toProcessX.size()){ process=false; } } } bool Segmentation3D::checkNotExist(int zw, std::vector &nb){ if(zw!=0){ for(unsigned int z=0; z