HDR exposure fusion 论文实现

7年前的老代码,两篇论文的实现:

1,Reference-guided exposure fusion in dynamic scenes
2,Tom Mertens 的 Exposure Fusion
3, Ghost Removal in Exposure Fusion by Temporal Consistency Assessment(这个是楼主写的论文,主要idea有两点,一个是多尺度的二值图,一个是颜色空间去鬼影,有时间会把代码整理一下放出来)
那时刚接触opencv,对接口不熟悉,很多opencv自带函数都自己写了,可能对还在研究HDR的朋友有一定帮助

应该是2.4.X的opencv版本


// My1_re.cpp : 定义控制台应用程序的入口点。
//zhang's method + binary map

#include "stdafx.h"
#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include "highgui.h" 
#include "cv.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
using namespace cv; 
using namespace std;
#define M_Cx 1000
#define M_Cy 667
#define PI 3.1415926535
#define radius 0
#define arf 0.01
#define bert 0.9
#define gamma 0.99
typedef struct pixel{
	int B;
	int G;
	int R;
	};
typedef struct pixel_double{
	double B;
	double G;
	double R;
	};
int NearestInt (double F){
	return F>0?(int)(F+0.5):(int)(F-0.5);
}

void GetPixel(IplImage *image,pixel **Matrix_QUYUTU)//get image's pixel value matrix
{
	int width=image->width;
	
	int heigh=image->height;
	
	int channel=image->nChannels;
	
	int widthStep=image->widthStep;
	uchar *pchar;
	int i,j;
	for (i=0; i<heigh; i++)
	{ 
		pchar = (uchar*)image->imageData + i*widthStep;
		for (j=0; j<width; j++) 
		{ 
			uchar* temp = pchar + j*channel;
		Matrix_QUYUTU[i][j].B=temp[0];
		//B
		Matrix_QUYUTU[i][j].G=temp[1] ;
		//G 
		 Matrix_QUYUTU[i][j].R=temp[2] ;
		//R 
		}
	}
	
}

void Get_CIMG(IplImage *image,pixel **Matrix_QUYUTU)//get image's pixel value matrix
{
	int width=image->width;
	
	int heigh=image->height;
	
	int channel=image->nChannels;
	
	int widthStep=image->widthStep;
	uchar *pchar;
	int i,j;
	for (i=0; i<heigh; i++)
	{ 
		pchar = (uchar*)image->imageData + i*widthStep;
		for (j=0; j<width; j++) 
		{ 
			uchar* temp = pchar + j*channel;
		temp[0]=Matrix_QUYUTU[i][j].B;
		//B
		temp[1]=Matrix_QUYUTU[i][j].G ;
		//G 
		 temp[2]=Matrix_QUYUTU[i][j].R ;
		//R 
		}
	}
	
}
void GetPixel_double(IplImage *image,pixel_double **Matrix_QUYUTU)//get image's pixel value matrix
{
	int width=image->width;
	
	int heigh=image->height;
	
	int channel=image->nChannels;
	
	int widthStep=image->widthStep;
	uchar *pchar;
	int i,j;
	for (i=0; i<heigh; i++)
	{ 
		pchar = (uchar*)image->imageData + i*widthStep;
		for (j=0; j<width; j++) 
		{ 
			uchar* temp = pchar + j*channel;
		Matrix_QUYUTU[i][j].B=temp[0];
		//B
		Matrix_QUYUTU[i][j].G=temp[1] ;
		//G 
		 Matrix_QUYUTU[i][j].R=temp[2] ;
		//R 
		}
	}
	
}
void GetPixel_GRAY(IplImage *image,int **Matrix_QUYUTU)//get image's pixel value matrix
{
	int width=image->width;
	
	int heigh=image->height;
	
	int channel=image->nChannels;
	
	int widthStep=image->widthStep;
	uchar *pchar;
	int i,j;
	for (i=0; i<heigh; i++)
	{ 
		pchar = (uchar*)image->imageData + i*widthStep;
		for (j=0; j<width; j++) 
		{ 
			uchar* temp = pchar + j*channel;
			Matrix_QUYUTU[i][j]=temp[0];

		}
	}
	
}
void extendTO_255(int **pixel__,double **float_number){

		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
			pixel__[i][j]=NearestInt(float_number[i][j]*255.0);
	
}
void Get_saturation(pixel_double **pixel_value, double **saturation){
	// for saturation 

	
		double mu;// mean of 3 channel 
		double R_d, G_d, B_d;// differnce between each channel and mean 
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){ 

			mu=(pixel_value[i][j].R+pixel_value[i][j].B+pixel_value[i][j].G)/3.0;

			R_d=pixel_value[i][j].R-mu;
			G_d=pixel_value[i][j].G-mu;
			B_d=pixel_value[i][j].B-mu;

			saturation[i][j]=sqrt((pow(R_d,2.0)+pow(G_d,2.0)+pow(B_d,2.0))/3.0);//pixel saturation
		}
		

}
void normalization(double **D_num,int **I_num){
	
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
		D_num[i][j]=I_num[i][j]/255.0;
			
}
void normalization_0_1(double** num){
	double buffer=0.0;
	for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				if (buffer<num[i][j])
					buffer=num[i][j];
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				num[i][j]=num[i][j]/buffer;




}
void doubleTOpixelvalue(double **number, int **pixel__){
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
			pixel__[i][j]=NearestInt(number[i][j]*255.0);

	}
