Esempio n. 1
0
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;
	}
Esempio n. 2
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;
	}