Exemplo n.º 1
0
		void LocalLaplacianFilter( 
			const MatrixF& src,
			float sigma,
			float alpha,
			MatrixF& dest)
		{
			//our remapping function
			Remapping remapFunction(sigma,alpha);

			//compute input gaussian pyramid
			MatrixFArray gpyramid, lpyramid;
			GaussianPyramid( src, gpyramid );

			//resize the laplacian pyramid
			lpyramid.resize( gpyramid.size() - 1 );
			for( int i = 0; i < lpyramid.size(); ++i )
				lpyramid[i].Resize( gpyramid[i].Rows(), gpyramid[i].Cols() );

			//no optimization
			//take the whole subregion
			cout << "Beginning" << endl;
			for( int i = 0; i < gpyramid.size() - 1; ++i )
			{
				for( int y = 0; y < gpyramid[i].Rows(); ++y )
				{
					for( int x = 0; x < gpyramid[i].Cols(); ++x )
					{		
						lpyramid[i][y][x] = FindLaplacianValue(
							src, remapFunction, gpyramid[i][y][x], i, y, x);
					}
				}
			}
			cout << "Ending" << endl;
			lpyramid.push_back( gpyramid[gpyramid.size()-1] );

			//collapse the pyramid
			CollapseLaplacianPyramid( lpyramid, dest );
		}
Exemplo n.º 2
0
/**
Gradient Domain HDR tone mapping operator
@param Y Image luminance values
@param alpha Parameter alpha of the paper (suggested value is 0.1)
@param beta Parameter beta of the paper (suggested value is between 0.8 and 0.9)
@return returns the tone mapped luminance
*/
static FIBITMAP* tmoFattal02(FIBITMAP *Y, float alpha, float beta) {
	const unsigned MIN_PYRAMID_SIZE = 32;	// minimun size (width or height) of the coarsest level of the pyramid

	FIBITMAP *H = NULL;
	FIBITMAP **pyramid = NULL;
	FIBITMAP **gradients = NULL;
	FIBITMAP *phy = NULL;
	FIBITMAP *divG = NULL;
	FIBITMAP *U = NULL;
	float *avgGrad = NULL;

	int k;
	int nlevels = 0;

	try {
		// get the normalized luminance
		FIBITMAP *H = LogLuminance(Y);
		if(!H) throw(1);
		
		// get the number of levels for the pyramid
		const unsigned width = FreeImage_GetWidth(H);
		const unsigned height = FreeImage_GetHeight(H);
		unsigned minsize = MIN(width, height);
		while(minsize >= MIN_PYRAMID_SIZE) {
			nlevels++;
			minsize /= 2;
		}

		// create the Gaussian pyramid
		pyramid = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
		if(!pyramid) throw(1);
		memset(pyramid, 0, nlevels * sizeof(FIBITMAP*));

		if(!GaussianPyramid(H, pyramid, nlevels)) throw(1);

		// calculate gradient magnitude and its average value on each pyramid level
		gradients = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
		if(!gradients) throw(1);
		memset(gradients, 0, nlevels * sizeof(FIBITMAP*));
		avgGrad = (float*)malloc(nlevels * sizeof(float));
		if(!avgGrad) throw(1);

		if(!GradientPyramid(pyramid, nlevels, gradients, avgGrad)) throw(1);

		// free the Gaussian pyramid
		for(k = 0; k < nlevels; k++) {
			if(pyramid[k]) FreeImage_Unload(pyramid[k]);
		}
		free(pyramid); pyramid = NULL;

		// compute the gradient attenuation function PHI(x, y)
		phy = PhiMatrix(gradients, avgGrad, nlevels, alpha, beta);
		if(!phy) throw(1);

		// free the gradient pyramid
		for(k = 0; k < nlevels; k++) {
			if(gradients[k]) FreeImage_Unload(gradients[k]);
		}
		free(gradients); gradients = NULL;
		free(avgGrad); avgGrad = NULL;

		// compute gradients in x and y directions, attenuate them with the attenuation matrix, 
		// then compute the divergence div G from the attenuated gradient. 
		divG = Divergence(H, phy);
		if(!divG) throw(1);

		// H & phy no longer needed
		FreeImage_Unload(H); H = NULL;
		FreeImage_Unload(phy); phy = NULL;

		// solve the PDE (Poisson equation) using a multigrid solver and 3 cycles
		FIBITMAP *U = FreeImage_MultigridPoissonSolver(divG, 3);
		if(!U) throw(1);

		FreeImage_Unload(divG);

		// perform exponentiation and recover the log compressed image
		ExpLuminance(U);

		return U;

	} catch(int) {
		if(H) FreeImage_Unload(H);
		if(pyramid) {
			for(int i = 0; i < nlevels; i++) {
				if(pyramid[i]) FreeImage_Unload(pyramid[i]);
			}
			free(pyramid);
		}
		if(gradients) {
			for(int i = 0; i < nlevels; i++) {
				if(gradients[i]) FreeImage_Unload(gradients[i]);
			}
			free(gradients);
		}
		if(avgGrad) free(avgGrad);
		if(phy) FreeImage_Unload(phy);
		if(divG) FreeImage_Unload(divG);
		if(U) FreeImage_Unload(U);

		return NULL;
	}
}