void Get_Intensity(int **I,pixel **Matrix_pixel)
{

	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
			I[i][j]=(Matrix_pixel[i][j].R+Matrix_pixel[i][j].B+Matrix_pixel[i][j].G)/3;

}
void Get_Intensity_double(double **I,pixel_double **Matrix_pixel)
{

	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
			I[i][j]=(Matrix_pixel[i][j].R+Matrix_pixel[i][j].B+Matrix_pixel[i][j].G)/3.0;

}
void Get_exposedness(double **EXP,pixel_double **Matrix_pixel){
	double R_Guass, G_Guass, B_Guass;
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
		R_Guass=exp(-1*pow((Matrix_pixel[i][j].R-0.5),2.0)/0.08);// Guass distribution
		G_Guass=exp(-1*pow((Matrix_pixel[i][j].G-0.5),2.0)/0.08);
		B_Guass=exp(-1*pow((Matrix_pixel[i][j].B-0.5),2.0)/0.08);
		EXP[i][j]=R_Guass*G_Guass*B_Guass;// Combining three channel
		}

}
void Get_IMG(IplImage* _IMG,int **Pixel_v){
	int widthStep=_IMG->widthStep;
	uchar *pchar;
	int i,j;
	for (i=0; i<M_Cy; i++)
	{ 
		pchar = (uchar*)_IMG->imageData +i*widthStep;
		for (j=0; j<M_Cx; j++) 
		{ 
			uchar *temp = pchar +j;
			temp[0]=Pixel_v[i][j];
		}
	}
}
void combine(double **mtrix1,double **mtrix2,double **mtrix3,double **sub_weight){
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
			sub_weight[i][j]=mtrix1[i][j]*mtrix2[i][j]*mtrix3[i][j];
	
}

 
void get_direction(CvMat *imgx,CvMat *imgy,double **direction){

	double bufferx, buffery;

	for(int i=0;i<M_Cy;i++){
		
		for(int j=0;j<M_Cx;j++){
			bufferx = cvmGet(imgx,i,j);
			buffery = cvmGet(imgy,i,j);
			if (bufferx==0)
				bufferx=bufferx+0.000000000000001;
			//direction[i][j]=atan2(buffery,bufferx);

			direction[i][j]=atan2(buffery,bufferx);///360;
		
				

		}
	}
	
}
void filter_2D(double** INTENSITY_double_ref,CvMat* xdst,CvMat* ydst)
  {
	  const int size_=M_Cy*M_Cx;
	  double *buffer=new double[size_];
	  int n=0;
	  for(int i=0;i<M_Cy;i++)
		  for(int j=0;j<M_Cx;j++){
			  buffer[n]=INTENSITY_double_ref[i][j];
			  n++;
		  }
		
	  	CvMat src = cvMat(M_Cy, M_Cx,CV_64FC1,buffer);




	
	
	double xfilter_mat[]={
		 0.0116601 ,  0.0861571 ,  0.0116601,
		 0.0 ,           0.0 ,        0.0,
		-0.0116601 , -0.0861571 , -0.0116601
	};
	
	CvMat xfilter=cvMat( 3, 3,CV_64FC1,xfilter_mat);
	CvPoint anchor=cvPoint(-1,-1);
	cvFilter2D(&src,xdst,&xfilter,anchor);

	double yfilter_mat[]={
		0.0116601 , 0.0 , -0.0116601,
		0.0861571 , 0.0 , -0.0861571,
		0.0116601 , 0.0 , -0.0116601
	};
	
	CvMat yfilter=cvMat( 3, 3,CV_64FC1,yfilter_mat);

	cvFilter2D(&src,ydst,&yfilter,anchor );
}
void get_delta(double **_mat,double **delta){
  for(int i=0;i<M_Cy;i++)
	  for(int j=0;j<M_Cx;j++){
	  
		  if((_mat[i][j])<gamma&&(_mat[i][j])>(1-gamma))	
			  delta[i][j]=arf;
		  else
			  delta[i][j]=bert;
	  }

  }
void get_Temporal_weight(double **ref,double **other_img,double **Delta,double **weight){
	
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
			double difference;
			if(abs(other_img[i][j]-ref[i][j])>PI)
				difference=2*PI-abs(other_img[i][j]-ref[i][j]);
			else
			{
				difference=abs(other_img[i][j]-ref[i][j]);
			}

			weight[i][j]=exp((-difference*difference)/(2.0*pow(Delta[i][j],2.0)));
		}
	//ref for reference image.
	//other_image stand for LDR images excepting reference image,
	//	Delta is matrix consistent with other image.
	

}
void Get_IMG_double(IplImage* _IMG,double **Pixel_v){

	int widthStep=_IMG->widthStep;
	uchar *pchar;
	int i,j,buffer;
	for (i=0; i<M_Cy; i++)
	{ 
		pchar = (uchar*)_IMG->imageData +i*widthStep;
		for (j=0; j<M_Cx; j++) 
		{	
			uchar *temp = pchar +j;
			buffer=NearestInt(Pixel_v[i][j]*255.0);
			temp[0]=buffer;
		}
	}
}

