⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 siftgpu.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////
//	File:		SiftGPU.cpp
//	Author:		Changchang Wu
//	Description :	Implementation of the SIFTGPU classes.
//					SiftGPU:	The SiftGPU Tool.  
//					SiftGPUEX:	SiftGPU + viewer
//					SiftParam:	Sift Parameters
//
//	Copyright (c) 2007 University of North Carolina at Chapel Hill
//	All Rights Reserved
//
//	Permission to use, copy, modify and distribute this software and its
//	documentation for educational, research and non-profit purposes, without
//	fee, and without a written agreement is hereby granted, provided that the
//	above copyright notice and the following paragraph appear in all copies.
//	
//	The University of North Carolina at Chapel Hill make no representations
//	about the suitability of this software for any purpose. It is provided
//	'as is' without express or implied warranty. 
//
//	Please send BUG REPORTS to ccwu@cs.unc.edu
//
////////////////////////////////////////////////////////////////////////////


#include "GL/glew.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;


#include "GlobalUtil.h"
#include "SiftGPU.h"
#include "IL/il.h"
#include "GLTexImage.h"
#include "ShaderMan.h"
#include "FrameBufferObject.h"
#include "SiftPyramid.h"
#include "PyramidGL.h"

//CUDA works only with vc8 or higher
#if (!defined(_MSC_VER) ||_MSC_VER >= 1400) && defined(CUDA_SIFTGPU_ENABLED)
#include "PyramidCU.h"
#endif


////
#if  defined(_WIN32) 
	#include "direct.h"
	#pragma comment(lib, "../lib/DevIL.lib")
	#pragma warning (disable : 4786) 
	#pragma warning (disable : 4996) 
#else
	//compatible with linux
	#define _stricmp strcasecmp
#endif

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//just want to make this class invisible
class ImageList:public std::vector<std::string> {};

SiftGPU::SiftGPU(int np)
{ 
	_texImage = new GLTexInput;
	_imgpath[0] = 0;
	_outpath[0] = 0;
	_initialized = 0;
	_image_loaded = 0;
	 GlobalUtil::_UseSiftGPUEX = 0;
	_current = 0;
	_list = new ImageList();
	
	_nPyramid = np < 1? 1 : np;
	_pyramids = NULL;
	_pyramid = NULL;
}



SiftGPUEX::SiftGPUEX() 
{
	_view = _sub_view = 0;
	_view_debug = 0;
	GlobalUtil::_UseSiftGPUEX = 1;
	srand((unsigned int)time(NULL));
	RandomizeColor();
}

void* SiftGPU::operator new (size_t  size){
  void * p = malloc(size);
  if (p == 0)  
  {
	  const std::bad_alloc ba;
	  throw ba; 
  }
  return p; 
}

void SiftGPU::SetActivePyramid(int index)
{
	if(index >=0 && index < _nPyramid)	
	{
		_pyramid = _pyramids[index];
	}
}

void SiftGPUEX::RandomizeColor()
{
	//
	float hsv[3] = {0, 0.8f, 1.0f};
	for(int i = 0; i < COLOR_NUM*3; i+=3)
	{
		hsv[0] = (rand()%100)*0.01f; //i/float(COLOR_NUM);
		HSVtoRGB(hsv, _colors+i);		
	}
}

SiftGPU::~SiftGPU()
{
	if(_pyramids)
	{
		for(int i = 0; i < _nPyramid; i++)
		{
			delete _pyramids[i];
		}
		delete _pyramids;
	}
	delete _texImage;
	delete _list;

	if(_initialized)
	{
		//destroy all the shaders?
		ShaderMan::DestroyShaders(_sigma_num);
		//shutdown iamge loader
		ilShutDown();
	} 

	//Calling glutDestroyWindow function will somehow give a heap corruption 
	//if(_glut_id >0) glutDestroyWindow(_glut_id);
}


