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

📄 fusionalgrithm.cpp

📁 影像融合与融合精度评价源码影像融合与融合精度评价源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// FusionAlgrithm.cpp: implementation of the CFusionAlgrithm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FusionAlgrithm.h"
#include "FeatureAlgrithm.h"
#include "dibapi.h"
#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFusionAlgrithm::CFusionAlgrithm()
{

}

CFusionAlgrithm::~CFusionAlgrithm()
{

}

HDIB CFusionAlgrithm::HISFUSION(HDIB HCOLOR, HDIB HPAN)
{
/////////////////进行HIS变换时当前图像为空图像(即输出图像)/////////////////////////

	LPSTR  muldib,pandib,outdib; //指向图像的指针
	BYTE* colorimage;//指向彩色图像的数据区位置
	BYTE* panimage;//指向全色图像的数据区位置
	muldib= (LPSTR) ::GlobalLock((HGLOBAL) HCOLOR);
	colorimage=(BYTE*)FindDIBBits(muldib);
	pandib= (LPSTR) ::GlobalLock((HGLOBAL) HPAN);
	panimage =(BYTE*)FindDIBBits(pandib);
	
	int wide,height,DibWidth,WIDE;
	wide=::DIBWidth(muldib);//取宽的像素个数
	height=::DIBHeight(muldib);
    DibWidth=3*wide+( sizeof(DWORD)- 3*wide %sizeof(DWORD) )%sizeof(DWORD);//取得原图的每行总位数
	WIDE=((wide*8)+31)/32*4;//取宽为4的整数倍

	BYTE * outimage;  //输出图像的数据区位置
	HDIB HOUT;
	
	HOUT=(HDIB)::GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+DibWidth*height);//生成一个新的图像句柄
	if(!HOUT){	return NULL;	}
	
	outdib	= (LPSTR)::GlobalLock((HGLOBAL)HOUT);
	memcpy(outdib,muldib,sizeof(BITMAPINFOHEADER));//sizeof(BITMAPINFOHEADER)=40
	outimage=  (BYTE*)FindDIBBits (outdib);

	if(muldib==NULL || pandib==NULL)
	{
		AfxMessageBox("必须选择两幅影像!",MB_ICONSTOP);	
		return NULL;
	}
	if(muldib==pandib)
	{
		AfxMessageBox("不可以出现两幅相同的影像!",MB_ICONSTOP);
		return NULL;
	}
	if(::DIBWidth(muldib)!=::DIBWidth(pandib) || ::DIBHeight(muldib)!= ::DIBHeight(pandib))
	{
		AfxMessageBox("两幅影像的宽度高度必须相等!",MB_ICONSTOP);
		return NULL;
	}
		
   	float *	HIS;//用于HIS空间
	float * Temp;
    float * Im;
	float * R;
	float * G;
	float * B;

	HIS  = new float[DibWidth*height] ;//开辟一个新内存
	Temp = new float[WIDE*height]     ;//处理全色图像
	Im   = new float[WIDE*height]     ;//用于存放I分量

	B    = new float[WIDE*height]     ;
	R    = new float[WIDE*height]     ;
	G    = new float[WIDE*height]     ;	
	////////////////    HIS TRANSFORM    ///////////
 
	for(int j=0;j<height;j++)
		for (int i=0;i<DibWidth;i+=3)
		{
			 B[j*WIDE+i/3] =colorimage[j*DibWidth+i  ];  //得到蓝值   
		     G[j*WIDE+i/3] =colorimage[j*DibWidth+i+1];  //得到绿值  
			 R[j*WIDE+i/3] =colorimage[j*DibWidth+i+2];  //得到红值
	      			
			float H,S,I;

			I=(R[j*WIDE+i/3]+G[j*WIDE+i/3]+B[j*WIDE+i/3])/3;
			
			if      (B[j*WIDE+i/3]<=G[j*WIDE+i/3]&&B[j*WIDE+i/3]<=R[j*WIDE+i/3])
			{
				H=(G[j*WIDE+i/3]-B[j*WIDE+i/3])/((I-B[j*WIDE+i/3])*3);
				S=1-(B[j*WIDE+i/3]/I);
			}
			else if (R[j*WIDE+i/3]<=G[j*WIDE+i/3]&&R[j*WIDE+i/3]<=B[j*WIDE+i/3])
			{
				H=(B[j*WIDE+i/3]-R[j*WIDE+i/3])/((I-R[j*WIDE+i/3])*3);
				S=1-(R[j*WIDE+i/3]/I);
			}
			else if (G[j*WIDE+i/3]<=B[j*WIDE+i/3]&&G[j*WIDE+i/3]<=R[j*WIDE+i/3])
			{
				H=(R[j*WIDE+i/3]-G[j*WIDE+i/3])/((I-G[j*WIDE+i/3])*3);
				S=1-(G[j*WIDE+i/3]/I);
			}
       
      /**/
            if (H<0)    H=(-1)*H;			
            if (S<0)    S=(-1)*S;		
           	if (I<0)    I=(-1)*I;
      
         
			HIS[i+j*DibWidth]   = I;
		    HIS[i+1+j*DibWidth] = H;
		    HIS[i+2+j*DibWidth] = S;
  			Im[j*WIDE+i/3]  = I; 
			Temp[j*WIDE+i/3] = (float)panimage[j*WIDE+i/3];
		}		