void MY_Laplace(double** INTENSITY_double_ref,double** Laplace_NMtrix){

		double buffer1;
	  const int size_=M_Cy*M_Cx;
	  double *buffer=new double[size_];
	  int n=0;
	  for(int i=0;i<M_Cy;i++)
		  for(int j=0;j<M_Cx;j++){
			  buffer[n]=INTENSITY_double_ref[i][j];
			  n++;
		  }
		
	  	CvMat src = cvMat(M_Cy, M_Cx,CV_64FC1,buffer);



	double Laplace_filter_mat[]={			
		0,1,0,
		1,-4,1,
		0,1,0
	};
	CvMat* dst= cvCreateMat(M_Cy, M_Cx,CV_64FC1);
	CvMat Laplace_filter=cvMat( 3, 3,CV_64FC1,Laplace_filter_mat);
	CvPoint anchor=cvPoint(-1,-1);
	cvFilter2D(&src,dst,&Laplace_filter,anchor);
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
				buffer1=cvmGet(dst,i,j);
				
				if(buffer1<0)
					Laplace_NMtrix[i][j]=-buffer1;
				else
					Laplace_NMtrix[i][j]=buffer1;
			}

}
void V_weight(IplImage* IMG, double** V_weight)
{
	
	pixel **mat;
	mat = new pixel * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		mat[i]=new pixel[M_Cx];
	GetPixel(IMG,mat);
// got pixel value in integer number
	pixel_double **mat_double;
		
	mat_double = new pixel_double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		mat_double[i]=new pixel_double[M_Cx];
	
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
			mat_double[i][j].B=mat[i][j].B/255.0;
			mat_double[i][j].G=mat[i][j].G/255.0;
			mat_double[i][j].R=mat[i][j].R/255.0;
	
		}
//normalization of image pixel
	IplImage* Laplace_IMG=cvCreateImage(cvGetSize(IMG),IPL_DEPTH_8U,1);//Laplace image, for contrast

	double **INTENSITY ;
	INTENSITY  = new double  * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		INTENSITY[i]=new double[M_Cx];

	Get_Intensity_double(INTENSITY,mat_double);


	
		
	double **Laplace_NMtrix;
	Laplace_NMtrix = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		Laplace_NMtrix[i]=new double[M_Cx];
		

	MY_Laplace(INTENSITY,Laplace_NMtrix);

//laplace of image
	
	double **SATURATION;
	SATURATION = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		SATURATION[i]=new double[M_Cx];
	Get_saturation(mat_double,SATURATION);



//got saturation assessment of image




	double **EXP;
	EXP = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		EXP[i]=new double[M_Cx];
		//IplImage* EXP_under_IMG= cvCreateImage(cvGetSize(IMG_under),IPL_DEPTH_8U,1);

	Get_exposedness(EXP,mat_double);
//got exposedness


	combine(Laplace_NMtrix,SATURATION,EXP,V_weight);
}