inline void SiftGPU::InitSiftGPU()
{
	if(_initialized || GlobalUtil::_GoodOpenGL ==0) return;

#if (defined(_MSC_VER) && _MSC_VER < 1400) || !defined(CUDA_SIFTGPU_ENABLED)
	if(GlobalUtil::_UseCUDA)
	{
		GlobalUtil::_UseCUDA = 0;
		std::cerr	<< "---------------------------------------------------------------------------\n"
					<< "CUDA is not supported in this binary! To enable CUDA implementation, please\n" 
					<< "use SiftGPU_CUDA_Enable Project for VS2005 or define CUDA_SIFTGPU_ENABLED\n"
					<< "----------------------------------------------------------------------------\n";
		GlobalUtil::_usePackedTex = 1;

	}
#endif


	_pyramids = new SiftPyramid*[_nPyramid];
	for(int i = 0; i < _nPyramid; i++)
	{
#if (!defined(_MSC_VER) || _MSC_VER >= 1400) && defined(CUDA_SIFTGPU_ENABLED)
		if(GlobalUtil::_UseCUDA)
			_pyramids[i] = new PyramidCU(*this);
		else 
#endif
		if(GlobalUtil::_usePackedTex) 
			_pyramids[i] = new PyramidPacked(*this);
		else
			_pyramids[i] = new PyramidNaive(*this);
	}
	_pyramid =  _pyramids[0];

	ilInit();
	ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
	ilEnable(IL_ORIGIN_SET);
	///

	//init opengl parameters
	GlobalUtil::InitGLParam();

	//sift parameters
	ParseSiftParam();

	if(GlobalUtil::_GoodOpenGL)
	{
		if(GlobalUtil::_verbose)	std::cout<<"\n[GPU Language]:\t"<<
		(GlobalUtil::_UseCUDA? "CUDA" : (GlobalUtil::_UseGLSL?"GLSL" : "CG")) <<"\n\n";

		//load shaders..
		if(!GlobalUtil::_UseCUDA)
		{
			GlobalUtil::StartTimer("Load OpenGL Shaders");
			ShaderMan::InitShaderMan();
			ShaderMan::LoadDogShaders(_dog_threshold, _edge_threshold);
			ShaderMan::LoadGenListShader(_dog_level_num, 0);
			ShaderMan::CreateGaussianFilters(*this);
			GlobalUtil::StopTimer();
		}

		if(GlobalUtil::_InitPyramidWidth >0 && GlobalUtil::_InitPyramidHeight >0)
		{
			GlobalUtil::StartTimer("Initialize Pyramids");
			for(int i = 0; i < _nPyramid; i++)
			{
				_pyramid[i].InitPyramid(GlobalUtil::_InitPyramidWidth,
										GlobalUtil::_InitPyramidHeight, 0);
			}
			GlobalUtil::StopTimer();
		}
	}


	ClockTimer::InitHighResolution();

	_initialized = 1;

}

int	 SiftGPU::RunSIFT(int index)
{
	if(_list->size()>0 )
	{
		index = index % _list->size();
		if(strcmp(_imgpath, _list->at(index).data()))
		{
			strcpy(_imgpath, _list->at(index).data());
			_image_loaded = 0;
			_current = index;
		}
		return RunSIFT();
	}else
	{
		return 0;
	}

}

int  SiftGPU::RunSIFT( int width,  int height, const void * data, unsigned int gl_format, unsigned int gl_type)
{

	if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
	if(!_initialized) InitSiftGPU();
	if(GlobalUtil::_GoodOpenGL ==0 ) return 0;

	if(width > 0 && height >0 && data != NULL)
	{
		_imgpath[0] = 0;
		//try downsample on CPU
		GlobalUtil::StartTimer("Upload Image data");
		if(_texImage->SetImageData(width, height, data, gl_format, gl_type))
		{
			_image_loaded = 2; //gldata;
			GlobalUtil::StopTimer();
			_timing[0] = GlobalUtil::GetElapsedTime();
			
			//if the size of image is different
			//pyramid need to be reallocated.
			GlobalUtil::StartTimer("Initialize Pyramid");
			_pyramid->InitPyramid(width, height, _texImage->_down_sampled);
			GlobalUtil::StopTimer();
			_timing[1] = GlobalUtil::GetElapsedTime();

			return RunSIFT();
		}else
		{
			return 0;
		}
	}else
	{
		return 0;
	}

}

