📄 pixelfusiondoc.cpp
字号:
}
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 + -