void T_weight(IplImage* IMG_other, double** weight_other){

	char* IMG_name_ref ="3.jpg";
	IplImage* IMG_ref = cvLoadImage(IMG_name_ref);

	pixel **ref_mat;
	ref_mat = new pixel * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		ref_mat[i]=new pixel[M_Cx];


	GetPixel(IMG_ref,ref_mat);
	cout<<"(179.505) "<<ref_mat[505][179].B<<" "<<ref_mat[505][179].G<<" "<<ref_mat[505][179].R<<endl;

	pixel_double **ref_mat_double;
		
	ref_mat_double = new pixel_double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		ref_mat_double[i]=new pixel_double[M_Cx];
	
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
			ref_mat_double[i][j].B=ref_mat[i][j].B/255.0;
			ref_mat_double[i][j].G=ref_mat[i][j].G/255.0;
			ref_mat_double[i][j].R=ref_mat[i][j].R/255.0;
		}


	double **Delta_ref;
	Delta_ref = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		Delta_ref[i]=new double[M_Cx];
	
	double **INTENSITY_double_ref;
	INTENSITY_double_ref = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		INTENSITY_double_ref[i]=new double[M_Cx];
	Get_Intensity_double(INTENSITY_double_ref,ref_mat_double);
	get_delta(INTENSITY_double_ref,Delta_ref);

		
	CvMat* xdst_ref = cvCreateMat(IMG_ref->height, IMG_ref->width,CV_64FC1);
	CvMat* ydst_ref = cvCreateMat(IMG_ref->height, IMG_ref->width,CV_64FC1);
	


	filter_2D(INTENSITY_double_ref,xdst_ref,ydst_ref);



	double **direction_ref;
	direction_ref = new double * [M_Cy];
		for(int i=0;i<M_Cy;i++)
			direction_ref[i]=new double[M_Cx];
	get_direction(xdst_ref,ydst_ref,direction_ref);
		double angleref;
	angleref=(360*direction_ref[392][471])/PI;
	cout<<"(179.505) fangxiang "<<angleref<<endl;


	pixel **other_mat;
	other_mat = new pixel * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		other_mat[i]=new pixel[M_Cx];


	GetPixel(IMG_other,other_mat);

	pixel_double **other_mat_double;
		
	other_mat_double = new pixel_double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		other_mat_double[i]=new pixel_double[M_Cx];
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
			other_mat_double[i][j].B=other_mat[i][j].B/255.0;
			other_mat_double[i][j].G=other_mat[i][j].G/255.0;
			other_mat_double[i][j].R=other_mat[i][j].R/255.0;
		}
		//IplImage* Laplace_other_IMG=cvCreateImage(cvGetSize(IMG_other),IPL_DEPTH_8U,1);//Laplace image, for contrast

	double **INTENSITY_double_other;
	INTENSITY_double_other = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		INTENSITY_double_other[i]=new double[M_Cx];
	Get_Intensity_double(INTENSITY_double_other,other_mat_double);

	//cvSaveImage("Delta_.jpg",imgweight_Deltaother);
	//cvSaveImage("INTENSITY_other_IMG.jpg",INTENSITY_other_IMG);

	CvMat* xdst_other = cvCreateMat(IMG_other->height, IMG_other->width,CV_64FC1);
	CvMat* ydst_other = cvCreateMat(IMG_other->height, IMG_other->width,CV_64FC1);
	filter_2D(INTENSITY_double_other,xdst_other,ydst_other);



	double **direction_other;
		direction_other = new double * [M_Cy];
		for(int i=0;i<M_Cy;i++)
			direction_other[i]=new double[M_Cx];
	get_direction(xdst_other,ydst_other,direction_other);
	double angleother;
	angleother=(360*direction_other[392][471])/PI;
	cout<<"(179.505) fangxiang "<<angleother<<endl;
	get_Temporal_weight(direction_ref,direction_other,Delta_ref,weight_other);

}
void combine_VT(double** V,double** T,double** combined_weight){

	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++)
		{
			combined_weight[i][j]=V[i][j]*T[i][j];
			
		}
		

}
void final_weight(double **weight_under,double **weight_mid,double **weight_over,double **weight_over4,double **weight_over5){
	double multiple ;// Time-domain normalization factor
	for(int i=0;i<M_Cy;i++)
		for(int j=0;j<M_Cx;j++){
		
		multiple = 1.0/(weight_under[i][j]+weight_mid[i][j]+weight_over[i][j]+weight_over4[i][j]+weight_over5[i][j]+0.00000000000000000001);
		weight_under[i][j]=weight_under[i][j]*multiple ;// Time-domain normalization

		weight_mid[i][j]=weight_mid[i][j]*multiple;// Time-domain normalization
		weight_over[i][j]=weight_over[i][j]*multiple;
		weight_over4[i][j]=weight_over4[i][j]*multiple;
		weight_over5[i][j]=weight_over5[i][j]*multiple;// Time-domain normalization 
		
		}


}

void MY_bilateral(IplImage* img,double** weight,double** R_weight){



		pixel **_mat;
		_mat = new pixel * [M_Cy];
		for(int i=0;i<M_Cy;i++)
			_mat[i]=new pixel[M_Cx];


		GetPixel(img,_mat);

		
		pixel_double **mat_double;
		
		mat_double = new pixel_double * [M_Cy];
		for(int i=0;i<M_Cy;i++)
			mat_double[i]=new pixel_double[M_Cx];
	
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
				mat_double[i][j].B=_mat[i][j].B/255.0;
				mat_double[i][j].G=_mat[i][j].G/255.0;
				mat_double[i][j].R=_mat[i][j].R/255.0;
	
			}


		double **INTENSITY_double;
		INTENSITY_double= new double * [M_Cy];
		for(int i=0;i<M_Cy;i++)
			INTENSITY_double[i]=new double[M_Cx];


		Get_Intensity_double(INTENSITY_double,mat_double);


	double mol,molbuffer;
	double den,denbuffer;
	
	for(int i=0;i<M_Cy;i++)

		for(int j=0;j<M_Cx;j++){
		R_weight[i][j]=weight[i][j];

		
		}

	for(int i=radius;i<M_Cy-radius;i++){

	for(int j=radius;j<M_Cx-radius;j++){
		molbuffer=0;
		denbuffer=0;
		for(int x=(-1)*radius;x<=radius;x++){
			for(int y=(-1)*radius;y<=radius;y++){
			mol=exp(-(x*x+y*y)/(2.0*25.0))*exp(-pow((INTENSITY_double[i][j]-INTENSITY_double[i+x][j+y]),2.0)/(2.0*pow(0.196078,2.0)))*weight[i+x][j+y];//
			molbuffer=molbuffer+mol;
			den=exp(-(x*x+y*y)/(2.0*25.0))*exp(-pow((INTENSITY_double[i][j]-INTENSITY_double[i+x][j+y]),2.0)/(2.0*pow(0.196078,2.0)));
			denbuffer=denbuffer+den;
		
			}
		}
		R_weight[i][j]=molbuffer/denbuffer;
	}

	}
	
				


}

class LaplacianBlending {  
    private:  
        Mat_<Vec3f> under; 
		Mat_<Vec3f> mid;
        Mat_<Vec3f> over; 
		Mat_<Vec3f> over4;
		Mat_<Vec3f> over5;
        Mat_<float> under_blendweight_;  
		Mat_<float> mid_blendweight_; 
		Mat_<float> over_blendweight_;
		Mat_<float> over4_blendweight_;
		Mat_<float> over5_blendweight_;
      
        vector<Mat_<Vec3f> > underLapPyr,midLapPyr,overLapPyr,over4LapPyr,over5LapPyr,resultLapPyr;//Laplacian Pyramids  
        Mat underHighestLevel,midHighestLevel, overHighestLevel,over4HighestLevel,over5HighestLevel, resultHighestLevel;  
        vector<Mat_<Vec3f> > under_weight_GaussianPyramid,mid_weight_GaussianPyramid,over_weight_GaussianPyramid,over4_weight_GaussianPyramid,over5_weight_GaussianPyramid; //weight_s are 3-channels for easier multiplication with RGB  
      
        int levels;  
      
        void buildPyramids() {  
            buildLaplacianPyramid(under,underLapPyr,underHighestLevel);  
			buildLaplacianPyramid(mid,midLapPyr,midHighestLevel);  
            buildLaplacianPyramid(over,overLapPyr,overHighestLevel);
			buildLaplacianPyramid(over4,over4LapPyr,over4HighestLevel);
			buildLaplacianPyramid(over5,over5LapPyr,over5HighestLevel);  
            build_under_GaussianPyramid();
			build_mid_GaussianPyramid();
			build_over_GaussianPyramid();
			build_over4_GaussianPyramid();
			build_over5_GaussianPyramid();

        }  
      
        void build_under_GaussianPyramid() {//pyramid stand for weight of every level  
            assert(underLapPyr.size()>0);  
      
            under_weight_GaussianPyramid.clear();  
            Mat currentImg;  
            cvtColor(under_blendweight_, currentImg, CV_GRAY2BGR);//store color img of blend weight into weight_GaussianPyramid  
            under_weight_GaussianPyramid.push_back(currentImg); //0-level  
      
            currentImg = under_blendweight_;  
            for (int l=1; l<levels+1; l++) {  
                Mat _down;  
                if (underLapPyr.size() > l)  
                    pyrDown(currentImg, _down, underLapPyr[l].size());  
                else  
                    pyrDown(currentImg, _down, underHighestLevel.size()); //lowest level  
      
                Mat down;  
                cvtColor(_down, down, CV_GRAY2BGR);  
                under_weight_GaussianPyramid.push_back(down);//add color blend weigh into weight Pyramid  
                currentImg = _down;  
            }  
		}  
      
   void build_mid_GaussianPyramid() {//pyramid stand for weight of every level   
            assert(underLapPyr.size()>0);  
      
            mid_weight_GaussianPyramid.clear();  
            Mat currentImg;  
            cvtColor(mid_blendweight_, currentImg, CV_GRAY2BGR);//store color img of blend weightinto weight GaussianPyramid  
            mid_weight_GaussianPyramid.push_back(currentImg); //0-level  
      
            currentImg = mid_blendweight_;  
            for (int l=1; l<levels+1; l++) {  
                Mat _down;  
                if (underLapPyr.size() > l)  
                    pyrDown(currentImg, _down, underLapPyr[l].size());  
                else  
                    pyrDown(currentImg, _down, underHighestLevel.size()); //lowest level  
      
                Mat down;  
                cvtColor(_down, down, CV_GRAY2BGR);  
                mid_weight_GaussianPyramid.push_back(down);//add color blend weight into weight Pyramid  
                currentImg = _down;  
            }  
		}  