int  SiftGPU::RunSIFT(char * imgpath)
{
	if(imgpath && imgpath[0])
	{
		if(strcmp(_imgpath, imgpath))
		{
			//set the new image
			strcpy(_imgpath, imgpath);
			_image_loaded = 0;
		}
		return RunSIFT();
	}else
	{
		return 0;
	}


}

int SiftGPU::RunSIFT(int num, const SiftKeypoint * keys, int keys_have_orientation)
{
	if(num <=0) return 0;
	_pyramid->SetKeypointList(num, (const float*) keys, 1, keys_have_orientation);
	return RunSIFT();
}

int SiftGPU::RunSIFT()
{
	//check image data
	if(_imgpath[0]==0 && _image_loaded == 0) return 0;

	//check OpenGL support
	if(GlobalUtil::_GoodOpenGL ==0 ) return 0;

	ClockTimer timer;

	//initialize SIFT GPU for once
	if(!_initialized)
	{
		InitSiftGPU();
		if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
	}

	timer.StartTimer("RUN SIFT");
	//process input image file
	if( _image_loaded ==0)
	{
		//load image
		GlobalUtil::StartTimer("Load Input Image");

		//try to down-sample on cpu
		int width, height; 

		if(_texImage->LoadImageFile(_imgpath, width, height)==0)
		{
			return 0;
		}

		_image_loaded = 1;

		GlobalUtil::StopTimer();
		_timing[0] = GlobalUtil::GetElapsedTime();

		//make sure the pyrmid can hold the new image.
		GlobalUtil::StartTimer("Initialize Pyramid");
		_pyramid->InitPyramid(width, height, _texImage->_down_sampled);
		GlobalUtil::StopTimer();
		_timing[1] = GlobalUtil::GetElapsedTime();

	}else
	{
		//change some global states
		if(!GlobalUtil::_UseCUDA)
		{
			GlobalUtil::FitViewPort(1,1);
			_texImage->FitTexViewPort();
		}
		if(_image_loaded == 1)
		{
			_timing[0] = _timing[1] = 0;
		}else
		{//2
			_image_loaded = 1; 
		}
	}

	if(_pyramid->_allocated ==0 ) return 0;

	//process the image
#ifdef DEBUG_SIFTGPU
	_pyramid->BeginDEBUG(_imgpath);
#endif
	_pyramid->RunSIFT(_texImage);
	_pyramid->GetPyramidTiming(_timing + 2); //

	//write output once if there is only one input
	if(_outpath[0] )
	{
		SaveSIFT(_outpath);
		_outpath[0] = 0;
	}
	
	//if you just want to call TestWin(Glut) as a sift processor
	//now we end the process
	if(GlobalUtil::_ExitAfterSIFT && GlobalUtil::_UseSiftGPUEX) exit(0); 

	if(GlobalUtil::_UseCUDA == 0)
	{
		//clean up OpenGL stuff
		GLTexImage::UnbindMultiTex(3);
		ShaderMan::UnloadProgram();
		FrameBufferObject::DeleteGlobalFBO();
		GlobalUtil::CleanupOpenGL();
	}
	timer.StopTimer();
	if(GlobalUtil::_verbose)std::cout<<endl;

	return 1;
}


void SiftGPU::SetKeypointList(int num, const SiftKeypoint * keys, int keys_have_orientation)
{
	_pyramid->SetKeypointList(num, (const float*)keys, 0, keys_have_orientation);
}

void SiftGPUEX::DisplayInput() 
{
	if(_texImage==NULL) return;
	_texImage->BindTex();
	_texImage->DrawImage();
	_texImage->UnbindTex();

}

void SiftGPU::GetImageDimension( int &w,  int &h)
{
	w = _texImage->GetImgWidth();
	h = _texImage->GetImgHeight();

}

void SiftGPU::SetVerbose(int verbose)
{
	GlobalUtil::_timingO = verbose>2;
	GlobalUtil::_timingL = verbose>3;
	if(verbose == -1)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -