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;
}