      void build_over_GaussianPyramid() {//pyramid stand for weight of every level  
            assert(underLapPyr.size()>0);  
      
            over_weight_GaussianPyramid.clear();  
            Mat currentImg;  
            cvtColor(over_blendweight_, currentImg, CV_GRAY2BGR);//store color img of blend weight_ into weight_GaussianPyramid  
            over_weight_GaussianPyramid.push_back(currentImg); //0-level  
      
            currentImg = over_blendweight_;  
            for (int l=1; l<levels+1; l++) {  
                Mat _down;  
                if (underLapPyr.size() > l)  
                    pyrDown(currentImg, _down, underLapPyr[l].size());  
                else  
                    pyrDown(currentImg, _down, underHighestLevel.size()); //lowest level  
      
                Mat down;  
                cvtColor(_down, down, CV_GRAY2BGR);  
                over_weight_GaussianPyramid.push_back(down);//extending weight from 1-channel to 3-channels
                currentImg = _down;  
            }  
		}  
	  //
	      void build_over4_GaussianPyramid() {//pyramid stand for weight of every level  
            assert(underLapPyr.size()>0);  
      
            over4_weight_GaussianPyramid.clear();  
            Mat currentImg;  
            cvtColor(over4_blendweight_, currentImg, CV_GRAY2BGR);//store color img of blend weight_ into weight_GaussianPyramid  
            over4_weight_GaussianPyramid.push_back(currentImg); //0-level  
      
            currentImg = over4_blendweight_;  
            for (int l=1; l<levels+1; l++) {  
                Mat _down;  
                if (underLapPyr.size() > l)  
                    pyrDown(currentImg, _down, underLapPyr[l].size());  
                else  
                    pyrDown(currentImg, _down, underHighestLevel.size()); //lowest level  
      
                Mat down;  
                cvtColor(_down, down, CV_GRAY2BGR);  
                over4_weight_GaussianPyramid.push_back(down);//extending weight from 1-channel to 3-channels
                currentImg = _down;  
            }  
		}  
		  //
		       void build_over5_GaussianPyramid() {//pyramid stand for weight of every level  
            assert(underLapPyr.size()>0);  
      
            over5_weight_GaussianPyramid.clear();  
            Mat currentImg;  
            cvtColor(over5_blendweight_, currentImg, CV_GRAY2BGR);//store color img of blend weight_ into weight_GaussianPyramid  
            over5_weight_GaussianPyramid.push_back(currentImg); //0-level  
      
            currentImg = over5_blendweight_;  
            for (int l=1; l<levels+1; l++) {  
                Mat _down;  
                if (underLapPyr.size()> l)  
                    pyrDown(currentImg, _down, underLapPyr[l].size());  
                else  
                    pyrDown(currentImg, _down, underHighestLevel.size()); //lowest level  
      
                Mat down;  
                cvtColor(_down, down, CV_GRAY2BGR);  
                over5_weight_GaussianPyramid.push_back(down);//extending weight from 1-channel to 3-channels
                currentImg = _down;  
            }  
		}  




        void buildLaplacianPyramid(const Mat& img, vector<Mat_<Vec3f> >& lapPyr, Mat& HighestLevel) {  
            lapPyr.clear();  
            Mat currentImg = img;  
            for (int l=0; l<levels; l++) {  
                Mat down,up;  
                pyrDown(currentImg, down);  
                pyrUp(down, up,currentImg.size());  
                Mat lap = currentImg - up;  
                lapPyr.push_back(lap);  
                currentImg = down;  
            }  
            currentImg.copyTo(HighestLevel);  
        }  
      
        Mat_<Vec3f> reconstructImgFromLapPyramid() {  
            //Reconstruct fusion image with resultLaPyr
            Mat currentImg = resultHighestLevel;  
            for (int l=levels-1; l>=0; l--) {  
                Mat up;  
      
                pyrUp(currentImg, up, resultLapPyr[l].size());  
                currentImg = up + resultLapPyr[l];  
            }  
            return currentImg;  
        }  
      
        void blendLapPyrs() {  
            // Getting every level weighted resultLapPyr
			Mat w1=under_weight_GaussianPyramid.back();
			Mat w2=mid_weight_GaussianPyramid.back();
			Mat w3=over_weight_GaussianPyramid.back();
			Mat w4=over4_weight_GaussianPyramid.back();
			Mat w5=over5_weight_GaussianPyramid.back();

            resultHighestLevel =(underHighestLevel.mul(w1) +  midHighestLevel.mul(w2) + overHighestLevel.mul(w3)+over4HighestLevel.mul(w4)+over5HighestLevel.mul(w5))/(w1+w2+w3+w4+w5+0.00000000000000000001);
            for (int l=0; l<levels; l++) {  
                Mat A = underLapPyr[l].mul(under_weight_GaussianPyramid[l]);  
               
                Mat B = midLapPyr[l].mul(mid_weight_GaussianPyramid[l]); 
				Mat C = overLapPyr[l].mul(over_weight_GaussianPyramid[l]);
				Mat D = over4LapPyr[l].mul(over4_weight_GaussianPyramid[l]);
				Mat E = over5LapPyr[l].mul(over5_weight_GaussianPyramid[l]);
				Mat W =under_weight_GaussianPyramid[l]+mid_weight_GaussianPyramid[l]+over_weight_GaussianPyramid[l]+over4_weight_GaussianPyramid[l]+over5_weight_GaussianPyramid[l]+0.00000000000000000001;
                Mat_<Vec3f> blendedLevel = (A + B +C+ D+E)/W;  
      
                resultLapPyr.push_back(blendedLevel);  
			}  
        }  
      
    public:  
        LaplacianBlending(const Mat_<Vec3f>& _under,const Mat_<Vec3f>& _mid, const Mat_<Vec3f>& _over,const Mat_<Vec3f>& _over4,const Mat_<Vec3f>& _over5, const Mat_<float>& _under_blendweight_,const Mat_<float>& _mid_blendweight_,const Mat_<float>& _over_blendweight_,const Mat_<float>& _over4_blendweight_,const Mat_<float>& _over5_blendweight_, int _levels)://construct function, used in LaplacianBlending lb(l,r,m,4);  
          under(_under),mid(_mid),over(_over),over4(_over4),over5(_over5),under_blendweight_(_under_blendweight_),mid_blendweight_(_mid_blendweight_),over_blendweight_(_over_blendweight_),over4_blendweight_(_over4_blendweight_),over5_blendweight_(_over5_blendweight_),levels(_levels)  
          {  
              assert(_under.size() == _over.size());  
              assert(_under.size() == _under_blendweight_.size());  
              buildPyramids();  //construct Laplacian Pyramid and Gaussian Pyramid  
              blendLapPyrs();   //blend under ,mid, over Pyramids into one Pyramid  
          };  
      
