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

📄 pixelfusiondoc.cpp

📁 图像融合的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	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;
			   //正变换
			   if(dRGB1[1]>=dRGB1[0]) C = 0;
			   if(dRGB1[1]<dRGB1[0]) C = pi;
               fI = (1/sqrt(3))*(dRGB1[0]+dRGB1[1]+dRGB1[2]);
			   v1 = (dRGB1[0]+dRGB1[1]-2*dRGB1[2])/(sqrt(6));
			   v2 = (dRGB1[0]-dRGB1[1])/(sqrt(2));
			   fH = atan(v1/v2) + C;
			   fS = sqrt(v1*v1+v2*v2);			   
               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;				
			 }
			bBlue = (1/(sqrt(3)))*dRGB2[0] + (1/(sqrt(6)))*v1 + (1/(sqrt(2)))*v2;
			bGreen = (1/(sqrt(3)))*dRGB2[0] + (1/(sqrt(6)))*v1 -(1/(sqrt(2)))*v2;
			bRed = (1/(sqrt(3)))*dRGB2[0] - (2/(sqrt(6)))*v1;
			
			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);

}

//+++++++++++++++++++++++++++++++++++++++++++++
//
//       Brovey变换
//
//
//+++++++++++++++++++++++++++++++++++++++++++++
void CPixelFusionDoc::OnBroveyFusion() 
{
	// 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;
	double RGBNum,*dRGB;
	RGBNum = 0.00;
	if((dRGB = new double[3]) == NULL)

	{
		AfxMessageBox("Can't allocate enough memory!");
		return ;
	}
	//清零
	for(i=0;i<3;i++)
	{
		dRGB[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);
	double* dImageBits;       //指向临时文件数据的指针	
    //////////////////////////////////////////////////////////

	//创建融合后影像的文件头
	CFile fileResult(lpszResultPath,CFile::modeCreate|CFile::modeWrite);
	fileResult.Write(&bmfHeaderMulspec,sizeof(BITMAPFILEHEADER));
	fileResult.Write(&bmiHeaderMulspec,sizeof(BITMAPINFO));
	BYTE* data;
	if((data = new BYTE[lLineBytesMulspec]) == NULL)
	{
		AfxMessageBox("Can't alloc enough memory!",MB_OK);
		return ;
	}
	for(i = 0;i<lLineBytesMulspec;i++)
	{
		data[i] = 0;
	}
	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;
	////////////////////////////////////////////////////////////////	
	//进行比值变换
	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;
			   dRGB[k] =  *lpMulspecBits;
			   RGBNum += dRGB[k];
			   if(RGBNum == 0) RGBNum = 1.0;
			}

			for(k=0;k<3;k++)
			{
				lpSpotBits = (unsigned char*)lpSpotDIBBits 
				             + lLineBytesSpot*(lSpotHeight-1-i) + j;
				lpMulspecBits = (unsigned char*)lpMulspecDIBBits 
					 + lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;
				dImageBits = dImageResult +
					+ lLineBytesMulspec*(lMulspecHeight-1-i) + j*3+k;			
				*dImageBits = (*lpMulspecBits)/RGBNum*(*lpSpotBits);
										
			}
			RGBNum = 0.0;
		}
	}

	//线性改正,将像素值分波段改到正数的范围内
	double dMax[3],dMin[3];
	for(i=0;i<3;i++)
	{
		dMax[i] = -255;
		dMin[i] = 255;
	}
	//统计极值
	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;
				if(dMax[k]<(*dImageBits))
					dMax[k] = *dImageBits;
				if(dMin[k]>(*dImageBits))
					dMin[k] = *dImageBits;
			}
			
		}
	}
	//线性拉伸
	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;
				if((dMax[k]-dMin[k])<255)
					*dImageBits = (*dImageBits-dMin[k]);
				else
					*dImageBits = (*dImageBits-dMin[k])*255/(dMax[k]-dMin[k]);
			}
			
		}
	}

	//将比值变换的结果写入结果图像中去	
	for(i=0;i<lMulspecHeight;i++)
	{
		for(j=0;j<lMulspecWidth;j++)

⌨️ 快捷键说明

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