///////////////////     融合    ////////////////// 
  float *imh;
  imh=new float[WIDE*height];
HistogramMatch(Temp,Im,WIDE,height,imh);//用I分量图像对全色图像进行直方图均衡
	if(imh == NULL)
	{
		AfxMessageBox("直方图均衡失败!",MB_ICONSTOP);
	    return NULL;
	}
	free(Temp); 
	free(Im)  ;  //自动分配内存,不用释放 
			
/////////////////////    HIS逆变换     /////////////

	for(int m=0;m<height;m++)
		for (int n=0;n<DibWidth;n+=3)
		{
			float I,H,S,r,g,b;
		   	I  = imh[m*WIDE+n/3]       ; //HIS内存赋给I
		    H  = HIS[m*DibWidth+n+1]   ; //HIS内存赋给H
		    S  = HIS[m*DibWidth+n+2]   ; //HIS内存赋给S
			if (B[m*WIDE+n/3]<=G[m*WIDE+n/3]&&B[m*WIDE+n/3]<=R[m*WIDE+n/3])
				{
					b=I*(1-S);
					g=3*H*(I-b)+b;
					r=3*I-g-b;
				}
			else if (R[m*WIDE+n/3]<=G[m*WIDE+n/3]&&R[m*WIDE+n/3]<=B[m*WIDE+n/3])
				{
					r=I*(1-S);
					b=3*H*(I-r)+r;
					g=3*I-r-b;
				}
			else if(G[m*WIDE+n/3]<=B[m*WIDE+n/3]&&G[m*WIDE+n/3]<=R[m*WIDE+n/3])
				{
			     	g=I*(1-S);
					r=3*H*(I-g)+g;
					b=3*I-r-g;
				}
	
			if (b>=255)  b=255;
			else  if (b<=0)    b=0;
			else b=b;
			if (r>=255)  r=255;
			else  if (r<=0)    r=0;
			else r=r;
			if (g>=255)  g=255;
			else  if (g<=0)    g=0;
			else g=g;
	
			HIS[m*DibWidth+n  ] = b ;//得到的b赋给蓝值
			HIS[m*DibWidth+n+1] = g ;//得到的g赋给绿值
			HIS[m*DibWidth+n+2] = r ;//得到的r赋给红值
				}
/////////////////   OUTIMAGE中输出融合图像/////
						
	for(int u=0;u<height;u++)
		for (int v=0;v<DibWidth;v+=3)
			{
				outimage[u*DibWidth+v  ] = (BYTE)HIS[u*DibWidth+v  ];
				outimage[u*DibWidth+v+1] = (BYTE)HIS[u*DibWidth+v+1];
				outimage[u*DibWidth+v+2] = (BYTE)HIS[u*DibWidth+v+2];
			}
		free(HIS);	
		free(R);
		free(B);
		free(G);
		delete []imh;
		::GlobalUnlock((HGLOBAL) HCOLOR); 
      	::GlobalUnlock((HGLOBAL) HPAN  ); 
		return  (HDIB)HOUT;	
}

float * CFusionAlgrithm::HistogramMatch(float *img1, float *img2, int width, int height,float *imgResult)
{
	////////////////////      直方图匹配分析      /////////////////////////
	//img1全色波段,img2为I分量

		if( img1 == NULL || img2 == NULL)
		{
			AfxMessageBox("获取影像指针失败!",MB_ICONSTOP);
			return NULL;
		}
	
	static int K = 256;
	int i,j,k,l;

	double min;		BYTE gray;
	int *histo1 = new int[K];	int *histo2 = new int[K];
	double *p1 = new double[K];		double *p2 = new double[K];
	double *f = new double[K];		double *g = new double[K];
	int *cpd = new int[K];//
	
	for(i=0;i<K;i++)    
	{	histo1[i] = 0;	histo2[i] = 0;	}
	
	//遍历图象的每一个像素* /
		for(i=0;i<height;i++)
			for(j=0;j<width;j++)
			{
				//计算图象的直方图
					histo1[(BYTE)img1[i*width+j]]++;
				histo2[(BYTE)img2[i*width+j]]++;
			}	
			
			//计算图象的直方图
				for(i=0;i<K;i++)
				{
					p1[i] = (double)histo1[i] / (double)(width*height);//p1[i]灰度值i的概率
					p2[i] = (double)histo2[i] / (double)(width*height);
					
				//直方图均衡化* /
						f[i] = g[i] = 0.0;
					for(l=0;l<=i;l++)
					{
						f[i] += p1[l];
						g[i] += p2[l];
					}
				}
				
				//建立直方图1和直方图2的对应关系(使用单映射规则)* /
					for(k=0;k<K;k++)
					{
						min = fabs(f[k] - g[0]);	cpd[k] = 0;
						for(l=1;l<=k;l++)
							if(fabs(f[k] - g[l]) < min)
							{	min = fabs(f[k] - g[l]);	cpd[k] = l; 	}
					}
					
				//遍历图象的每一个像素* /
						//计算直方图变换后的图象* /
						for(i=0;i<height;i++)
							for(j=0;j<width;j++)
							{
								//将灰度值赋给新数组的该像素* /
									gray = (BYTE)img1[i*width+j];
								imgResult[i*width+j] = (float)cpd[gray];
							}
							
	delete []histo1;
	delete []histo2;
	delete []cpd;
	delete [] p1;
	delete [] p2;
	delete [] f;
	delete [] g;
							
							return imgResult;
}

HDIB CFusionAlgrithm::YIQFUSION(HDIB HMUL, HDIB HPAN)
{

		LPSTR  muldib,pandib,outdib; //指向图像的指针
		BYTE * colorimage;//指向彩色图像的数据区位置
		BYTE * panimage;//指向全色图像的数据区位置
		muldib= (LPSTR) ::GlobalLock((HGLOBAL) HMUL);
		colorimage=(BYTE *)FindDIBBits(muldib);
		pandib= (LPSTR) ::GlobalLock((HGLOBAL) HPAN);
		panimage =(BYTE *)FindDIBBits(pandib);
		
		int wide,height,DibWidth,WIDE;
		wide=::DIBWidth(muldib);//取宽的像素个数
		height=::DIBHeight(muldib);
	    DibWidth=3*wide+( sizeof(DWORD)- 3*wide %sizeof(DWORD) )%sizeof(DWORD);//取得原图的每行总位数
		WIDE=((wide*8)+31)/32*4;//取宽为4的整数倍
		
		BYTE * outimage;  //输出图像的数据区位置
		HDIB HOUT;
		
		HOUT=(HDIB)::GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+DibWidth*height);//生成一个新的图像句柄
		if(!HOUT){	return NULL;	}
		
		outdib	= (LPSTR)::GlobalLock((HGLOBAL)HOUT);
		memcpy(outdib,muldib,sizeof(BITMAPINFOHEADER));
		outimage= (BYTE *) FindDIBBits (outdib);
		if(muldib==NULL || pandib==NULL)
		{
			AfxMessageBox("必须选择两幅影像!",MB_ICONSTOP);	
			return NULL;
		}
		if(muldib==pandib)
		{
			AfxMessageBox("不可以出现两幅相同的影像!",MB_ICONSTOP);
			return NULL;
		}
		if(::DIBWidth(muldib)!=::DIBWidth(pandib) || ::DIBHeight(muldib)!= ::DIBHeight(pandib))
		{
			AfxMessageBox("两幅影像的宽度高度必须相等!",MB_ICONSTOP);
			return NULL;
		}
	
		double * Y;
		double * Q;
		double * I;
		double * Temp;
		Y    = new double[WIDE*height]     ;//用于YIQ空间
		Q    = new double[WIDE*height]     ;//用于YIQ空间
		I    = new double[WIDE*height]     ;//用于存放I分量
		Temp = new double[WIDE*height]     ;//处理全色图像

		for(int i=0;i<height;i++)
		{
			for(int j=0;j<WIDE;j++)
			{	
				double R,G,B,Ym,Im,Qm;
				R = colorimage[i*DibWidth+3*j +2];//2,1,0用来控制RGB分量
                G = colorimage[i*DibWidth+3*j +1];
				B = colorimage[i*DibWidth+3*j +0];
		        Ym= 0.299*R+0.587*G+0.114*B;
				Im= 0.596*R-0.274*G-0.322*B;
				Qm= 0.211*R-0.522*G+0.311*B;
				Y[i*WIDE+j] = Ym;
				I[i*WIDE+j] = Im;
				Q[i*WIDE+j] = Qm;
			  Temp[(DWORD)j*WIDE+i] = (float)panimage[(DWORD)j*WIDE+i];
			}
		}