          Mat_<Vec3f> blend() {  
              return reconstructImgFromLapPyramid();//reconstruct Image from Laplacian Pyramid  
          }  
    };  
      
    Mat_<Vec3f> LaplacianBlend(const Mat_<Vec3f>& under, const Mat_<Vec3f>& mid,const Mat_<Vec3f>& over,const Mat_<Vec3f>& over4,const Mat_<Vec3f>& over5, const Mat_<float>& W_under,const Mat_<float>& W_mid,const Mat_<float>& W_over,const Mat_<float>& W_over4,const Mat_<float>& W_over5) {  
        LaplacianBlending lb(under,mid,over,over4,over5,W_under,W_mid,W_over,W_over4,W_over5,7);  
        return lb.blend();  
    }   
int _tmain(int argc, _TCHAR* argv[])
{
	
	char* IMG_under ="1.jpg";
	IplImage* V_IMG_under = cvLoadImage(IMG_under);

	double **V_weight_under;


	V_weight_under = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		V_weight_under[i]=new double[M_Cx];

	V_weight(V_IMG_under,V_weight_under);

	double **T_weight_under;
	T_weight_under = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		T_weight_under[i]=new double[M_Cx];
	T_weight(V_IMG_under,T_weight_under);
	
	double **weight_under;
	weight_under = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		weight_under[i]=new double[M_Cx];	


//	under image finish
	
	char* IMG_mid ="2.jpg";
	IplImage* V_IMG_mid = cvLoadImage(IMG_mid);

	double **V_weight_mid;
	V_weight_mid = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		V_weight_mid[i]=new double[M_Cx];
	double **T_weight_mid;
	T_weight_mid = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		T_weight_mid[i]=new double[M_Cx];

	V_weight( V_IMG_mid,V_weight_mid);
	T_weight(V_IMG_mid,T_weight_mid);


	double **weight_mid;
	weight_mid = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		weight_mid[i]=new double[M_Cx];	

//	mid image finish
//got visibility weight of mid-exposure image



	char* IMG_over ="3.jpg";
	IplImage* V_IMG_over = cvLoadImage(IMG_over);

	double **V_weight_over;
	V_weight_over = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		V_weight_over[i]=new double[M_Cx];
	double **T_weight_over;
	T_weight_over = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		T_weight_over[i]=new double[M_Cx];


	V_weight(V_IMG_over  ,V_weight_over);
	T_weight(V_IMG_over,T_weight_over);
	
	double **weight_over;
		weight_over = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		weight_over[i]=new double[M_Cx];


		char* IMG_over4 ="4.jpg";
	IplImage* V_IMG_over4 = cvLoadImage(IMG_over4);

	double **V_weight_over4;
	V_weight_over4 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		V_weight_over4[i]=new double[M_Cx];
	double **T_weight_over4;
	T_weight_over4 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		T_weight_over4[i]=new double[M_Cx];


	V_weight(V_IMG_over4  ,V_weight_over4);
	T_weight(V_IMG_over4,T_weight_over4);
	
	double **weight_over4;
		weight_over4 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		weight_over4[i]=new double[M_Cx];	

			
	
	char* IMG_over5 ="5.jpg";

	IplImage* V_IMG_over5 = cvLoadImage(IMG_over5);

	double **V_weight_over5;
	V_weight_over5 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		V_weight_over5[i]=new double[M_Cx];
	double **T_weight_over5;
	T_weight_over5 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		T_weight_over5[i]=new double[M_Cx];


	V_weight(V_IMG_over5  ,V_weight_over5);
	T_weight(V_IMG_over5,T_weight_over5);

	double **weight_over5;
		weight_over5 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		weight_over5[i]=new double[M_Cx];	
	

//
final_weight(V_weight_under,V_weight_mid,V_weight_over,V_weight_over4,V_weight_over5);

	combine_VT(V_weight_under,T_weight_under,weight_under);
	combine_VT(V_weight_mid,T_weight_mid,weight_mid);
	combine_VT(V_weight_over,T_weight_over,weight_over);
	combine_VT(V_weight_over4,T_weight_over4,weight_over4);
	combine_VT(V_weight_over5,T_weight_over5,weight_over5);


//final_weight(weight_under,weight_mid,weight_over);

		
//
	double **VTW_under;
	VTW_under= new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		VTW_under[i]=new double[M_Cx];
	MY_bilateral(V_IMG_under,weight_under,VTW_under);

	double **VTW_mid;
	VTW_mid = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		VTW_mid[i]=new double[M_Cx];
	MY_bilateral(V_IMG_mid,weight_mid,VTW_mid);

	double **VTW_over;
	VTW_over = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		VTW_over[i]=new double[M_Cx];
	MY_bilateral(V_IMG_over,weight_over,VTW_over);

	double **VTW_over4;
	VTW_over4 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		VTW_over4[i]=new double[M_Cx];
	MY_bilateral(V_IMG_over4,weight_over4,VTW_over4);

	double **VTW_over5;
	VTW_over5 = new double * [M_Cy];
	for(int i=0;i<M_Cy;i++)
		VTW_over5[i]=new double[M_Cx];
	MY_bilateral(V_IMG_over5,weight_over5,VTW_over5);
	//normalization_0_1(VTW_over);	

Mat src=Mat(M_Cy, M_Cx,CV_64FC1);
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				src.at<double>(i,j)=VTW_mid[i][j];

		//imshow("VTW_mid",src);  
  	Mat src1=Mat(M_Cy, M_Cx,CV_64FC1);
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				src1.at<double>(i,j)=VTW_over[i][j];

			Mat src4=Mat(M_Cy, M_Cx,CV_64FC1);
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				src4.at<double>(i,j)=VTW_over4[i][j];

			Mat src5=Mat(M_Cy, M_Cx,CV_64FC1);
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
				src5.at<double>(i,j)=VTW_over5[i][j];



		     
	Mat under8u = imread("1.jpg");  
	Mat mid8u = imread("2.jpg"); 
    Mat over8u = imread("3.jpg");  
	 
	Mat over8u4 = imread("4.jpg");  
	Mat over8u5 = imread("5.jpg"); 

	imshow("1",under8u);  
	imshow("2",mid8u);
	imshow("3",over8u);
	imshow("4",over8u4);
	imshow("5",over8u5);  
     
	Mat_<Vec3f> under; under8u.convertTo(under,CV_32F,1.0/255.0);//Vec3f data structure has 3-channel pixels, defination for visit 3-channel mat.
	Mat_<Vec3f> mid; mid8u.convertTo(mid,CV_32F,1.0/255.0);
	Mat_<Vec3f> over; over8u.convertTo(over,CV_32F,1.0/255.0);
	Mat_<Vec3f> over4; over8u4.convertTo(over4,CV_32F,1.0/255.0);
	Mat_<Vec3f> over5; over8u5.convertTo(over5,CV_32F,1.0/255.0);

		//imshow("VTW_over",src1);  
     



		Mat_<float> W_under(under.rows,under.cols,0.0); //将W_under全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++)
			{
				W_under.at<float>(i,j)=(float)VTW_under[i][j];
			}
	

		Mat_<float> W_mid(under.rows,under.cols,0.0); //将W_mid全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			    W_mid.at<float>(i,j)=(float)VTW_mid[i][j];
			}

		Mat_<float> W_over(under.rows,under.cols,0.0); //将W_over全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			W_over.at<float>(i,j)=(float)VTW_over[i][j];
			}

		Mat_<float> W_over4(under.rows,under.cols,0.0); //将W_over全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			W_over4.at<float>(i,j)=(float)VTW_over4[i][j];
			}
		Mat_<float> W_over5(under.rows,under.cols,0.0); //将W_over全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			W_over5.at<float>(i,j)=(float)VTW_over5[i][j];
		}

				Mat_<float> W_over51(under.rows,under.cols,0.0); //将W_over全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			W_over51.at<float>(i,j)=(float)V_weight_over5[i][j];
		}
				


		Mat_<float> Tmertns3(under.rows,under.cols,0.0); //将W_over全部赋值为0
		for(int i=0;i<M_Cy;i++)
			for(int j=0;j<M_Cx;j++){
			Tmertns3.at<float>(i,j)=(float)V_weight_over[i][j];
		}
				imshow("Tmertns5",W_over51);
					imshow("Tmertns3",Tmertns3);
	imshow("3_weight",W_over);
		imshow("1_weight",W_under);
		imshow("2_weight",W_mid);
		imshow("4_weight",W_over4);
		imshow("5_weight",W_over5);

	Mat_<Vec3f> blend = LaplacianBlend(under, mid,over,over4,over5, W_under,W_mid,W_over,W_over4,W_over5);  
	imshow("Zhang’",blend); // 
	Mat static6= imread("6.jpg");
		Mat_<Vec3f> static61; static6.convertTo(static61,CV_32F,1.0/255.0);

		Mat static7= imread("7.jpg");
		Mat_<Vec3f> static71; static7.convertTo(static71,CV_32F,1.0/255.0);

		Mat static8= imread("8.jpg");
		Mat_<Vec3f> static81; static8.convertTo(static81,CV_32F,1.0/255.0);


	Mat_<Vec3f> blend1 = LaplacianBlend(under,static61,over,static71,static81, W_under,W_mid,W_over,W_over4,W_over5);  
	imshow("Zhang1’",blend1); //
Mat_<Vec3b> showshowshow;
	Vec3b showb;
	Vec3f showf;
	
			showshowshow=blend*255 ;
			//under_C(i,j)=(float)sqrt((double)(under_a(i,j)*under_a(i,j)+under_b(i,j)*under_b(i,j)));
			
			

	//showshowshow =255* blend;
	imshow("HDR_Resulting",blend); // 
	imwrite("Zhang's.jpg",showshowshow);
	showshowshow=blend1*255 ;
		imwrite("Zhang's1.jpg",showshowshow);



	waitKey(); 
	



	return 0;
}





  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值