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

📄 pixelfusiondoc.cpp

📁 图像融合的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}
	fileResult.Seek(dwMulspecSizeOff,CFile::begin);
	for(i=0;i<lMulspecHeight;i++)
	{
		fileResult.Write(data,lLineBytesMulspec);
	}	
	fileResult.Close();
	delete []data;
	//融合结果影像的文件映射
	HANDLE hFileResult = 

::CreateFile(lpszResultPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,
		                      FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE hMapResult = ::CreateFileMapping(hFileResult,NULL,PAGE_READWRITE,0,0,NULL);
	
	if(hMapResult != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMapResult);
		hMapResult = NULL;
		return ;
	}
	LPSTR lpResultHead = (LPSTR)::MapViewOfFile(hMapResult,FILE_MAP_WRITE,0,0,0);
	LPSTR lpFusionDIBBits = lpResultHead + dwMulspecSizeOff;
	unsigned char* lpResultBits;       //指向融合源图象象素的指针

	LONG  lLineBytesResult = lLineBytesMulspec;
    //////////////////////////////////////////////////////////////////////////////////
	//进行HSI正变换
	for(i=0;i<lMulspecHeight;i++)
	{
		for(j=0;j<lMulspecWidth;j++)
		{	
			//读取每一像素的三颜色分量
			for(k=0;k<3;k++)
			{
               lpMulspecBits = (unsigned char*)lpMulspecDIBBits 
					 + lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
			   dRGB1[k] =  *lpMulspecBits;
			   RGBNum += dRGB1[k];
			   if(RGBNum == 0) RGBNum = 1.0;
			}
		    //进行正变换
			max_min_value(dRGB1,3,dMax,dMin);
		    //当B分量为最小值时,注意:象素的三颜色分量是按B,G,R的顺序排列的
			if(dMin == dRGB1[0])
			{
               fI = RGBNum/3;
			   if((RGBNum-3*dRGB1[0]) != 0) fH = 

(dRGB1[1]-dRGB1[0])/(RGBNum-3*dRGB1[0]);
			   else fH = (dRGB1[1]-dRGB1[0])/(RGBNum-3*dRGB1[0]+1);		
			   fS = (RGBNum-3*dRGB1[0])/RGBNum;
			}
		    //当R分量为最小值时
			if(dMin == dRGB1[2])
			{
               fI = RGBNum/3;
			   if(RGBNum-3*dRGB1[2] != 0) fH = 

(dRGB1[0]-dRGB1[2])/(RGBNum-3*dRGB1[2])+1;
			   else  fH = (dRGB1[0]-dRGB1[2])/(RGBNum-3*dRGB1[2]+1)+1;			
			   fS = (RGBNum-3*dRGB1[2])/RGBNum;
			}
			//当G分量为最小值时
			if(dMin == dRGB1[1])
			{
               fI = RGBNum/3;
			   if((RGBNum-3*dRGB1[1]) != 0)  fH = 

(dRGB1[2]-dRGB1[1])/(RGBNum-3*dRGB1[1])+2;
			   else fH = (dRGB1[2]-dRGB1[1])+2;	
			   fS = (RGBNum-3*dRGB1[1])/RGBNum;
			}
			dRGB2[0] = fI;dRGB2[1] = fS;dRGB2[2] = fH;
            //先放在内存中
			for(k=0;k<3;k++)
			{
				dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
				*dImageBits = dRGB2[k];				
			}
			//用高空间分辨率的图像替换bIntensity亮度分量.
		
			 dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3;
			 lpSpotBits = (unsigned char*)lpSpotDIBBits 
				             + lLineBytesSpot*(lSpotHeight-1-i) + j;             
			 *dImageBits = *lpSpotBits;
			 //进行逆变换.
			 for(k=0;k<3;k++)
			{
				dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
				dRGB2[k] = *dImageBits;				
			}
			
			 //当B分量为最小值时,注意:象素的三颜色分量是按B,G,R的顺序排列的
			if(dMin == dRGB1[0])
			{
               bRed = (dRGB2[0])*(1+2*dRGB2[1]-3*dRGB2[1]*dRGB2[2]);
			   bGreen = (dRGB2[0])*(1-dRGB2[1]+3*dRGB2[1]*dRGB2[2]);
			   bBlue = (dRGB2[0])*(1-dRGB2[1]);
			}
			//当R分量为最小值时,注意:象素的三颜色分量是按B,G,R的顺序排列的
			if(dMin == dRGB1[2])
			{
               bRed = (dRGB2[0])*(1-dRGB2[1]);
			   bGreen = (dRGB2[0])*(1+5*dRGB2[1]-3*dRGB2[1]*dRGB2[2]);
			   bBlue = (dRGB2[0])*(1-4*dRGB2[1]+3*dRGB2[1]*dRGB2[2]);
			}
			//当G分量为最小值时,注意:象素的三颜色分量是按B,G,R的顺序排列的
			if(dMin == dRGB1[1])
			{
               bRed = (dRGB2[0])*(1-7*dRGB2[1]+3*dRGB2[1]*dRGB2[2]);
			   bGreen = (dRGB2[0])*(1-dRGB2[1]);
			   bBlue = (dRGB2[0])*(1+8*dRGB2[1]-3*dRGB2[2]*dRGB2[1]);
			}
			if(bRed>255) bRed = 255;
		    if(bRed<0)   bRed = 0;
		    if(bGreen>255) bGreen = 255;
		    if(bGreen<0)  bGreen = 0;
		    if(bBlue>255) bBlue = 255;
		    if(bBlue<0)  bBlue = 0;
            dRGB1[0] = bBlue;dRGB1[1] = bGreen;dRGB1[2] = bRed;
			//把结果存入融合后的影像中.
            for(k=0;k<3;k++)
			{
               dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
			   *dImageBits = dRGB1[k];
			} 			
			//重新给中间变量赋初值
			dMin = 255; dMax = 0;
			RGBNum = 0;				
		}		
	}
	///////////////////////////////////////////////////////////////////////////////////////
	//将HSI变换中三角形彩色坐标变换的逆变换的结果写入结果图像中去
	for(i=0;i<lMulspecHeight;i++)
	{
		for(j=0;j<lMulspecWidth;j++)
		{
			for(k=0;k<3;k++)
			{
				dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
				lpResultBits = (unsigned char*)lpFusionDIBBits 
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
				*lpResultBits = (unsigned char)(*dImageBits);
			}		
		}
	}
	
	::UnmapViewOfFile(lpSpotBits);
	::CloseHandle(hMapSpot);
	::CloseHandle(hFileSpot);

	::UnmapViewOfFile(lpMulspecBits);
	::CloseHandle(hMapMulspec);
	::CloseHandle(hFileMulspec);
    
	::UnmapViewOfFile(dImageBits);
	::CloseHandle(hMapTemp);
	::CloseHandle(hFileTemp);

	::UnmapViewOfFile(lpResultBits);
	::CloseHandle(hMapResult);
	::CloseHandle(hFileResult);

	::DeleteFile(lpszTempFile);

	//+++++++++++++++++++++++++++++
	// 打开存储文件,用于显示
	//++++++++++++++++++++++++++++
	CFile fileM;
	CFileException feM;

	if (!fileM.Open(lpszResultPath, CFile::modeRead | CFile::shareDenyWrite, &feM))
	{
		// 失败
		ReportSaveLoadException(lpszResultPath, &feM,
			FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		
		// 返回FALSE
		return ;
	}
	
	// 尝试调用ReadDIBFile()读取图像
	TRY
	{
		m_hFusionDIB = ::ReadDIBFile(fileM);
	}
	CATCH (CFileException, eLoad)
	{
		// 读取失败
		fileM.Abort();
		
		// 恢复光标形状
		EndWaitCursor();
		
		// 报告失败
		ReportSaveLoadException(lpszResultPath, eLoad,
			FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		
		// 设置DIB为空
		m_hFusionDIB = NULL;
		
		fileM.Close();

		// 返回FALSE
		return ;
	}
	END_CATCH
	
	// 判断读取文件是否成功
	if (m_hFusionDIB == NULL)
	{
		// 失败,可能非BMP格式
		CString strMsg;
		strMsg = "读取图像时出错!可能是不支持该类型的图像文件!";
		
		// 提示出错
		//MessageBox(NULL, strMsg, "系统提示", MB_ICONINFORMATION | MB_OK);
		
		fileM.Close();

		// 返回FALSE
		return ;
	}

	fileM.Close();

	UpdateAllViews(NULL);

}

//求多个数的最大值和最小值。
void CPixelFusionDoc::max_min_value(double* array,int nSize, double& a,double& b)
{
	double dMax,dMin;
	dMax = dMin =array[0];
	double *p = array;
	for(int i=0; i<nSize;i++)
	{
		if(dMax < *p)
			dMax = *p;
		if(dMin > *p)
			dMin = *p;
		p++;
			
	}
	a=dMax;
	b=dMin;
}

//+++++++++++++++++++++++++++++++++++++++++++++
//
//       普通圆柱体HIS变换
//
//
//+++++++++++++++++++++++++++++++++++++++++++++
void CPixelFusionDoc::OnCylinder1HISFusion() 
{
	// TODO: Add your command handler code here
	// 存储文件对话框
	CFileDialog dlg(FALSE, "Bmp", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
		"BMP文件(*.bmp)|*.bmp|所有文件(*.*)|*.*||",NULL);
	if (dlg.DoModal() == IDCANCEL)
		return ;

	// 获取存储文件路径
	lpszResultPath = dlg.GetPathName();

	BITMAPFILEHEADER bmfHeaderSpot,bmfHeaderMulspec;
	BITMAPINFOHEADER bmiHeaderSpot,bmiHeaderMulspec;

	////////////////////////////////////////////////
	//获取高空间分辨率影像的信息	
	CFile fileSpot;
	if(!fileSpot.Open(lpszSpotPath,CFile::modeRead))
	{
		AfxMessageBox("当前文件不能打开!",MB_OK);
		return ;
	}
	//读文件头
	if(fileSpot.Read(&bmfHeaderSpot,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
		return ;
	//判断读入的文件是否是BMP文件
	if(bmfHeaderSpot.bfType != DIB_HEADER_MARKER)
		return ;
	//读信息头
	if(fileSpot.Read(&bmiHeaderSpot,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
	{
		return ;
	}	
	WORD wBitCountSpot = bmiHeaderSpot.biBitCount; 
	LONG  lSpotWidth = bmiHeaderSpot.biWidth;
	LONG  lSpotHeight = bmiHeaderSpot.biHeight;
	DWORD dwSpotSizeOff = bmfHeaderSpot.bfOffBits; //文件头到象素的偏移量
	//计算高分辨率图象的行宽度
	LONG lLineBytesSpot = 

WIDTHBYTES(bmiHeaderSpot.biWidth*bmiHeaderSpot.biBitCount*bmiHeaderSpot.biPlanes);

	//判断图像是否满足SPOT全色影像的条件 
	if(wBitCountSpot != 8)
	{
		AfxMessageBox("SPOT全色图像必须为8-bit,请重新输入图像!",MB_OK);
		return ;
	}
	fileSpot.Close();

	////////////////////////////////////////////////
	//获取高光谱分辨率影像的信息
	CFile fileMulspec;
	if(!fileMulspec.Open(lpszMulspecPath,CFile::modeRead))
	{
		AfxMessageBox("当前文件不能打开!",MB_OK);
		return ;
	}	
	//读文件头
	if(fileMulspec.Read(&bmfHeaderMulspec,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
		return ;
	//判断读入的文件是否是BMP文件
	if(bmfHeaderMulspec.bfType != DIB_HEADER_MARKER)
		return ;
	//读信息头
	if(fileMulspec.Read(&bmiHeaderMulspec,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
	{
		return ;
	}	
	WORD wBitCountMulspec = bmiHeaderMulspec.biBitCount; 
	LONG  lMulspecWidth = bmiHeaderMulspec.biWidth;
	LONG  lMulspecHeight = bmiHeaderMulspec.biHeight;
	DWORD dwMulspecSizeOff = bmfHeaderMulspec.bfOffBits; //文件头到象素的偏移量
	//计算高分辨率图象的行宽度
	LONG lLineBytesMulspec = 

WIDTHBYTES(bmiHeaderMulspec.biWidth*bmiHeaderMulspec.biBitCount*bmiHeaderMulspec.biPlanes);
	//判断图像是否满足SPOT全色影像的条件 
	if(wBitCountMulspec != 24)
	{
		AfxMessageBox("多光谱图像必须为24-bit,请重新输入图像!",MB_OK);
		return ;
	}
	fileMulspec.Close();
	////////////////////////////////////////////////
	//判断两幅图像尺寸是否一致。
	if((lSpotWidth != lMulspecWidth) || (lSpotHeight != lMulspecHeight))
	{
		AfxMessageBox("图像大小不匹配,请重新输入!");
		return ;
	}
	/////////////////////////////////////////////////
	//建立文件映射
	//高空间分辨率图象
	HANDLE hFileSpot = 

::CreateFile(lpszSpotPath,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
		                            OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE hMapSpot = ::CreateFileMapping(hFileSpot,NULL,PAGE_READONLY,0,0,NULL);

	if(hMapSpot != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMapSpot);
		hMapSpot = NULL;
		return ;
	}
	LPSTR lpSpotHead = (LPSTR)::MapViewOfFile(hMapSpot,FILE_MAP_READ,0,0,0);
	LPSTR lpSpotDIBBits = lpSpotHead + dwSpotSizeOff;
	unsigned char* lpSpotBits;       //指向SPOT源图象象素的指针
		
	//高光谱分辨率图象
	HANDLE hFileMulspec = 

::CreateFile(lpszMulspecPath,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE hMapMulspec = ::CreateFileMapping(hFileMulspec,NULL,PAGE_READONLY,0,0,NULL);
	
	if(hMapMulspec != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMapMulspec);
		hMapMulspec = NULL;
		return ;
	}
	LPSTR lpMulspecHead = (LPSTR)::MapViewOfFile(hMapMulspec,FILE_MAP_READ,0,0,0);
	LPSTR lpMulspecDIBBits = lpMulspecHead + dwMulspecSizeOff;
	unsigned char* lpMulspecBits;       //指向多光谱源图象象素的指针  
	

	////////////////////////////////////////////////////////////////////////////////////
	LONG i,j,k;	
	
	//RGB分量
	double bRed;
	double bGreen;
	double bBlue;

    double fH,fS,fI;

    //RGB->HIS变换所用到的中间变量
	double dMin,dMax,RGBNum;
	double *dRGB1,*dRGB2; 
	double C = 0;
	double v1,v2;

	//变量初始化
    dMin = 255; dMax = 0;RGBNum = 0;
	//分配内存
	if(((dRGB1 = new double[3]) == NULL)||((dRGB2 = new double[3]) == NULL))

	{
		AfxMessageBox("Can't allocate enough memory!");
		return ;
	}
	//清零
	for(i=0;i<3;i++)
	{
		dRGB1[i] = 0; 
		dRGB2[i] = 0;	
	}
		
	//////////////////////////////////////////////////////////////
	//创建临时文件
    LPCTSTR lpszTempFile = "D:\\temp.dat"; 
	
	CFile fileTemp(lpszTempFile,CFile::modeCreate|CFile::modeReadWrite);
		
	double* data1;
	if((data1 = new double[lLineBytesMulspec*sizeof(double)]) == NULL)
	{
		AfxMessageBox("Can't alloc enough memory!",MB_OK);
		return ;
	}
	for(i = 0;i<lLineBytesMulspec;i++)
	{
		data1[i] = 0;
	}
    fileTemp.Seek(0L,CFile::begin);	
	for(i=0;i<lMulspecHeight;i++)
	{
		fileTemp.Write(data1,lLineBytesMulspec*sizeof(double));
	}	
    delete []data1;
	fileTemp.Close();	
	//临时文件映射
	HANDLE hFileTemp =::CreateFile(lpszTempFile,GENERIC_READ|GENERIC_WRITE,
		        NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE hMapTemp = ::CreateFileMapping(hFileTemp,NULL,PAGE_READWRITE,0,0,NULL);	
	if(hMapTemp == NULL && GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMapTemp);
		hMapTemp = NULL;
		return ;
	}
	double* dImageResult = (double*)::MapViewOfFile(hMapTemp,FILE_MAP_WRITE,0,0,0);

⌨️ 快捷键说明

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