///////////////////     融合    ////////////////// 
		double *imh;
		imh=new double[WIDE*height];
	HistogramMatch(Temp,Y,WIDE,height,imh);//对全色图像进行直方图均衡
		if(imh == NULL)
		{
			AfxMessageBox("直方图均衡失败!",MB_ICONSTOP);
			return NULL;
		}
		free(Temp); 
		free(Y);//自动分配内存,不用释放 
/////////////////////    YIQ逆变换     /////////////
		//用全色图像来代替YIQ空间的Y亮度分量
		for(int m=0;m<height;m++)
			for (int n=0;n<WIDE;n++)
			{
				double Yn,In,Qn,r,g,b;
				Yn=imh[m*WIDE+n];
				In=I[m*WIDE+n];
                Qn=Q[m*WIDE+n];
				r=Yn+0.956*In+0.623*Qn;
				g=Yn-0.272*In-0.648*Qn;
				b=Yn-1.105*In+0.705*Qn;
				if (b>=256)  b=256;
				if (b<=0)    b=0;
				if (r>=256)  r=256;
				if (r<=0)    r=0;
				if (g>=256)  g=256;
				if (g<=0)    g=0;

				outimage[m*DibWidth+n*3  ]=(BYTE)b;
                outimage[m*DibWidth+n*3+1]=(BYTE)g;
				outimage[m*DibWidth+n*3+2]=(BYTE)r;
			}
		    free (I);
            free (Q);
		delete []imh;
		return  (HDIB)HOUT;	

}

double * CFusionAlgrithm::HistogramMatch(double *img1, double *img2, int width, int height,double *imgResult)
{
	////////////////////      直方图匹配分析      /////////////////////////
	//img1全色波段,img2为I分量
	
	if( img1 == NULL || img2 == NULL)
	{
		AfxMessageBox("获取影像指针失败!",MB_ICONSTOP);
		return NULL;
	}
	
	static int K = 256;
	int i,j,k,l;

	double min;		BYTE gray;
	int *histo1 = new int[K];	int *histo2 = new int[K];
	double *p1 = new double[K];		double *p2 = new double[K];
	double *f = new double[K];		double *g = new double[K];
	int *cpd = new int[K];//
	
	for(i=0;i<K;i++)    
	{	histo1[i] = 0;	histo2[i] = 0;	}
	
	//遍历图象的每一个像素* /
	for(i=0;i<height;i++)
		for(j=0;j<width;j++)
		{
			//计算图象的直方图
			histo1[(BYTE)img1[i*width+j]]++;
			histo2[(BYTE)img2[i*width+j]]++;
		}	
		
		//计算图象的直方图
		for(i=0;i<K;i++)
		{
			p1[i] = (double)histo1[i] / (double)(width*height);//p1[i]灰度值i的概率
			p2[i] = (double)histo2[i] / (double)(width*height);
			
			//直方图均衡化* /
			f[i] = g[i] = 0.0;
			for(l=0;l<=i;l++)
			{
				f[i] += p1[l];
				g[i] += p2[l];
			}
		}
		
		//建立直方图1和直方图2的对应关系(使用单映射规则)* /
		for(k=0;k<K;k++)
		{
			min = fabs(f[k] - g[0]);	cpd[k] = 0;
			for(l=1;l<=k;l++)
				if(fabs(f[k] - g[l]) < min)
				{	min = fabs(f[k] - g[l]);	cpd[k] = l; 	}
		}
		
		//遍历图象的每一个像素* /
		//计算直方图变换后的图象* /
		for(i=0;i<height;i++)
			for(j=0;j<width;j++)
			{

⌨️ 快捷键说明

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