int main(int argc,char* argv[]) { /* Set up the volumetric grid: */ Box gridBox=Box(Point(-32.0,-64.0,16.0),Point(32.0,0.0,80.0)); Index gridSize(256,256,256); Grid grid(gridSize); /* Initialize the grid: */ for(Grid::iterator gIt=grid.begin();gIt!=grid.end();++gIt) *gIt=Voxel(255); /* Carve away the n-th facade from each depth stream file listed on the command line: */ unsigned int facadeIndex=atoi(argv[1]); for(int depthFileIndex=2;depthFileIndex<argc;++depthFileIndex) { try { /* Open the depth file: */ IO::AutoFile depthFile(IO::openFile(argv[depthFileIndex])); depthFile->setEndianness(IO::File::LittleEndian); /* Read the facade projection matrix and the projector transformation: */ Projection depthTransform; depthFile->read<double>(depthTransform.getMatrix().getEntries(),4*4); OGTransform projectorTransform=Misc::Marshaller<OGTransform>::read(*depthFile); /* Calculate the joint projective transformation from 3D world space into depth image space: */ Projection proj=Geometry::invert(Projection(projectorTransform)*depthTransform); /* Create a depth frame reader: */ DepthFrameReader depthFrameReader(*depthFile); /* Read the n-th facade: */ FrameBuffer frame; for(unsigned int i=0;i<facadeIndex;++i) frame=depthFrameReader.readNextFrame(); /* Run a sequence of morphological open and close operators on the frame to fill holes: */ #if 1 for(int i=0;i<8;++i) frame=open(frame); #endif #if 1 for(int i=0;i<8;++i) frame=close(frame); #endif /* Carve the facade out of the grid: */ std::cout<<"Processing depth file "<<argv[depthFileIndex]<<std::flush; double fmax[2]; for(int i=0;i<2;++i) fmax[i]=double(frame.getSize(i)); unsigned short* frameBuffer=static_cast<unsigned short*>(frame.getBuffer()); Size cellSize; for(int i=0;i<3;++i) cellSize[i]=(gridBox.max[i]-gridBox.min[i])/double(gridSize[i]); Index index; Point gridp; gridp[0]=gridBox.min[0]+0.5*cellSize[0]; for(index[0]=0;index[0]<gridSize[0];++index[0],gridp[0]+=cellSize[0]) { gridp[1]=gridBox.min[1]+0.5*cellSize[1]; for(index[1]=0;index[1]<gridSize[1];++index[1],gridp[1]+=cellSize[1]) { gridp[2]=gridBox.min[2]+0.5*cellSize[2]; for(index[2]=0;index[2]<gridSize[2];++index[2],gridp[2]+=cellSize[2]) { /* Project the grid point into the depth frame: */ Point fp=proj.transform(gridp); /* Check if the projected grid point is inside the depth frame: */ if(fp[0]>=0.0&&fp[0]<fmax[0]&&fp[1]>=0.0&&fp[1]<fmax[1]) { /* Check if the grid point is outside the facade: */ int x=int(fp[0]); int y=int(fp[1]); unsigned short depth=frameBuffer[y*frame.getSize(0)+x]; if(fp[2]<double(depth)) grid(index)=Voxel(0); } else grid(index)=Voxel(0); } } std::cout<<'.'<<std::flush; } std::cout<<"done"<<std::endl; } catch(std::runtime_error err) { std::cerr<<"Ignoring depth file "<<argv[depthFileIndex]<<" due to exception "<<err.what()<<std::endl; } catch(...) { std::cerr<<"Ignoring depth file "<<argv[depthFileIndex]<<" due to spurious exception"<<std::endl; } } /* Save the result grid to a volume file: */ IO::AutoFile volFile(IO::openFile("SpaceCarverOut.vol",IO::File::WriteOnly)); volFile->setEndianness(IO::File::BigEndian); for(int i=0;i<3;++i) volFile->write<int>(int(gridSize[i])); volFile->write<int>(0); for(int i=0;i<3;++i) volFile->write<float>((gridBox.max[i]-gridBox.min[i])*double(gridSize[i]-1)/double(gridSize[i])); volFile->write<Voxel>(grid.getArray(),grid.getNumElements()); return 0; }
int main(int argc,char* argv[]) { /* Open the uncompressed depth stream file: */ IO::FilePtr depthFrameFile(IO::openFile("/work/okreylos/3DVideo/Kinect/DepthFrames.dat")); depthFrameFile->setEndianness(Misc::LittleEndian); /* Read the file header: */ unsigned int size[2]; depthFrameFile->read(size,2); /* Create a background frame: */ unsigned short* backgroundFrame=new unsigned short[size[1]*size[0]]; unsigned short* bfPtr=backgroundFrame; for(unsigned int y=0;y<size[1];++y) for(unsigned int x=0;x<size[0];++x,++bfPtr) *bfPtr=0x07ffU; unsigned int numCaptureFrames=150; /* Create the depth frame writer and reader: */ IO::FilePtr compressedDepthFrameFile(IO::openFile("/work/okreylos/3DVideo/Kinect/CompressedDepthFrames.dat",IO::File::ReadWrite)); Kinect::DepthFrameWriter depthFrameWriter(*compressedDepthFrameFile,size); compressedDepthFrameFile->flush(); Kinect::DepthFrameReader depthFrameReader(*compressedDepthFrameFile); /* Process all frames from the two depth frame files: */ double totalTime=0.0; double maxTime=0.0; unsigned int numFrames=0; while(!depthFrameFile->eof()) { /* Read the next uncompressed depth frame: */ Kinect::FrameBuffer frame0(size[0],size[1],size[1]*size[0]*sizeof(unsigned short)); frame0.timeStamp=depthFrameFile->read<double>(); unsigned short* frameBuffer0=frame0.getData<unsigned short>(); depthFrameFile->read(frameBuffer0,size[1]*size[0]); if(numCaptureFrames>0) { /* Add the depth frame to the background frame: */ unsigned short* bfPtr=backgroundFrame; const unsigned short* dfPtr=frameBuffer0; for(unsigned int y=0;y<size[1];++y) for(unsigned int x=0;x<size[0];++x,++bfPtr,++dfPtr) if(*bfPtr>*dfPtr-2) *bfPtr=*dfPtr-2; --numCaptureFrames; } else { /* Remove background from the depth frame: */ const unsigned short* bfPtr=backgroundFrame; unsigned short* dfPtr=frameBuffer0; for(unsigned int y=0;y<size[1];++y) for(unsigned int x=0;x<size[0];++x,++bfPtr,++dfPtr) if(*dfPtr>=*bfPtr) *dfPtr=0x07ffU; } /* Write the compressed depth frame: */ depthFrameWriter.writeFrame(frame0); compressedDepthFrameFile->flush(); /* Read the next compressed depth frame: */ Misc::Timer uncompressTime; Kinect::FrameBuffer frame1=depthFrameReader.readNextFrame(); uncompressTime.elapse(); double time=uncompressTime.getTime(); totalTime+=time; if(maxTime<time) maxTime=time; ++numFrames; /* Compare the two frames: */ unsigned int numPixels=size[0]*size[1]; const unsigned short* f0Ptr=frameBuffer0; const unsigned short* f1Ptr=frame1.getData<unsigned short>(); while(numPixels>0) { if(*f0Ptr!=*f1Ptr) std::cerr<<"Difference in frame "<<numFrames-1<<", "<<numPixels<<" pixels left"<<std::endl; ++f0Ptr; ++f1Ptr; --numPixels; } } std::cout<<"Total decompression time: "<<totalTime*1000.0<<" ms, "<<numFrames<<" frames"<<std::endl; std::cout<<"Maximum decompression time: "<<maxTime*1000.0<<" ms"<<std::endl; std::cout<<"Decompression frame rate: "<<double(numFrames)/totalTime<<" Hz"<<std::endl; return 0; }